diff options
Diffstat (limited to 'source')
434 files changed, 18655 insertions, 6127 deletions
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt index 0215526e894..e9bae71feec 100644 --- a/source/blender/CMakeLists.txt +++ b/source/blender/CMakeLists.txt @@ -87,6 +87,7 @@ set(SRC_DNA_INC ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_world_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_movieclip_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_tracking_types.h + ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_mask_types.h ) add_subdirectory(editors) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 24386730ddb..b833bc44201 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 263 -#define BLENDER_SUBVERSION 8 +#define BLENDER_SUBVERSION 11 #define BLENDER_MINVERSION 250 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 378cc72beb1..bcda970e60c 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -56,7 +56,7 @@ struct CollisionTree; /* Bits to or into the ClothVertex.flags. */ #define CLOTH_VERT_FLAG_PINNED 1 -#define CLOTH_VERT_FLAG_COLLISION 2 +#define CLOTH_VERT_FLAG_NOSELFCOLL 2 /* vertex NOT used for self collisions */ #define CLOTH_VERT_FLAG_PINNED_EM 3 /** @@ -69,8 +69,7 @@ struct CollisionTree; * own connectivity of the mesh based on the actual edges in the mesh. * */ -typedef struct Cloth -{ +typedef struct Cloth { struct ClothVertex *verts; /* The vertices that represent this cloth. */ struct LinkNode *springs; /* The springs connecting the mesh. */ unsigned int numverts; /* The number of verts == m * n. */ @@ -91,8 +90,7 @@ typedef struct Cloth /** * The definition of a cloth vertex. */ -typedef struct ClothVertex -{ +typedef struct ClothVertex { int flags; /* General flags per vertex. */ float v[3]; /* The velocity of the point. */ float xconst[3]; /* constrained position */ @@ -117,8 +115,7 @@ ClothVertex; /** * The definition of a spring. */ -typedef struct ClothSpring -{ +typedef struct ClothSpring { int ij; /* Pij from the paper, one end of the spring. */ int kl; /* Pkl from the paper, one end of the spring. */ float restlen; /* The original length of the spring. */ @@ -149,8 +146,7 @@ ClothSpring; /* SIMULATION FLAGS: goal flags,.. */ /* These are the bits used in SimSettings.flags. */ -typedef enum -{ +typedef enum { CLOTH_SIMSETTINGS_FLAG_COLLOBJ = ( 1 << 2 ),// object is only collision object, no cloth simulation is done CLOTH_SIMSETTINGS_FLAG_GOAL = ( 1 << 3 ), // we have goals enabled CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ),// true if tearing is enabled @@ -160,15 +156,13 @@ typedef enum } CLOTH_SIMSETTINGS_FLAGS; /* COLLISION FLAGS */ -typedef enum -{ +typedef enum { CLOTH_COLLSETTINGS_FLAG_ENABLED = ( 1 << 1 ), /* enables cloth - object collisions */ CLOTH_COLLSETTINGS_FLAG_SELF = ( 1 << 2 ), /* enables selfcollisions */ } CLOTH_COLLISIONSETTINGS_FLAGS; /* Spring types as defined in the paper.*/ -typedef enum -{ +typedef enum { CLOTH_SPRING_TYPE_STRUCTURAL = (1 << 1), CLOTH_SPRING_TYPE_SHEAR = (1 << 2), CLOTH_SPRING_TYPE_BENDING = (1 << 3), @@ -176,8 +170,7 @@ typedef enum } CLOTH_SPRING_TYPES; /* SPRING FLAGS */ -typedef enum -{ +typedef enum { CLOTH_SPRING_FLAG_DEACTIVATE = ( 1 << 1 ), CLOTH_SPRING_FLAG_NEEDED = ( 1 << 2 ), // springs has values to be applied } CLOTH_SPRINGS_FLAGS; @@ -230,16 +223,14 @@ int cloth_add_spring (struct ClothModifierData *clmd, unsigned int indexA, unsig /* This enum provides the IDs for our solvers. */ // only one available in the moment -typedef enum -{ +typedef enum { CM_IMPLICIT = 0, } CM_SOLVER_ID; /* This structure defines how to call the solver. */ -typedef struct -{ +typedef struct { const char *name; CM_SOLVER_ID id; int ( *init ) (struct Object *ob, struct ClothModifierData *clmd ); diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h index 191056571c0..ec257a2f394 100644 --- a/source/blender/blenkernel/BKE_collision.h +++ b/source/blender/blenkernel/BKE_collision.h @@ -59,8 +59,7 @@ struct LinkNode; //////////////////////////////////////// /* COLLISION FLAGS */ -typedef enum -{ +typedef enum { COLLISION_IN_FUTURE = (1 << 1), #ifdef WITH_ELTOPO COLLISION_USE_COLLFACE = (1 << 2), diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index 23df246b430..7a1172335d8 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -260,6 +260,7 @@ struct Image *CTX_data_edit_image(const bContext *C); struct Text *CTX_data_edit_text(const bContext *C); struct MovieClip *CTX_data_edit_movieclip(const bContext *C); +struct Mask *CTX_data_edit_mask(const bContext *C); int CTX_data_selected_nodes(const bContext *C, ListBase *list); diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index bbe68db8bfe..3dc68edf12b 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -321,6 +321,7 @@ void CustomData_to_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata, int totloop, int totpoly); void CustomData_from_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata, int total); void CustomData_bmesh_update_active_layers(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata); +void CustomData_bmesh_do_versions_update_active_layers(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata); void CustomData_bmesh_init_pool(struct CustomData *data, int totelem, const char htype); /* External file storage */ diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h index 134ec1acd8e..f3223fb4af1 100644 --- a/source/blender/blenkernel/BKE_gpencil.h +++ b/source/blender/blenkernel/BKE_gpencil.h @@ -57,6 +57,7 @@ struct bGPdata *gpencil_data_duplicate(struct bGPdata *gpd); void gpencil_frame_delete_laststroke(struct bGPDlayer *gpl, struct bGPDframe *gpf); +struct bGPDframe *BKE_gpencil_layer_find_frame(struct bGPDlayer *gpl, int cframe); struct bGPDframe *gpencil_layer_getframe(struct bGPDlayer *gpl, int cframe, short addnew); void gpencil_layer_delframe(struct bGPDlayer *gpl, struct bGPDframe *gpf); struct bGPDlayer *gpencil_layer_getactive(struct bGPdata *gpd); diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index 91e3e9edbf0..baa530c0599 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -44,6 +44,7 @@ struct anim; struct Scene; struct Object; struct ImageFormatData; +struct Main; /* call from library */ void BKE_image_free(struct Image *me); @@ -143,6 +144,9 @@ struct Image *BKE_image_add_from_imbuf(struct ImBuf *ibuf); /* for reload, refresh, pack */ void BKE_image_signal(struct Image *ima, struct ImageUser *iuser, int signal); +void BKE_image_walk_all_users(const struct Main *mainp, void *customdata, + void callback(struct Image *ima, struct ImageUser *iuser, void *customdata)); + /* ensures an Image exists for viewing nodes or render */ struct Image *BKE_image_verify_viewer(int type, const char *name); @@ -151,7 +155,9 @@ void BKE_image_assign_ibuf(struct Image *ima, struct ImBuf *ibuf); /* called on frame change or before render */ void BKE_image_user_frame_calc(struct ImageUser *iuser, int cfra, int fieldnr); +void BKE_image_user_check_frame_calc(struct ImageUser *iuser, int cfra, int fieldnr); int BKE_image_user_frame_get(const struct ImageUser *iuser, int cfra, int fieldnr); +void BKE_image_user_file_path(struct ImageUser *iuser, struct Image *ima, char *path); /* sets index offset for multilayer files */ struct RenderPass *BKE_image_multilayer_index(struct RenderResult *rr, struct ImageUser *iuser); diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index 3a19d6c9007..3248944dae8 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -66,7 +66,7 @@ void id_clear_lib_data(struct Main *bmain, struct ID *id); struct ListBase *which_libbase(struct Main *mainlib, short type); -#define MAX_LIBARRAY 40 +#define MAX_LIBARRAY 41 int set_listbasepointers(struct Main *main, struct ListBase **lb); void BKE_libblock_free(struct ListBase *lb, void *idv); diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index 043d0a9886d..ad5541a5a2f 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -86,6 +86,7 @@ typedef struct Main { ListBase wm; ListBase gpencil; ListBase movieclip; + ListBase mask; ListBase linestyle; char id_tag_update[256]; diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h new file mode 100644 index 00000000000..ec2eb82a9eb --- /dev/null +++ b/source/blender/blenkernel/BKE_mask.h @@ -0,0 +1,186 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BKE_MASK_H__ +#define __BKE_MASK_H__ + +struct Main; +struct Mask; +struct MaskParent; +struct MaskLayer; +struct MaskLayerShape; +struct MaskSpline; +struct MaskSplinePoint; +struct MaskSplinePointUW; +struct MovieClip; +struct MovieClipUser; +struct Scene; + +struct MaskSplinePoint *BKE_mask_spline_point_array(struct MaskSpline *spline); +struct MaskSplinePoint *BKE_mask_spline_point_array_from_point(struct MaskSpline *spline, struct MaskSplinePoint *point_ref); + +/* mask layers */ +struct MaskLayer *BKE_mask_layer_new(struct Mask *mask, const char *name); +struct MaskLayer *BKE_mask_layer_active(struct Mask *mask); +void BKE_mask_layer_active_set(struct Mask *mask, struct MaskLayer *masklay); +void BKE_mask_layer_remove(struct Mask *mask, struct MaskLayer *masklay); + +void BKE_mask_layer_free(struct MaskLayer *masklay); +void BKE_mask_spline_free(struct MaskSpline *spline); +struct MaskSpline *BKE_mask_spline_copy(struct MaskSpline *spline); +void BKE_mask_point_free(struct MaskSplinePoint *point); + +void BKE_mask_layer_unique_name(struct Mask *mask, struct MaskLayer *masklay); + +/* splines */ +struct MaskSpline *BKE_mask_spline_add(struct MaskLayer *masklay); + +float (*BKE_mask_spline_differentiate(struct MaskSpline *spline, int *tot_diff_point))[2]; +float (*BKE_mask_spline_feather_differentiated_points(struct MaskSpline *spline, int *tot_feather_point))[2]; + +float (*BKE_mask_spline_differentiate_with_resolution(struct MaskSpline *spline, int width, int height, int *tot_diff_point))[2]; +float (*BKE_mask_spline_feather_differentiated_points_with_resolution(struct MaskSpline *spline, + int width, int height, int *tot_feather_point))[2]; + +float (*BKE_mask_spline_feather_points(struct MaskSpline *spline, int *tot_feather_point))[2]; + +void BKE_mask_point_direction_switch(struct MaskSplinePoint *point); +void BKE_mask_spline_direction_switch(struct MaskLayer *masklay, struct MaskSpline *spline); + +typedef enum { + MASK_PROJ_NEG = -1, + MASK_PROJ_ANY = 0, + MASK_PROJ_POS = 1 +} eMaskSign; +float BKE_mask_spline_project_co(struct MaskSpline *spline, struct MaskSplinePoint *point, + float start_u, const float co[2], const eMaskSign sign); + +/* point */ +int BKE_mask_point_has_handle(struct MaskSplinePoint *point); +void BKE_mask_point_handle(struct MaskSplinePoint *point, float handle[2]); +void BKE_mask_point_set_handle(struct MaskSplinePoint *point, float loc[2], int keep_direction, + float orig_handle[2], float orig_vec[3][3]); + +float *BKE_mask_point_segment_diff(struct MaskSpline *spline, struct MaskSplinePoint *point, int *tot_diff_point); +float *BKE_mask_point_segment_feather_diff(struct MaskSpline *spline, struct MaskSplinePoint *point, + int *tot_feather_point); + +float *BKE_mask_point_segment_diff_with_resolution(struct MaskSpline *spline, struct MaskSplinePoint *point, + int width, int height, int *tot_diff_point); + +float *BKE_mask_point_segment_feather_diff_with_resolution(struct MaskSpline *spline, struct MaskSplinePoint *point, + int width, int height, + int *tot_feather_point); + +void BKE_mask_point_segment_co(struct MaskSpline *spline, struct MaskSplinePoint *point, float u, float co[2]); +void BKE_mask_point_normal(struct MaskSpline *spline, struct MaskSplinePoint *point, + float u, float n[2]); +float BKE_mask_point_weight_scalar(struct MaskSpline *spline, struct MaskSplinePoint *point, const float u); +float BKE_mask_point_weight(struct MaskSpline *spline, struct MaskSplinePoint *point, const float u); +struct MaskSplinePointUW *BKE_mask_point_sort_uw(struct MaskSplinePoint *point, struct MaskSplinePointUW *uw); +void BKE_mask_point_add_uw(struct MaskSplinePoint *point, float u, float w); + +void BKE_mask_point_select_set(struct MaskSplinePoint *point, const short do_select); +void BKE_mask_point_select_set_handle(struct MaskSplinePoint *point, const short do_select); + +/* general */ +struct Mask *BKE_mask_new(const char *name); + +void BKE_mask_free(struct Mask *mask); +void BKE_mask_unlink(struct Main *bmain, struct Mask *mask); + +void BKE_mask_coord_from_movieclip(struct MovieClip *clip, struct MovieClipUser *user, float r_co[2], const float co[2]); +void BKE_mask_coord_to_movieclip(struct MovieClip *clip, struct MovieClipUser *user, float r_co[2], const float co[2]); + +/* parenting */ + +void BKE_mask_update_display(struct Mask *mask, float ctime); + +void BKE_mask_evaluate_all_masks(struct Main *bmain, float ctime, const int do_newframe); +void BKE_mask_evaluate(struct Mask *mask, const float ctime, const int do_newframe); +void BKE_mask_update_scene(struct Main *bmain, struct Scene *scene, const int do_newframe); +void BKE_mask_parent_init(struct MaskParent *parent); +void BKE_mask_calc_handle_adjacent_interp(struct MaskSpline *spline, struct MaskSplinePoint *point, const float u); +void BKE_mask_calc_tangent_polyline(struct MaskSpline *spline, struct MaskSplinePoint *point, float t[2]); +void BKE_mask_calc_handle_point(struct MaskSpline *spline, struct MaskSplinePoint *point); +void BKE_mask_calc_handle_point_auto(struct MaskSpline *spline, struct MaskSplinePoint *point, + const short do_recalc_length); +void BKE_mask_get_handle_point_adjacent(struct MaskSpline *spline, struct MaskSplinePoint *point, + struct MaskSplinePoint **r_point_prev, struct MaskSplinePoint **r_point_next); +void BKE_mask_layer_calc_handles(struct MaskLayer *masklay); +void BKE_mask_layer_calc_handles_deform(struct MaskLayer *masklay); +void BKE_mask_calc_handles(struct Mask *mask); +void BKE_mask_calc_handles_deform(struct Mask *mask); +void BKE_mask_spline_ensure_deform(struct MaskSpline *spline); + +/* animation */ +int BKE_mask_layer_shape_totvert(struct MaskLayer *masklay); +void BKE_mask_layer_shape_from_mask(struct MaskLayer *masklay, struct MaskLayerShape *masklay_shape); +void BKE_mask_layer_shape_to_mask(struct MaskLayer *masklay, struct MaskLayerShape *masklay_shape); +void BKE_mask_layer_shape_to_mask_interp(struct MaskLayer *masklay, + struct MaskLayerShape *masklay_shape_a, + struct MaskLayerShape *masklay_shape_b, + const float fac); +struct MaskLayerShape *BKE_mask_layer_shape_find_frame(struct MaskLayer *masklay, const int frame); +int BKE_mask_layer_shape_find_frame_range(struct MaskLayer *masklay, const float frame, + struct MaskLayerShape **r_masklay_shape_a, + struct MaskLayerShape **r_masklay_shape_b); +struct MaskLayerShape *BKE_mask_layer_shape_alloc(struct MaskLayer *masklay, const int frame); +void BKE_mask_layer_shape_free(struct MaskLayerShape *masklay_shape); +struct MaskLayerShape *BKE_mask_layer_shape_varify_frame(struct MaskLayer *masklay, const int frame); +struct MaskLayerShape *BKE_mask_layer_shape_duplicate(struct MaskLayerShape *masklay_shape); +void BKE_mask_layer_shape_unlink(struct MaskLayer *masklay, struct MaskLayerShape *masklay_shape); +void BKE_mask_layer_shape_sort(struct MaskLayer *masklay); + +int BKE_mask_layer_shape_spline_from_index(struct MaskLayer *masklay, int index, + struct MaskSpline **r_masklay_shape, int *r_index); +int BKE_mask_layer_shape_spline_to_index(struct MaskLayer *masklay, struct MaskSpline *spline); + +int BKE_mask_layer_shape_spline_index(struct MaskLayer *masklay, int index, + struct MaskSpline **r_masklay_shape, int *r_index); +void BKE_mask_layer_shape_changed_add(struct MaskLayer *masklay, int index, + int do_init, int do_init_interpolate); + +void BKE_mask_layer_shape_changed_remove(struct MaskLayer *masklay, int index, int count); + +/* rasterization */ +int BKE_mask_get_duration(struct Mask *mask); +void BKE_mask_rasterize(struct Mask *mask, int width, int height, float *buffer, + const short do_aspect_correct, const short do_linear); + +#define MASKPOINT_ISSEL_ANY(p) ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT) +#define MASKPOINT_ISSEL_KNOT(p) ( (p)->bezt.f2 & SELECT) +#define MASKPOINT_ISSEL_HANDLE_ONLY(p) ( (((p)->bezt.f1 | (p)->bezt.f2) & SELECT) && (((p)->bezt.f2 & SELECT) == 0) ) +#define MASKPOINT_ISSEL_HANDLE(p) ( (((p)->bezt.f1 | (p)->bezt.f2) & SELECT) ) + +#define MASKPOINT_SEL_ALL(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f2 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0 +#define MASKPOINT_DESEL_ALL(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f2 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0 +#define MASKPOINT_INVSEL_ALL(p) { (p)->bezt.f1 ^= SELECT; (p)->bezt.f2 ^= SELECT; (p)->bezt.f3 ^= SELECT; } (void)0 + +#define MASKPOINT_SEL_HANDLE(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0 +#define MASKPOINT_DESEL_HANDLE(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0 + +#endif diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 7abec074647..887340622ad 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -33,6 +33,7 @@ /***/ +struct ID; struct BoundBox; struct DispList; struct ListBase; @@ -150,6 +151,14 @@ void copy_dverts(struct MDeformVert *dst, struct MDeformVert *src, int totvert); void BKE_mesh_delete_material_index(struct Mesh *me, short index); void BKE_mesh_smooth_flag_set(struct Object *meshOb, int enableSmooth); 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(struct ID *id, + struct CustomData *fdata, struct CustomData *ldata, struct CustomData *pdata, + int totedge_i, int totface_i, int totloop_i, int totpoly_i, + struct MEdge *medge, struct MFace *mface, + int *totloop_r, int *totpoly_r, + struct MLoop **mloop_r, struct MPoly **mpoly_r); + void BKE_mesh_calc_normals_tessface(struct MVert *mverts, int numVerts, struct MFace *mfaces, int numFaces, float (*faceNors_r)[3]); /* used for unit testing; compares two meshes, checking only diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h index 15b3cb91b90..221ae99a0ec 100644 --- a/source/blender/blenkernel/BKE_movieclip.h +++ b/source/blender/blenkernel/BKE_movieclip.h @@ -63,6 +63,9 @@ void BKE_movieclip_get_cache_segments(struct MovieClip *clip, struct MovieClipUs void BKE_movieclip_build_proxy_frame(struct MovieClip *clip, int clip_flag, struct MovieDistortion *distortion, int cfra, int *build_sizes, int build_count, int undistorted); +int BKE_movieclip_remap_scene_to_clip_frame(struct MovieClip *clip, int framenr); +int BKE_movieclip_remap_clip_to_scene_frame(struct MovieClip *clip, int framenr); + /* cacheing flags */ #define MOVIECLIP_CACHE_SKIP (1 << 0) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index d093c9108b6..b1e5fabc456 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -266,8 +266,7 @@ struct bNodeTreeExec; typedef void (*bNodeTreeCallback)(void *calldata, struct ID *owner_id, struct bNodeTree *ntree); typedef void (*bNodeClassCallback)(void *calldata, int nclass, const char *name); -typedef struct bNodeTreeType -{ +typedef struct bNodeTreeType { int type; /* type identifier */ char idname[64]; /* id name for RNA identification */ @@ -528,6 +527,7 @@ struct ShadeResult; #define SH_NODE_BRIGHTCONTRAST 165 #define SH_NODE_LIGHT_FALLOFF 166 #define SH_NODE_OBJECT_INFO 167 +#define SH_NODE_PARTICLE_INFO 168 /* custom defines options for Material node */ #define SH_NODE_MAT_DIFF 1 @@ -658,6 +658,7 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat); #define CMP_NODE_MOVIEDISTORTION 265 #define CMP_NODE_DOUBLEEDGEMASK 266 #define CMP_NODE_OUTPUT_MULTI_FILE__DEPRECATED 267 /* DEPRECATED multi file node has been merged into regular CMP_NODE_OUTPUT_FILE */ +#define CMP_NODE_MASK 268 #define CMP_NODE_GLARE 301 #define CMP_NODE_TONEMAP 302 diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index b32b7145ff4..419fb4cedae 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -32,6 +32,7 @@ * \ingroup bke */ +struct bContext; struct Brush; struct MDisps; struct MeshElemMap; @@ -55,6 +56,7 @@ void free_paint(struct Paint *p); void copy_paint(struct Paint *src, struct Paint *tar); struct Paint *paint_get_active(struct Scene *sce); +struct Paint *paint_get_active_from_context(const struct bContext *C); struct Brush *paint_brush(struct Paint *paint); void paint_brush_set(struct Paint *paint, struct Brush *br); diff --git a/source/blender/blenkernel/BKE_sketch.h b/source/blender/blenkernel/BKE_sketch.h index 50ee1184b3e..ed7ce05506d 100644 --- a/source/blender/blenkernel/BKE_sketch.h +++ b/source/blender/blenkernel/BKE_sketch.h @@ -26,14 +26,12 @@ * \ingroup bke */ -typedef enum SK_PType -{ +typedef enum SK_PType { PT_CONTINUOUS, PT_EXACT, } SK_PType; -typedef enum SK_PMode -{ +typedef enum SK_PMode { PT_SNAP, PT_PROJECT, } SK_PMode; diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 817cb477aba..8c28dd93a5e 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -48,7 +48,7 @@ struct Object; struct Scene; void BKE_tracking_init_settings(struct MovieTracking *tracking); -void BKE_tracking_clamp_track(struct MovieTrackingTrack *track, int event); +void BKE_tracking_clamp_marker(struct MovieTrackingMarker *marker, int event); void BKE_tracking_track_flag(struct MovieTrackingTrack *track, int area, int flag, int clear); struct MovieTrackingTrack *BKE_tracking_add_track(struct MovieTracking *tracking, struct ListBase *tracksbase, @@ -57,6 +57,7 @@ struct MovieTrackingMarker *BKE_tracking_insert_marker(struct MovieTrackingTrack struct MovieTrackingMarker *marker); void BKE_tracking_delete_marker(struct MovieTrackingTrack *track, int framenr); +void BKE_tracking_marker_pattern_minmax(struct MovieTrackingMarker *marker, float min[2], float max[2]); struct MovieTrackingMarker *BKE_tracking_get_marker(struct MovieTrackingTrack *track, int framenr); struct MovieTrackingMarker *BKE_tracking_ensure_marker(struct MovieTrackingTrack *track, int framenr); struct MovieTrackingMarker *BKE_tracking_exact_marker(struct MovieTrackingTrack *track, int framenr); @@ -70,12 +71,15 @@ void BKE_tracking_clear_path(struct MovieTrackingTrack *track, int ref_frame, in void BKE_tracking_join_tracks(struct MovieTrackingTrack *dst_track, struct MovieTrackingTrack *src_track); void BKE_tracking_free(struct MovieTracking *tracking); +struct ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, + struct ImBuf *struct_ibuf, struct MovieTrackingMarker *marker, + int num_samples_x, int num_samples_y, float pos[2]); struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, - struct MovieTrackingMarker *marker, int margin, int anchored, - float pos[2], int origin[2]); + struct MovieTrackingMarker *marker, int anchored, int disable_channels); struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, - struct MovieTrackingMarker *marker, int margin, int anchored, - float pos[2], int origin[2]); + struct MovieTrackingMarker *marker, int anchored, int disable_channels); +struct ImBuf *BKE_tracking_track_mask_get(struct MovieTracking *tracking, struct MovieTrackingTrack *track, + struct MovieTrackingMarker *marker, int width, int height); void BKE_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track); @@ -189,7 +193,6 @@ void BKE_tracking_dopesheet_update(struct MovieTracking *tracking, int sort_meth #define CLAMP_PAT_POS 2 #define CLAMP_SEARCH_DIM 3 #define CLAMP_SEARCH_POS 4 -#define CLAMP_PYRAMID_LEVELS 5 #define TRACK_AREA_NONE -1 #define TRACK_AREA_POINT 1 @@ -202,5 +205,6 @@ void BKE_tracking_dopesheet_update(struct MovieTracking *tracking, int sort_meth #define TRACK_SORT_NAME 0 #define TRACK_SORT_LONGEST 1 #define TRACK_SORT_TOTAL 2 +#define TRACK_SORT_AVERAGE_ERROR 3 #endif diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index baa714c9de4..558db1c8742 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -44,6 +44,7 @@ set(INC ../../../intern/memutil ../../../intern/mikktspace ../../../intern/opennl/extern + ../../../intern/raskter # XXX - BAD LEVEL CALL WM_api.h ../windowmanager @@ -102,6 +103,7 @@ set(SRC intern/lattice.c intern/library.c intern/linestyle.c + intern/mask.c intern/material.c intern/mball.c intern/mesh.c @@ -190,6 +192,7 @@ set(SRC BKE_lattice.h BKE_library.h BKE_linestyle.h + BKE_mask.h BKE_main.h BKE_material.h BKE_mball.h diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index 61ef30d5149..819632414d9 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -17,6 +17,7 @@ incs += ' #/intern/smoke/extern' incs += ' #/intern/mikktspace' incs += ' #/intern/audaspace/intern' incs += ' #/intern/ffmpeg' +incs += ' #/intern/raskter' incs += ' ' + env['BF_OPENGL_INC'] incs += ' ' + env['BF_ZLIB_INC'] diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index f73221066b1..170638f0e8d 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -75,7 +75,7 @@ /* --------------------- */ /* forward declarations */ -static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated); +static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index, int level, int animated); /* ******************************************************************** */ /* Animation Visualisation */ @@ -699,7 +699,7 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua /* ******************************************************************** */ /* Dupli-Geometry */ -static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int type, int animated) +static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int par_index, int type, int animated) { DupliObject *dob = MEM_callocN(sizeof(DupliObject), "dupliobject"); @@ -709,6 +709,7 @@ static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], i copy_m4_m4(dob->omat, ob->obmat); dob->origlay = ob->lay; dob->index = index; + dob->particle_index = par_index; dob->type = type; dob->animated = (type == OB_DUPLIGROUP) && animated; ob->lay = lay; @@ -716,7 +717,7 @@ static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], i return dob; } -static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, int animated) +static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, int level, int animated) { DupliObject *dob; Group *group; @@ -748,7 +749,7 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, i mult_m4_m4m4(mat, ob->obmat, go->ob->obmat); } - dob = new_dupli_object(lb, go->ob, mat, ob->lay, 0, OB_DUPLIGROUP, animated); + dob = new_dupli_object(lb, go->ob, mat, ob->lay, 0, par_index, OB_DUPLIGROUP, animated); /* check the group instance and object layers match, also that the object visible flags are ok. */ if ((dob->origlay & group->layer) == 0 || @@ -763,14 +764,14 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, i if (go->ob->transflag & OB_DUPLI) { copy_m4_m4(dob->ob->obmat, dob->mat); - object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, level + 1, animated); + object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, par_index, level + 1, animated); copy_m4_m4(dob->ob->obmat, dob->omat); } } } } -static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, int animated) +static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, int level, int animated) { extern int enable_cu_speed; /* object.c */ Object copyob; @@ -818,7 +819,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */ BKE_object_where_is_calc_time(scene, ob, (float)scene->r.cfra); - dob = new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, OB_DUPLIFRAMES, animated); + dob = new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, par_index, OB_DUPLIFRAMES, animated); copy_m4_m4(dob->omat, copyob.obmat); } } @@ -839,7 +840,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, *ob = copyob; } -typedef struct vertexDupliData { +typedef struct VertexDupliData { ID *id; /* scene or group, for recursive loops */ int level; int animated; @@ -849,7 +850,8 @@ typedef struct vertexDupliData { Scene *scene; Object *ob, *par; float (*orco)[3]; -} vertexDupliData; + int par_index; +} VertexDupliData; /* ------------- */ @@ -857,7 +859,7 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]) { DupliObject *dob; - vertexDupliData *vdd = userData; + VertexDupliData *vdd = userData; float vec[3], q2[4], mat[3][3], tmat[4][4], obmat[4][4]; int origlay; @@ -885,7 +887,7 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3], origlay = vdd->ob->lay; - dob = new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, OB_DUPLIVERTS, vdd->animated); + dob = new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, vdd->par_index, OB_DUPLIVERTS, vdd->animated); /* restore the original layer so that each dupli will have proper dob->origlay */ vdd->ob->lay = origlay; @@ -897,18 +899,18 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3], float tmpmat[4][4]; copy_m4_m4(tmpmat, vdd->ob->obmat); copy_m4_m4(vdd->ob->obmat, obmat); /* pretend we are really this mat */ - object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->level + 1, vdd->animated); + object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->par_index, vdd->level + 1, vdd->animated); copy_m4_m4(vdd->ob->obmat, tmpmat); } } -static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int level, int animated) +static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index, int level, int animated) { Object *ob, *ob_iter; Mesh *me = par->data; Base *base = NULL; DerivedMesh *dm; - vertexDupliData vdd; + VertexDupliData vdd; Scene *sce = NULL; Group *group = NULL; GroupObject *go = NULL; @@ -986,6 +988,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl vdd.scene = scene; vdd.par = par; copy_m4_m4(vdd.pmat, pmat); + vdd.par_index = par_index; /* mballs have a different dupli handling */ if (ob->type != OB_MBALL) ob->flag |= OB_DONE; /* doesnt render */ @@ -1024,7 +1027,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl dm->release(dm); } -static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int level, int animated) +static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index, int level, int animated) { Object *ob, *ob_iter; Base *base = NULL; @@ -1171,7 +1174,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa copy_m4_m4(tmat, obmat); mul_m4_m4m3(obmat, tmat, mat); - dob = new_dupli_object(lb, ob, obmat, par->lay, a, OB_DUPLIFACES, animated); + dob = new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIFACES, animated); if (G.rendering) { w = 1.0f / (float)mp->totloop; @@ -1194,7 +1197,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa float tmpmat[4][4]; copy_m4_m4(tmpmat, ob->obmat); copy_m4_m4(ob->obmat, obmat); /* pretend we are really this mat */ - object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, level + 1, animated); + object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, par_index, level + 1, animated); copy_m4_m4(ob->obmat, tmpmat); } } @@ -1214,7 +1217,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa dm->release(dm); } -static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level, int animated) +static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int UNUSED(par_index), ParticleSystem *psys, int level, int animated) { GroupObject *go; Object *ob = NULL, **oblist = NULL, obcopy, *obcopylist = NULL; @@ -1228,7 +1231,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p float ctime, pa_time, scale = 1.0f; float tmat[4][4], mat[4][4], pamat[4][4], vec[3], size = 0.0; float (*obmat)[4], (*oldobmat)[4]; - int a, b, counter, hair = 0; + int a, b, counter, index, hair = 0; int totpart, totchild, totgroup = 0 /*, pa_num */; int no_draw_flag = PARS_UNEXIST; @@ -1342,6 +1345,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p else a = totpart; + index = 0; for (pa = psys->particles, counter = 0; a < totpart + totchild; a++, pa++, counter++) { if (a < totpart) { /* handle parent particle */ @@ -1437,7 +1441,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p else copy_m4_m4(mat, tmat); - dob = new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated); + dob = new_dupli_object(lb, go->ob, mat, par->lay, counter, index, OB_DUPLIPARTS, animated); copy_m4_m4(dob->omat, obcopylist[b].obmat); if (G.rendering) psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); @@ -1479,11 +1483,14 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p if (part->draw & PART_DRAW_GLOBAL_OB) add_v3_v3v3(mat[3], mat[3], vec); - dob = new_dupli_object(lb, ob, mat, ob->lay, counter, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, animated); + dob = new_dupli_object(lb, ob, mat, ob->lay, counter, index, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, animated); copy_m4_m4(dob->omat, oldobmat); if (G.rendering) psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); } + + /* only counts visible particles */ + ++index; } /* restore objects since they were changed in BKE_object_where_is_calc_time */ @@ -1530,7 +1537,7 @@ static Object *find_family_object(Object **obar, char *family, char ch) } -static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int level, int animated) +static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_index, int level, int animated) { Object *ob, *obar[256] = {NULL}; Curve *cu; @@ -1569,7 +1576,7 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int level, i copy_m4_m4(obmat, par->obmat); copy_v3_v3(obmat[3], vec); - new_dupli_object(lb, ob, obmat, par->lay, a, OB_DUPLIVERTS, animated); + new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIVERTS, animated); } } @@ -1578,7 +1585,7 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int level, i /* ------------- */ -static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated) +static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index, int level, int animated) { if ((ob->transflag & OB_DUPLI) == 0) return; @@ -1598,31 +1605,31 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas if (ob->transflag & OB_DUPLIPARTS) { ParticleSystem *psys = ob->particlesystem.first; for (; psys; psys = psys->next) - new_particle_duplilist(duplilist, id, scene, ob, par_space_mat, psys, level + 1, animated); + new_particle_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, psys, level + 1, animated); } else if (ob->transflag & OB_DUPLIVERTS) { if (ob->type == OB_MESH) { - vertex_duplilist(duplilist, id, scene, ob, par_space_mat, level + 1, animated); + vertex_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, animated); } else if (ob->type == OB_FONT) { if (GS(id->name) == ID_SCE) { /* TODO - support dupligroups */ - font_duplilist(duplilist, scene, ob, level + 1, animated); + font_duplilist(duplilist, scene, ob, par_index, level + 1, animated); } } } else if (ob->transflag & OB_DUPLIFACES) { if (ob->type == OB_MESH) - face_duplilist(duplilist, id, scene, ob, par_space_mat, level + 1, animated); + face_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, animated); } else if (ob->transflag & OB_DUPLIFRAMES) { if (GS(id->name) == ID_SCE) { /* TODO - support dupligroups */ - frames_duplilist(duplilist, scene, ob, level + 1, animated); + frames_duplilist(duplilist, scene, ob, par_index, level + 1, animated); } } else if (ob->transflag & OB_DUPLIGROUP) { DupliObject *dob; - group_duplilist(duplilist, scene, ob, level + 1, animated); /* now recursive */ + group_duplilist(duplilist, scene, ob, par_index, level + 1, animated); /* now recursive */ if (level == 0) { for (dob = duplilist->first; dob; dob = dob->next) @@ -1638,7 +1645,7 @@ ListBase *object_duplilist(Scene *sce, Object *ob) { ListBase *duplilist = MEM_mallocN(sizeof(ListBase), "duplilist"); duplilist->first = duplilist->last = NULL; - object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0); + object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0, 0); return duplilist; } diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index b042c0091d7..ec2b8a04c9a 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -91,6 +91,7 @@ short id_type_can_have_animdata(ID *id) case ID_SPK: case ID_SCE: case ID_MC: + case ID_MSK: { return 1; } @@ -803,10 +804,13 @@ void BKE_animdata_main_cb(Main *mainptr, ID_AnimData_Edit_Callback func, void *u /* objects */ ANIMDATA_IDS_CB(mainptr->object.first); + + /* masks */ + ANIMDATA_IDS_CB(mainptr->mask.first); /* worlds */ ANIMDATA_IDS_CB(mainptr->world.first); - + /* scenes */ ANIMDATA_NODETREE_IDS_CB(mainptr->scene.first, Scene); @@ -890,6 +894,9 @@ void BKE_all_animdata_fix_paths_rename(ID *ref_id, const char *prefix, const cha /* objects */ RENAMEFIX_ANIM_IDS(mainptr->object.first); + + /* masks */ + RENAMEFIX_ANIM_IDS(mainptr->mask.first); /* worlds */ RENAMEFIX_ANIM_IDS(mainptr->world.first); @@ -2360,6 +2367,9 @@ void BKE_animsys_evaluate_all_animation(Main *main, Scene *scene, float ctime) * linked from other (not-visible) scenes will not need their data calculated. */ EVAL_ANIM_IDS(main->object.first, 0); + + /* masks */ + EVAL_ANIM_IDS(main->mask.first, ADT_RECALC_ANIM); /* worlds */ EVAL_ANIM_NODETREE_IDS(main->world.first, World, ADT_RECALC_ANIM); diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 4e6a4b4a43c..e5e73061d52 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -2594,94 +2594,15 @@ MPoly *CDDM_get_polys(DerivedMesh *dm) void CDDM_tessfaces_to_faces(DerivedMesh *dm) { - /*converts mfaces to mpolys/mloops*/ + /* converts mfaces to mpolys/mloops */ CDDerivedMesh *cddm = (CDDerivedMesh *)dm; - MFace *mf; - MEdge *me; - EdgeHash *eh = BLI_edgehash_new(); - int i, totloop; - /* ... on second thaughts, better comment this and assume caller knows edge state. */ -#if 0 - /* ensure we have all the edges we need */ - CDDM_calc_edges_tessface(dm); -#else -# ifndef NDEBUG - { - /* ensure we have correct edges on non release builds */ - i = cddm->dm.numEdgeData; - CDDM_calc_edges_tessface(dm); - BLI_assert(cddm->dm.numEdgeData == i); - } -# endif -#endif - - /*build edge hash*/ - me = cddm->medge; - for (i = 0; i < cddm->dm.numEdgeData; i++, me++) { - BLI_edgehash_insert(eh, me->v1, me->v2, SET_INT_IN_POINTER(i)); - } - - mf = cddm->mface; - totloop = 0; - for (i = 0; i < cddm->dm.numTessFaceData; i++, mf++) { - totloop += mf->v4 ? 4 : 3; - } - - CustomData_free(&cddm->dm.polyData, cddm->dm.numPolyData); - CustomData_free(&cddm->dm.loopData, cddm->dm.numLoopData); - - cddm->dm.numLoopData = totloop; - cddm->dm.numPolyData = cddm->dm.numTessFaceData; - - if (totloop) { - MLoop *ml; - MPoly *mp; - int l, *polyindex; - - cddm->mloop = MEM_callocN(sizeof(MLoop) * totloop, "cddm->mloop in CDDM_tessfaces_to_faces"); - cddm->mpoly = MEM_callocN(sizeof(MPoly) * cddm->dm.numTessFaceData, "cddm->mpoly in CDDM_tessfaces_to_faces"); - - CustomData_add_layer(&cddm->dm.loopData, CD_MLOOP, CD_ASSIGN, cddm->mloop, totloop); - CustomData_add_layer(&cddm->dm.polyData, CD_MPOLY, CD_ASSIGN, cddm->mpoly, cddm->dm.numPolyData); - CustomData_merge(&cddm->dm.faceData, &cddm->dm.polyData, - CD_MASK_ORIGINDEX, CD_DUPLICATE, cddm->dm.numTessFaceData); - - polyindex = CustomData_get_layer(&cddm->dm.faceData, CD_POLYINDEX); - - mf = cddm->mface; - mp = cddm->mpoly; - ml = cddm->mloop; - l = 0; - for (i = 0; i < cddm->dm.numTessFaceData; i++, mf++, mp++, polyindex++) { - mp->flag = mf->flag; - mp->loopstart = l; - mp->mat_nr = mf->mat_nr; - mp->totloop = mf->v4 ? 4 : 3; - - ml->v = mf->v1; - ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v1, mf->v2)); - ml++, l++; - - ml->v = mf->v2; - ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v2, mf->v3)); - ml++, l++; - - ml->v = mf->v3; - ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v3, mf->v4 ? mf->v4 : mf->v1)); - ml++, l++; - - if (mf->v4) { - ml->v = mf->v4; - ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v4, mf->v1)); - ml++, l++; - } - - *polyindex = i; - } - } - - BLI_edgehash_free(eh, NULL); + BKE_mesh_convert_mfaces_to_mpolys_ex(NULL, &cddm->dm.faceData, &cddm->dm.loopData, &cddm->dm.polyData, + cddm->dm.numEdgeData, cddm->dm.numTessFaceData, + cddm->dm.numLoopData, cddm->dm.numPolyData, + cddm->medge, cddm->mface, + &cddm->dm.numLoopData, &cddm->dm.numPolyData, + &cddm->mloop, &cddm->mpoly); } void CDDM_set_mvert(DerivedMesh *dm, MVert *mvert) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index e067b7195ce..b681426f8a7 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -143,6 +143,7 @@ void cloth_init(ClothModifierData *clmd ) clmd->coll_parms->collision_list = NULL; clmd->coll_parms->self_loop_count = 1.0; clmd->coll_parms->selfepsilon = 0.75; + clmd->coll_parms->vgroup_selfcol = 0; /* These defaults are copied from softbody.c's * softbody_calc_forces() function. @@ -756,10 +757,12 @@ static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*verte int cloth_uses_vgroup(ClothModifierData *clmd) { return (((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) || - (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) && + (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) || + (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF)) && ((clmd->sim_parms->vgroup_mass>0) || (clmd->sim_parms->vgroup_struct>0)|| - (clmd->sim_parms->vgroup_bend>0))); + (clmd->sim_parms->vgroup_bend>0) || + (clmd->coll_parms->vgroup_selfcol>0))); } /** @@ -815,6 +818,13 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) verts->bend_stiff = dvert->dw [j].weight; } } + + if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF ) { + if ( dvert->dw[j].def_nr == (clmd->coll_parms->vgroup_selfcol-1)) { + if( dvert->dw [j].weight > 0.0) + verts->flags |= CLOTH_VERT_FLAG_NOSELFCOLL; + } + } /* // for later if ( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_weight-1)) diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 32e9dd7508b..44f524304d2 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -840,6 +840,10 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData * clmd, float step, flo continue; } } + + if( ( cloth->verts[i].flags & CLOTH_VERT_FLAG_NOSELFCOLL ) || + ( cloth->verts[j].flags & CLOTH_VERT_FLAG_NOSELFCOLL ) ) + continue; sub_v3_v3v3(temp, verts[i].tx, verts[j].tx); diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index d15f678f1c5..12dee600532 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -910,7 +910,7 @@ DO_INLINE int get_bin_float(float f) return bin; } -DO_INLINE void save_sample_line(Scopes *scopes, const int idx, const float fx, const float rgb[3], const float ycc[3]) +static void save_sample_line(Scopes *scopes, const int idx, const float fx, const float rgb[3], const float ycc[3]) { float yuv[3]; @@ -953,9 +953,9 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management) double div, divl; float *rf = NULL; unsigned char *rc = NULL; - unsigned int *bin_r, *bin_g, *bin_b, *bin_lum; + unsigned int *bin_lum, *bin_r, *bin_g, *bin_b, *bin_a; int savedlines, saveline; - float rgb[3], ycc[3], luma; + float rgba[4], ycc[3], luma; int ycc_mode = -1; const short is_float = (ibuf->rect_float != NULL); @@ -987,11 +987,12 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management) break; } - /* temp table to count pix value for histo */ - bin_r = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins"); - bin_g = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins"); - bin_b = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins"); - bin_lum = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins"); + /* temp table to count pix value for histogram */ + bin_r = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins"); + bin_g = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins"); + bin_b = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins"); + bin_a = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins"); + bin_lum = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins"); /* convert to number of lines with logarithmic scale */ scopes->sample_lines = (scopes->accuracy * 0.01f) * (scopes->accuracy * 0.01f) * ibuf->y; @@ -1038,27 +1039,28 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management) if (is_float) { if (use_color_management) - linearrgb_to_srgb_v3_v3(rgb, rf); + linearrgb_to_srgb_v3_v3(rgba, rf); else - copy_v3_v3(rgb, rf); + copy_v3_v3(rgba, rf); + rgba[3] = rf[3]; } else { - for (c = 0; c < 3; c++) - rgb[c] = rc[c] * INV_255; + for (c = 0; c < 4; c++) + rgba[c] = rc[c] * INV_255; } /* we still need luma for histogram */ - luma = rgb_to_luma(rgb); + luma = rgb_to_luma(rgba); /* check for min max */ if (ycc_mode == -1) { for (c = 0; c < 3; c++) { - if (rgb[c] < scopes->minmax[c][0]) scopes->minmax[c][0] = rgb[c]; - if (rgb[c] > scopes->minmax[c][1]) scopes->minmax[c][1] = rgb[c]; + if (rgba[c] < scopes->minmax[c][0]) scopes->minmax[c][0] = rgba[c]; + if (rgba[c] > scopes->minmax[c][1]) scopes->minmax[c][1] = rgba[c]; } } else { - rgb_to_ycc(rgb[0], rgb[1], rgb[2], &ycc[0], &ycc[1], &ycc[2], ycc_mode); + rgb_to_ycc(rgba[0], rgba[1], rgba[2], &ycc[0], &ycc[1], &ycc[2], ycc_mode); for (c = 0; c < 3; c++) { ycc[c] *= INV_255; if (ycc[c] < scopes->minmax[c][0]) scopes->minmax[c][0] = ycc[c]; @@ -1066,16 +1068,17 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management) } } /* increment count for histo*/ - bin_r[get_bin_float(rgb[0])] += 1; - bin_g[get_bin_float(rgb[1])] += 1; - bin_b[get_bin_float(rgb[2])] += 1; bin_lum[get_bin_float(luma)] += 1; + bin_r[get_bin_float(rgba[0])] += 1; + bin_g[get_bin_float(rgba[1])] += 1; + bin_b[get_bin_float(rgba[2])] += 1; + bin_a[get_bin_float(rgba[3])] += 1; /* save sample if needed */ if (saveline) { const float fx = (float)x / (float)ibuf->x; const int idx = 2 * (ibuf->x * savedlines + x); - save_sample_line(scopes, idx, fx, rgb, ycc); + save_sample_line(scopes, idx, fx, rgba, ycc); } rf += ibuf->channels; @@ -1089,27 +1092,26 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management) n = 0; nl = 0; for (x = 0; x < 256; x++) { - if (bin_r[x] > n) - n = bin_r[x]; - if (bin_g[x] > n) - n = bin_g[x]; - if (bin_b[x] > n) - n = bin_b[x]; - if (bin_lum[x] > nl) - nl = bin_lum[x]; + if (bin_lum[x] > nl) nl = bin_lum[x]; + if (bin_r[x] > n) n = bin_r[x]; + if (bin_g[x] > n) n = bin_g[x]; + if (bin_b[x] > n) n = bin_b[x]; + if (bin_a[x] > n) n = bin_a[x]; } div = 1.0 / (double)n; divl = 1.0 / (double)nl; for (x = 0; x < 256; x++) { + scopes->hist.data_luma[x] = bin_lum[x] * divl; scopes->hist.data_r[x] = bin_r[x] * div; scopes->hist.data_g[x] = bin_g[x] * div; scopes->hist.data_b[x] = bin_b[x] * div; - scopes->hist.data_luma[x] = bin_lum[x] * divl; + scopes->hist.data_a[x] = bin_a[x] * div; } + MEM_freeN(bin_lum); MEM_freeN(bin_r); MEM_freeN(bin_g); MEM_freeN(bin_b); - MEM_freeN(bin_lum); + MEM_freeN(bin_a); scopes->ok = 1; } diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index c6a0ecc057a..0150646a96c 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1460,7 +1460,7 @@ static bConstraintTypeInfo CTI_ROTLIMIT = { rotlimit_evaluate /* evaluate */ }; -/* --------- Limit Scaling --------- */ +/* --------- Limit Scale --------- */ static void sizelimit_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets)) @@ -1507,7 +1507,7 @@ static void sizelimit_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *U static bConstraintTypeInfo CTI_SIZELIMIT = { CONSTRAINT_TYPE_SIZELIMIT, /* type */ sizeof(bSizeLimitConstraint), /* size */ - "Limit Scaling", /* name */ + "Limit Scale", /* name */ "bSizeLimitConstraint", /* struct name */ NULL, /* free data */ NULL, /* id looper */ @@ -1721,7 +1721,7 @@ static bConstraintTypeInfo CTI_ROTLIKE = { rotlike_evaluate /* evaluate */ }; -/* ---------- Copy Scaling ---------- */ +/* ---------- Copy Scale ---------- */ static void sizelike_new_data(void *cdata) { @@ -3352,7 +3352,7 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t static bConstraintTypeInfo CTI_TRANSFORM = { CONSTRAINT_TYPE_TRANSFORM, /* type */ sizeof(bTransformConstraint), /* size */ - "Transform", /* name */ + "Transformation", /* name */ "bTransformConstraint", /* struct name */ NULL, /* free data */ transform_id_looper, /* id looper */ @@ -3897,6 +3897,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase MovieTrackingTrack *track; MovieTrackingObject *tracking_object; Object *camob = data->camera ? data->camera : scene->camera; + int framenr; if (data->flag & FOLLOWTRACK_ACTIVECLIP) clip = scene->clip; @@ -3919,6 +3920,8 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase if (!track) return; + framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, scene->r.cfra); + if (data->flag & FOLLOWTRACK_USE_3D_POSITION) { if (track->flag & TRACK_HAS_BUNDLE) { float obmat[4][4], mat[4][4]; @@ -3930,7 +3933,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase copy_m4_m4(mat, camob->obmat); - BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, imat); + BKE_tracking_get_interpolated_camera(tracking, tracking_object, framenr, imat); invert_m4(imat); mul_serie_m4(cob->matrix, obmat, mat, imat, NULL, NULL, NULL, NULL, NULL); @@ -3969,7 +3972,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase CameraParams params; float pos[2], rmat[4][4]; - marker = BKE_tracking_get_marker(track, scene->r.cfra); + marker = BKE_tracking_get_marker(track, framenr); add_v2_v2v2(pos, marker->pos, track->offset); @@ -4092,8 +4095,9 @@ static void camerasolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase float mat[4][4], obmat[4][4]; MovieTracking *tracking = &clip->tracking; MovieTrackingObject *object = BKE_tracking_get_camera_object(tracking); + int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, scene->r.cfra); - BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat); + BKE_tracking_get_interpolated_camera(tracking, object, framenr, mat); copy_m4_m4(obmat, cob->matrix); @@ -4156,10 +4160,11 @@ static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase if (object) { float mat[4][4], obmat[4][4], imat[4][4], cammat[4][4], camimat[4][4], parmat[4][4]; + int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, scene->r.cfra); BKE_object_where_is_calc_mat4(scene, camob, cammat); - BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat); + BKE_tracking_get_interpolated_camera(tracking, object, framenr, mat); invert_m4_m4(camimat, cammat); mult_m4_m4m4(parmat, cammat, data->invmat); @@ -4208,10 +4213,10 @@ static void constraints_init_typeinfo(void) constraintsTypeInfo[4] = &CTI_FOLLOWPATH; /* Follow-Path Constraint */ constraintsTypeInfo[5] = &CTI_ROTLIMIT; /* Limit Rotation Constraint */ constraintsTypeInfo[6] = &CTI_LOCLIMIT; /* Limit Location Constraint */ - constraintsTypeInfo[7] = &CTI_SIZELIMIT; /* Limit Scaling Constraint */ + constraintsTypeInfo[7] = &CTI_SIZELIMIT; /* Limit Scale Constraint */ constraintsTypeInfo[8] = &CTI_ROTLIKE; /* Copy Rotation Constraint */ constraintsTypeInfo[9] = &CTI_LOCLIKE; /* Copy Location Constraint */ - constraintsTypeInfo[10] = &CTI_SIZELIKE; /* Copy Scaling Constraint */ + constraintsTypeInfo[10] = &CTI_SIZELIKE; /* Copy Scale Constraint */ constraintsTypeInfo[11] = &CTI_PYTHON; /* Python/Script Constraint */ constraintsTypeInfo[12] = &CTI_ACTION; /* Action Constraint */ constraintsTypeInfo[13] = &CTI_LOCKTRACK; /* Locked-Track Constraint */ diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 3c8f29d8440..ff2dd27e0c9 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -973,6 +973,11 @@ struct MovieClip *CTX_data_edit_movieclip(const bContext *C) return ctx_data_pointer_get(C, "edit_movieclip"); } +struct Mask *CTX_data_edit_mask(const bContext *C) +{ + return ctx_data_pointer_get(C, "edit_mask"); +} + struct EditBone *CTX_data_active_bone(const bContext *C) { return ctx_data_pointer_get(C, "active_bone"); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 5dc50dca45a..f551b2d18a4 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2219,6 +2219,48 @@ void CustomData_bmesh_update_active_layers(CustomData *fdata, CustomData *pdata, } } +/* update active indices for active/render/clone/stencil custom data layers + * based on indices from fdata layers + * used by do_versions in readfile.c when creating pdata and ldata for pre-bmesh + * meshes and needed to preserve active/render/clone/stencil flags set in pre-bmesh files + */ +void CustomData_bmesh_do_versions_update_active_layers(CustomData *fdata, CustomData *pdata, CustomData *ldata) +{ + int act; + + if (CustomData_has_layer(fdata, CD_MTFACE)) { + act = CustomData_get_active_layer(fdata, CD_MTFACE); + CustomData_set_layer_active(pdata, CD_MTEXPOLY, act); + CustomData_set_layer_active(ldata, CD_MLOOPUV, act); + + act = CustomData_get_render_layer(fdata, CD_MTFACE); + CustomData_set_layer_render(pdata, CD_MTEXPOLY, act); + CustomData_set_layer_render(ldata, CD_MLOOPUV, act); + + act = CustomData_get_clone_layer(fdata, CD_MTFACE); + CustomData_set_layer_clone(pdata, CD_MTEXPOLY, act); + CustomData_set_layer_clone(ldata, CD_MLOOPUV, act); + + act = CustomData_get_stencil_layer(fdata, CD_MTFACE); + CustomData_set_layer_stencil(pdata, CD_MTEXPOLY, act); + CustomData_set_layer_stencil(ldata, CD_MLOOPUV, act); + } + + if (CustomData_has_layer(fdata, CD_MCOL)) { + act = CustomData_get_active_layer(fdata, CD_MCOL); + CustomData_set_layer_active(ldata, CD_MLOOPCOL, act); + + act = CustomData_get_render_layer(fdata, CD_MCOL); + CustomData_set_layer_render(ldata, CD_MLOOPCOL, act); + + act = CustomData_get_clone_layer(fdata, CD_MCOL); + CustomData_set_layer_clone(ldata, CD_MLOOPCOL, act); + + act = CustomData_get_stencil_layer(fdata, CD_MCOL); + CustomData_set_layer_stencil(ldata, CD_MLOOPCOL, act); + } +} + void CustomData_bmesh_init_pool(CustomData *data, int totelem, const char htype) { int chunksize; diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index a6ce5daf247..a1e67ebd414 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -54,6 +54,7 @@ #include "DNA_screen_types.h" #include "DNA_windowmanager_types.h" #include "DNA_movieclip_types.h" +#include "DNA_mask_types.h" #include "BKE_animsys.h" #include "BKE_action.h" @@ -2469,6 +2470,15 @@ void DAG_on_visible_update(Main *bmain, const short do_time) /* hack to get objects updating on layer changes */ DAG_id_type_tag(bmain, ID_OB); + + /* so masks update on load */ + if (bmain->mask.first) { + Mask *mask; + + for (mask = bmain->mask.first; mask; mask = mask->id.next) { + DAG_id_tag_update(&mask->id, 0); + } + } } static void dag_id_flush_update__isDependentTexture(void *userData, Object *UNUSED(ob), ID **idpoin) @@ -2611,6 +2621,18 @@ static void dag_id_flush_update(Scene *sce, ID *id) } } + if (idtype == ID_MSK) { + if (sce->nodetree) { + bNode *node; + + for (node = sce->nodetree->nodes.first; node; node = node->next) { + if (node->id == id) { + nodeUpdate(sce->nodetree, node); + } + } + } + } + /* camera's matrix is used to orient reconstructed stuff, * so it should happen tracking-related constraints recalculation * when camera is changing (sergey) */ diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 335758fec11..32c6caffff7 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -1697,8 +1697,8 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, BM_ITER_MESH_INDEX (eve, &iter, bmdm->tc->bm, BM_VERTS_OF_MESH, i) { DM_set_vert_data(&bmdm->dm, i, CD_MVERT_SKIN, - CustomData_bmesh_get(&bm->vdata, eve->head.data, - CD_MVERT_SKIN)); + CustomData_bmesh_get(&bm->vdata, eve->head.data, + CD_MVERT_SKIN)); } } diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 6ec19018ab5..c317dc63ef7 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -321,6 +321,19 @@ void gpencil_frame_delete_laststroke(bGPDlayer *gpl, bGPDframe *gpf) /* -------- GP-Layer API ---------- */ +bGPDframe *BKE_gpencil_layer_find_frame(bGPDlayer *gpl, int cframe) +{ + bGPDframe *gpf; + + for (gpf = gpl->frames.last; gpf; gpf = gpf->prev) { + if (gpf->framenum == cframe) { + return gpf; + } + } + + return NULL; +} + /* get the appropriate gp-frame from a given layer * - this sets the layer's actframe var (if allowed to) * - extension beyond range (if first gp-frame is after all frame in interest and cannot add) diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c index c5d25276085..828f752eaa5 100644 --- a/source/blender/blenkernel/intern/idcode.c +++ b/source/blender/blenkernel/intern/idcode.c @@ -80,6 +80,7 @@ static IDType idtypes[] = { { ID_WO, "World", "worlds", IDTYPE_FLAGS_ISLINKABLE}, { ID_WM, "WindowManager", "window_managers", 0}, { ID_MC, "MovieClip", "movieclips", IDTYPE_FLAGS_ISLINKABLE}, + { ID_MSK, "Mask", "masks", IDTYPE_FLAGS_ISLINKABLE}, }; static int nidtypes = sizeof(idtypes) / sizeof(idtypes[0]); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index a2b1fb10500..eaf4c898b86 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -91,6 +91,14 @@ #include "BLO_sys_types.h" // for intptr_t support +/* for image user iteration */ +#include "DNA_node_types.h" +#include "DNA_space_types.h" +#include "DNA_screen_types.h" +#include "DNA_view3d_types.h" + +#include "WM_api.h" + /* max int, to indicate we don't store sequences in ibuf */ #define IMA_NO_INDEX 0x7FEFEFEF @@ -111,8 +119,8 @@ static void de_interlace_ng(struct ImBuf *ibuf) /* neogeo fields */ if (ibuf->rect) { /* make copies */ - tbuf1 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, (int)IB_rect); - tbuf2 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, (int)IB_rect); + 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; @@ -139,8 +147,8 @@ static void de_interlace_st(struct ImBuf *ibuf) /* standard fields */ if (ibuf->rect) { /* make copies */ - tbuf1 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, IB_rect); - tbuf2 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, IB_rect); + 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; @@ -1814,6 +1822,65 @@ void BKE_image_assign_ibuf(Image *ima, ImBuf *ibuf) image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); } +void BKE_image_walk_all_users(const Main *mainp, void *customdata, + void callback(Image *ima, ImageUser *iuser, void *customdata)) +{ + wmWindowManager *wm; + wmWindow *win; + Tex *tex; + + /* texture users */ + for (tex = mainp->tex.first; tex; tex = tex->id.next) { + if (tex->type == TEX_IMAGE && tex->ima) { + if (ELEM(tex->ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { + callback(tex->ima, &tex->iuser, customdata); + } + } + } + + /* image window, compo node users */ + for (wm = mainp->wm.first; wm; wm = wm->id.next) { /* only 1 wm */ + for (win = wm->windows.first; win; win = win->next) { + ScrArea *sa; + for (sa = win->screen->areabase.first; sa; sa = sa->next) { + if (sa->spacetype == SPACE_VIEW3D) { + View3D *v3d = sa->spacedata.first; + BGpic *bgpic; + for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) { + callback(bgpic->ima, &bgpic->iuser, customdata); + } + } + else if (sa->spacetype == SPACE_IMAGE) { + SpaceImage *sima = sa->spacedata.first; + callback(sima->image, &sima->iuser, customdata); + } + else if (sa->spacetype == SPACE_NODE) { + SpaceNode *snode = sa->spacedata.first; + if ((snode->treetype == NTREE_COMPOSIT) && (snode->nodetree)) { + bNode *node; + for (node = snode->nodetree->nodes.first; node; node = node->next) { + if (node->id && node->type == CMP_NODE_IMAGE) { + Image *ima = (Image *)node->id; + ImageUser *iuser = node->storage; + callback(ima, iuser, customdata); + } + } + } + } + } + } + } +} + +static void image_tag_frame_recalc(Image *ima, ImageUser *iuser, void *customdata) +{ + Image *changed_image = customdata; + + if (ima == changed_image) { + iuser->flag |= IMA_NEED_FRAME_RECALC; + } +} + void BKE_image_signal(Image *ima, ImageUser *iuser, int signal) { if (ima == NULL) @@ -1847,6 +1914,9 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal) ima->ok = 1; if (iuser) iuser->ok = 1; + + BKE_image_walk_all_users(G.main, ima, image_tag_frame_recalc); + break; case IMA_SIGNAL_RELOAD: @@ -2014,8 +2084,7 @@ static void image_initialize_after_load(Image *ima, ImBuf *ibuf) static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame) { struct ImBuf *ibuf; - unsigned short numlen; - char name[FILE_MAX], head[FILE_MAX], tail[FILE_MAX]; + char name[FILE_MAX]; int flag; /* XXX temp stuff? */ @@ -2023,11 +2092,7 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame) ima->tpageflag |= IMA_TPAGE_REFRESH; ima->lastframe = frame; - BLI_strncpy(name, ima->name, sizeof(name)); - BLI_stringdec(name, head, tail, &numlen); - BLI_stringenc(name, head, tail, numlen, frame); - - BLI_path_abs(name, ID_BLEND_PATH(G.main, &ima->id)); + BKE_image_user_file_path(iuser, ima, name); flag = IB_rect | IB_multilayer; if (ima->flag & IMA_DO_PREMUL) @@ -2139,8 +2204,7 @@ static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame) if (ima->anim == NULL) { char str[FILE_MAX]; - BLI_strncpy(str, ima->name, FILE_MAX); - BLI_path_abs(str, ID_BLEND_PATH(G.main, &ima->id)); + BKE_image_user_file_path(iuser, ima, str); /* FIXME: make several stream accessible in image editor, too*/ ima->anim = openanim(str, IB_rect, 0); @@ -2203,8 +2267,8 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra) flag |= IB_premul; /* get the right string */ - BLI_strncpy(str, ima->name, sizeof(str)); - BLI_path_abs(str, ID_BLEND_PATH(G.main, &ima->id)); + BKE_image_user_frame_calc(iuser, cfra, 0); + BKE_image_user_file_path(iuser, ima, str); /* read ibuf */ ibuf = IMB_loadiffname(str, flag); @@ -2658,15 +2722,42 @@ int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, int fieldnr) void BKE_image_user_frame_calc(ImageUser *iuser, int cfra, int fieldnr) { - const int framenr = BKE_image_user_frame_get(iuser, cfra, fieldnr); + if (iuser) { + const int framenr = BKE_image_user_frame_get(iuser, cfra, fieldnr); + + /* allows image users to handle redraws */ + if (iuser->flag & IMA_ANIM_ALWAYS) + if (framenr != iuser->framenr) + iuser->flag |= IMA_ANIM_REFRESHED; + + iuser->framenr = framenr; + if (iuser->ok == 0) iuser->ok = 1; + } +} + +void BKE_image_user_check_frame_calc(ImageUser *iuser, int cfra, int fieldnr) +{ + if ((iuser->flag & IMA_ANIM_ALWAYS) || (iuser->flag & IMA_NEED_FRAME_RECALC)) { + BKE_image_user_frame_calc(iuser, cfra, fieldnr); - /* allows image users to handle redraws */ - if (iuser->flag & IMA_ANIM_ALWAYS) - if (framenr != iuser->framenr) - iuser->flag |= IMA_ANIM_REFRESHED; + iuser->flag &= ~IMA_NEED_FRAME_RECALC; + } +} - iuser->framenr = framenr; - if (iuser->ok == 0) iuser->ok = 1; +void BKE_image_user_file_path(ImageUser *iuser, Image *ima, char *filepath) +{ + BLI_strncpy(filepath, ima->name, FILE_MAX); + + if (ima->source == IMA_SRC_SEQUENCE) { + char head[FILE_MAX], tail[FILE_MAX]; + unsigned short numlen; + int frame = iuser->framenr; + + BLI_stringdec(filepath, head, tail, &numlen); + BLI_stringenc(filepath, head, tail, numlen, frame); + } + + BLI_path_abs(filepath, ID_BLEND_PATH(G.main, &ima->id)); } int BKE_image_has_alpha(struct Image *image) @@ -2684,4 +2775,3 @@ int BKE_image_has_alpha(struct Image *image) else return 0; } - diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index d4861a27057..4aef47159df 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -695,8 +695,7 @@ DO_INLINE void subadd_bfmatrixS_bfmatrixS( fmatrix3x3 *to, fmatrix3x3 *from, flo /////////////////////////////////////////////////////////////////// // simulator start /////////////////////////////////////////////////////////////////// -typedef struct Implicit_Data -{ +typedef struct Implicit_Data { lfVector *X, *V, *Xnew, *Vnew, *olddV, *F, *B, *dV, *z; fmatrix3x3 *A, *dFdV, *dFdX, *S, *P, *Pinv, *bigI, *M; } Implicit_Data; diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 9737888e0b2..bbc1874c2ae 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -1924,14 +1924,14 @@ void do_versions_ipos_to_animato(Main *main) * (semi-hack (tm) ) */ switch (seq->type) { - case SEQ_IMAGE: - case SEQ_META: - case SEQ_SCENE: - case SEQ_MOVIE: - case SEQ_COLOR: + case SEQ_TYPE_IMAGE: + case SEQ_TYPE_META: + case SEQ_TYPE_SCENE: + case SEQ_TYPE_MOVIE: + case SEQ_TYPE_COLOR: adrcode = SEQ_FAC_OPACITY; break; - case SEQ_SPEED: + case SEQ_TYPE_SPEED: adrcode = SEQ_FAC_SPEED; break; } diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 5cc328212a9..2fe6999c6e8 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -66,6 +66,7 @@ #include "DNA_world_types.h" #include "DNA_gpencil_types.h" #include "DNA_movieclip_types.h" +#include "DNA_mask_types.h" #include "BLI_blenlib.h" #include "BLI_dynstr.h" @@ -108,6 +109,7 @@ #include "BKE_speaker.h" #include "BKE_utildefines.h" #include "BKE_movieclip.h" +#include "BKE_mask.h" #include "BKE_linestyle.h" #include "RNA_access.h" @@ -492,6 +494,8 @@ ListBase *which_libbase(Main *mainlib, short type) return &(mainlib->gpencil); case ID_MC: return &(mainlib->movieclip); + case ID_MSK: + return &(mainlib->mask); case ID_LS: return &(mainlib->linestyle); } @@ -577,7 +581,8 @@ int set_listbasepointers(Main *main, ListBase **lb) lb[a++] = &(main->library); lb[a++] = &(main->wm); lb[a++] = &(main->movieclip); - lb[a++]= &(main->linestyle); + lb[a++] = &(main->mask); + lb[a++] = &(main->linestyle); lb[a] = NULL; @@ -689,6 +694,9 @@ static ID *alloc_libblock_notest(short type) case ID_MC: id = MEM_callocN(sizeof(MovieClip), "Movie Clip"); break; + case ID_MSK: + id = MEM_callocN(sizeof(Mask), "Mask"); + break; case ID_LS: id = MEM_callocN(sizeof(FreestyleLineStyle), "Freestyle Line Style"); break; @@ -900,6 +908,9 @@ void BKE_libblock_free(ListBase *lb, void *idv) case ID_MC: BKE_movieclip_free((MovieClip *)id); break; + case ID_MSK: + BKE_mask_free((Mask *)id); + break; case ID_LS: FRS_free_linestyle((FreestyleLineStyle *)id); break; @@ -1146,7 +1157,7 @@ static ID *is_dupid(ListBase *lb, ID *id, const char *name) * Normally the ID that's being check is already in the ListBase, so ID *id * points at the new entry. The Python Library module needs to know what * the name of a datablock will be before it is appended; in this case ID *id - * id is NULL; + * id is NULL */ static int check_for_dupid(ListBase *lb, ID *id, char *name) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c new file mode 100644 index 00000000000..bb2940091e4 --- /dev/null +++ b/source/blender/blenkernel/intern/mask.c @@ -0,0 +1,2225 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/mask.c + * \ingroup bke + */ + +#include <stddef.h> +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_path_util.h" +#include "BLI_string.h" +#include "BLI_listbase.h" +#include "BLI_math.h" + +#include "DNA_mask_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_movieclip_types.h" +#include "DNA_tracking_types.h" + +#include "BKE_curve.h" +#include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_mask.h" +#include "BKE_tracking.h" +#include "BKE_movieclip.h" +#include "BKE_utildefines.h" + +#include "raskter.h" + +static MaskSplinePoint *mask_spline_point_next(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point) +{ + if (point == &points_array[spline->tot_point - 1]) { + if (spline->flag & MASK_SPLINE_CYCLIC) { + return &points_array[0]; + } + else { + return NULL; + } + } + else { + return point + 1; + } +} + +static MaskSplinePoint *mask_spline_point_prev(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point) +{ + if (point == points_array) { + if (spline->flag & MASK_SPLINE_CYCLIC) { + return &points_array[spline->tot_point - 1]; + } + else { + return NULL; + } + } + else { + return point - 1; + } +} + +static BezTriple *mask_spline_point_next_bezt(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point) +{ + if (point == &points_array[spline->tot_point - 1]) { + if (spline->flag & MASK_SPLINE_CYCLIC) { + return &(points_array[0].bezt); + } + else { + return NULL; + } + } + else { + return &((point + 1))->bezt; + } +} + +#if 0 +static BezTriple *mask_spline_point_prev_bezt(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point) +{ + if (point == points_array) { + if (spline->flag & MASK_SPLINE_CYCLIC) { + return &(points_array[0].bezt); + } + else { + return NULL; + } + } + else { + return &((point - 1))->bezt; + } +} +#endif + +MaskSplinePoint *BKE_mask_spline_point_array(MaskSpline *spline) +{ + return spline->points_deform ? spline->points_deform : spline->points; +} + +MaskSplinePoint *BKE_mask_spline_point_array_from_point(MaskSpline *spline, MaskSplinePoint *point_ref) +{ + if ((point_ref >= spline->points) && (point_ref < &spline->points[spline->tot_point])) { + return spline->points; + } + + if ((point_ref >= spline->points_deform) && (point_ref < &spline->points_deform[spline->tot_point])) { + return spline->points_deform; + } + + BLI_assert(!"wrong array"); + return NULL; +} + +/* mask layers */ + +MaskLayer *BKE_mask_layer_new(Mask *mask, const char *name) +{ + MaskLayer *masklay = MEM_callocN(sizeof(MaskLayer), __func__); + + if (name && name[0]) + BLI_strncpy(masklay->name, name, sizeof(masklay->name)); + else + strcpy(masklay->name, "MaskLayer"); + + BLI_addtail(&mask->masklayers, masklay); + + BKE_mask_layer_unique_name(mask, masklay); + + mask->masklay_tot++; + + masklay->alpha = 1.0f; + + return masklay; +} + +/* note: may still be hidden, caller needs to check */ +MaskLayer *BKE_mask_layer_active(Mask *mask) +{ + return BLI_findlink(&mask->masklayers, mask->masklay_act); +} + +void BKE_mask_layer_active_set(Mask *mask, MaskLayer *masklay) +{ + mask->masklay_act = BLI_findindex(&mask->masklayers, masklay); +} + +void BKE_mask_layer_remove(Mask *mask, MaskLayer *masklay) +{ + BLI_remlink(&mask->masklayers, masklay); + BKE_mask_layer_free(masklay); + + mask->masklay_tot--; + + if (mask->masklay_act >= mask->masklay_tot) + mask->masklay_act = mask->masklay_tot - 1; +} + +void BKE_mask_layer_unique_name(Mask *mask, MaskLayer *masklay) +{ + BLI_uniquename(&mask->masklayers, masklay, "MaskLayer", '.', offsetof(MaskLayer, name), sizeof(masklay->name)); +} + +/* splines */ + +MaskSpline *BKE_mask_spline_add(MaskLayer *masklay) +{ + MaskSpline *spline; + + spline = MEM_callocN(sizeof(MaskSpline), "new mask spline"); + BLI_addtail(&masklay->splines, spline); + + /* spline shall have one point at least */ + spline->points = MEM_callocN(sizeof(MaskSplinePoint), "new mask spline point"); + spline->tot_point = 1; + + /* cyclic shapes are more usually used */ + // spline->flag |= MASK_SPLINE_CYCLIC; // disable because its not so nice for drawing. could be done differently + + spline->weight_interp = MASK_SPLINE_INTERP_LINEAR; + + BKE_mask_parent_init(&spline->parent); + + return spline; +} + +static int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height) +{ + float max_segment = 0.01f; + int i, resol = 1; + + if (width != 0 && height != 0) { + if (width >= height) + max_segment = 1.0f / (float) width; + else + max_segment = 1.0f / (float) height; + } + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + BezTriple *bezt, *bezt_next; + float a, b, c, len; + int cur_resol; + + bezt = &point->bezt; + bezt_next = mask_spline_point_next_bezt(spline, spline->points, point); + + if (bezt_next == NULL) { + break; + } + + a = len_v3v3(bezt->vec[1], bezt->vec[2]); + b = len_v3v3(bezt->vec[2], bezt_next->vec[0]); + c = len_v3v3(bezt_next->vec[0], bezt_next->vec[1]); + + len = a + b + c; + cur_resol = len / max_segment; + + resol = MAX2(resol, cur_resol); + } + + return resol; +} + +static int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height) +{ + const float max_segment = 0.005; + int resol = BKE_mask_spline_resolution(spline, width, height); + float max_jump = 0.0f; + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + float prev_u, prev_w; + int j; + + prev_u = 0.0f; + prev_w = point->bezt.weight; + + for (j = 0; j < point->tot_uw; j++) { + float jump = fabsf((point->uw[j].w - prev_w) / (point->uw[j].u - prev_u)); + + max_jump = MAX2(max_jump, jump); + + prev_u = point->uw[j].u; + prev_w = point->uw[j].w; + } + } + + resol += max_jump / max_segment; + + return resol; +} + +float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline, int width, int height, + int *tot_diff_point))[2] +{ + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + + MaskSplinePoint *point, *prev; + float (*diff_points)[2], (*fp)[2]; + int a, len, resol = BKE_mask_spline_resolution(spline, width, height); + + if (spline->tot_point <= 1) { + /* nothing to differentiate */ + *tot_diff_point = 0; + return NULL; + } + + /* count */ + len = (spline->tot_point - 1) * resol; + + if (spline->flag & MASK_SPLINE_CYCLIC) + len += resol; + else + len++; + + /* len+1 because of 'forward_diff_bezier' function */ + *tot_diff_point = len; + diff_points = fp = MEM_mallocN((len + 1) * sizeof(*diff_points), "mask spline vets"); + + a = spline->tot_point - 1; + if (spline->flag & MASK_SPLINE_CYCLIC) + a++; + + prev = points_array; + point = prev + 1; + + while (a--) { + BezTriple *prevbezt; + BezTriple *bezt; + int j; + + if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC)) + point = points_array; + + prevbezt = &prev->bezt; + bezt = &point->bezt; + + for (j = 0; j < 2; j++) { + BKE_curve_forward_diff_bezier(prevbezt->vec[1][j], prevbezt->vec[2][j], + bezt->vec[0][j], bezt->vec[1][j], + &(*fp)[j], resol, 2 * sizeof(float)); + } + + fp += resol; + + if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) { + copy_v2_v2(*fp, bezt->vec[1]); + } + + prev = point; + point++; + } + + return diff_points; +} + +float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point))[2] +{ + return BKE_mask_spline_differentiate_with_resolution(spline, 0, 0, tot_diff_point); +} + +float (*BKE_mask_spline_feather_differentiated_points_with_resolution(MaskSpline *spline, int width, int height, + int *tot_feather_point))[2] +{ + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + + float (*feather)[2], (*fp)[2]; + int i, j, tot, resol = BKE_mask_spline_feather_resolution(spline, width, height); + + tot = resol * spline->tot_point; + feather = fp = MEM_mallocN(tot * sizeof(*feather), "mask spline feather diff points"); + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &points_array[i]; + + for (j = 0; j < resol; j++, fp++) { + float u = (float) j / resol, weight; + float co[2], n[2]; + + /* TODO - these calls all calculate similar things + * could be unified for some speed */ + BKE_mask_point_segment_co(spline, point, u, co); + BKE_mask_point_normal(spline, point, u, n); + weight = BKE_mask_point_weight(spline, point, u); + + madd_v2_v2v2fl(*fp, co, n, weight); + } + } + + *tot_feather_point = tot; + + return feather; +} + +float (*BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *tot_feather_point))[2] +{ + return BKE_mask_spline_feather_differentiated_points_with_resolution(spline, 0, 0, tot_feather_point); +} + +float (*BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point))[2] +{ + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + + int i, tot = 0; + float (*feather)[2], (*fp)[2]; + + /* count */ + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &points_array[i]; + + tot += point->tot_uw + 1; + } + + /* create data */ + feather = fp = MEM_mallocN(tot * sizeof(*feather), "mask spline feather points"); + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &points_array[i]; + BezTriple *bezt = &point->bezt; + float weight, n[2]; + int j; + + BKE_mask_point_normal(spline, point, 0.0f, n); + weight = BKE_mask_point_weight(spline, point, 0.0f); + + madd_v2_v2v2fl(*fp, bezt->vec[1], n, weight); + fp++; + + for (j = 0; j < point->tot_uw; j++) { + float u = point->uw[j].u; + float co[2]; + + BKE_mask_point_segment_co(spline, point, u, co); + BKE_mask_point_normal(spline, point, u, n); + weight = BKE_mask_point_weight(spline, point, u); + + madd_v2_v2v2fl(*fp, co, n, weight); + fp++; + } + } + + *tot_feather_point = tot; + + return feather; +} + +void BKE_mask_point_direction_switch(MaskSplinePoint *point) +{ + const int tot_uw = point->tot_uw; + const int tot_uw_half = tot_uw / 2; + int i; + + float co_tmp[2]; + + /* swap handles */ + copy_v2_v2(co_tmp, point->bezt.vec[0]); + copy_v2_v2(point->bezt.vec[0], point->bezt.vec[2]); + copy_v2_v2(point->bezt.vec[2], co_tmp); + /* in this case the flags are unlikely to be different but swap anyway */ + SWAP(char, point->bezt.f1, point->bezt.f3); + SWAP(char, point->bezt.h1, point->bezt.h2); + + + /* swap UW's */ + if (tot_uw > 1) { + /* count */ + for (i = 0; i < tot_uw_half; i++) { + MaskSplinePointUW *uw_a = &point->uw[i]; + MaskSplinePointUW *uw_b = &point->uw[tot_uw - (i + 1)]; + SWAP(MaskSplinePointUW, *uw_a, *uw_b); + } + } + + for (i = 0; i < tot_uw; i++) { + MaskSplinePointUW *uw = &point->uw[i]; + uw->u = 1.0f - uw->u; + } +} + +void BKE_mask_spline_direction_switch(MaskLayer *masklay, MaskSpline *spline) +{ + const int tot_point = spline->tot_point; + const int tot_point_half = tot_point / 2; + int i, i_prev; + + if (tot_point < 2) { + return; + } + + /* count */ + for (i = 0; i < tot_point_half; i++) { + MaskSplinePoint *point_a = &spline->points[i]; + MaskSplinePoint *point_b = &spline->points[tot_point - (i + 1)]; + SWAP(MaskSplinePoint, *point_a, *point_b); + } + + /* correct UW's */ + i_prev = tot_point - 1; + for (i = 0; i < tot_point; i++) { + + BKE_mask_point_direction_switch(&spline->points[i]); + + SWAP(MaskSplinePointUW *, spline->points[i].uw, spline->points[i_prev].uw); + SWAP(int, spline->points[i].tot_uw, spline->points[i_prev].tot_uw); + + i_prev = i; + } + + /* correct animation */ + if (masklay->splines_shapes.first) { + MaskLayerShape *masklay_shape; + + const int spline_index = BKE_mask_layer_shape_spline_to_index(masklay, spline); + + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + MaskLayerShapeElem *fp_arr = (MaskLayerShapeElem *)masklay_shape->data; + + for (i = 0; i < tot_point_half; i++) { + MaskLayerShapeElem *fp_a = &fp_arr[spline_index + (i) ]; + MaskLayerShapeElem *fp_b = &fp_arr[spline_index + (tot_point - (i + 1))]; + SWAP(MaskLayerShapeElem, *fp_a, *fp_b); + } + } + } +} + + +float BKE_mask_spline_project_co(MaskSpline *spline, MaskSplinePoint *point, + float start_u, const float co[2], const eMaskSign sign) +{ + const float proj_eps = 1e-3; + const float proj_eps_squared = proj_eps * proj_eps; + const int N = 1000; + float u = -1.0f, du = 1.0f / N, u1 = start_u, u2 = start_u; + float ang = -1.0f; + + BLI_assert(ABS(sign) <= 1); /* (-1, 0, 1) */ + + while (u1 > 0.0f || u2 < 1.0f) { + float n1[2], n2[2], co1[2], co2[2]; + float v1[2], v2[2]; + float ang1, ang2; + + if (u1 >= 0.0f) { + BKE_mask_point_segment_co(spline, point, u1, co1); + BKE_mask_point_normal(spline, point, u1, n1); + sub_v2_v2v2(v1, co, co1); + + if ((sign == MASK_PROJ_ANY) || + ((sign == MASK_PROJ_NEG) && (dot_v2v2(v1, n1) <= 0.0f)) || + ((sign == MASK_PROJ_POS) && (dot_v2v2(v1, n1) >= 0.0f))) + { + + if (len_squared_v2(v1) > proj_eps_squared) { + ang1 = angle_v2v2(v1, n1); + if (ang1 > M_PI / 2.0f) + ang1 = M_PI - ang1; + + if (ang < 0.0f || ang1 < ang) { + ang = ang1; + u = u1; + } + } + else { + u = u1; + break; + } + } + } + + if (u2 <= 1.0f) { + BKE_mask_point_segment_co(spline, point, u2, co2); + BKE_mask_point_normal(spline, point, u2, n2); + sub_v2_v2v2(v2, co, co2); + + if ((sign == MASK_PROJ_ANY) || + ((sign == MASK_PROJ_NEG) && (dot_v2v2(v2, n2) <= 0.0f)) || + ((sign == MASK_PROJ_POS) && (dot_v2v2(v2, n2) >= 0.0f))) + { + + if (len_squared_v2(v2) > proj_eps_squared) { + ang2 = angle_v2v2(v2, n2); + if (ang2 > M_PI / 2.0f) + ang2 = M_PI - ang2; + + if (ang2 < ang) { + ang = ang2; + u = u2; + } + } + else { + u = u2; + break; + } + } + } + + u1 -= du; + u2 += du; + } + + return u; +} + +/* point */ + +int BKE_mask_point_has_handle(MaskSplinePoint *point) +{ + BezTriple *bezt = &point->bezt; + + return bezt->h1 == HD_ALIGN; +} + +void BKE_mask_point_handle(MaskSplinePoint *point, float handle[2]) +{ + float vec[2]; + + sub_v2_v2v2(vec, point->bezt.vec[0], point->bezt.vec[1]); + + handle[0] = (point->bezt.vec[1][0] + vec[1]); + handle[1] = (point->bezt.vec[1][1] - vec[0]); +} + +void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], int keep_direction, + float orig_handle[2], float orig_vec[3][3]) +{ + BezTriple *bezt = &point->bezt; + float v1[2], v2[2], vec[2]; + + if (keep_direction) { + sub_v2_v2v2(v1, loc, orig_vec[1]); + sub_v2_v2v2(v2, orig_handle, orig_vec[1]); + + project_v2_v2v2(vec, v1, v2); + + if (dot_v2v2(v2, vec) > 0) { + float len = len_v2(vec); + + sub_v2_v2v2(v1, orig_vec[0], orig_vec[1]); + + mul_v2_fl(v1, len / len_v2(v1)); + + add_v2_v2v2(bezt->vec[0], bezt->vec[1], v1); + sub_v2_v2v2(bezt->vec[2], bezt->vec[1], v1); + } + else { + copy_v3_v3(bezt->vec[0], bezt->vec[1]); + copy_v3_v3(bezt->vec[2], bezt->vec[1]); + } + } + else { + sub_v2_v2v2(v1, loc, bezt->vec[1]); + + v2[0] = -v1[1]; + v2[1] = v1[0]; + + add_v2_v2v2(bezt->vec[0], bezt->vec[1], v2); + sub_v2_v2v2(bezt->vec[2], bezt->vec[1], v2); + } +} + +float *BKE_mask_point_segment_feather_diff_with_resolution(MaskSpline *spline, MaskSplinePoint *point, + int width, int height, + int *tot_feather_point) +{ + float *feather, *fp; + int i, resol = BKE_mask_spline_feather_resolution(spline, width, height); + + feather = fp = MEM_callocN(2 * resol * sizeof(float), "mask point spline feather diff points"); + + for (i = 0; i < resol; i++, fp += 2) { + float u = (float)(i % resol) / resol, weight; + float co[2], n[2]; + + BKE_mask_point_segment_co(spline, point, u, co); + BKE_mask_point_normal(spline, point, u, n); + weight = BKE_mask_point_weight(spline, point, u); + + fp[0] = co[0] + n[0] * weight; + fp[1] = co[1] + n[1] * weight; + } + + *tot_feather_point = resol; + + return feather; +} + +float *BKE_mask_point_segment_feather_diff(MaskSpline *spline, MaskSplinePoint *point, int *tot_feather_point) +{ + return BKE_mask_point_segment_feather_diff_with_resolution(spline, point, 0, 0, tot_feather_point); +} + +float *BKE_mask_point_segment_diff_with_resolution(MaskSpline *spline, MaskSplinePoint *point, + int width, int height, int *tot_diff_point) +{ + MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point); + + BezTriple *bezt, *bezt_next; + float *diff_points, *fp; + int j, resol = BKE_mask_spline_resolution(spline, width, height); + + bezt = &point->bezt; + bezt_next = mask_spline_point_next_bezt(spline, points_array, point); + + if (!bezt_next) + return NULL; + + /* resol+1 because of 'forward_diff_bezier' function */ + *tot_diff_point = resol + 1; + diff_points = fp = MEM_callocN((resol + 1) * 2 * sizeof(float), "mask segment vets"); + + for (j = 0; j < 2; j++) { + BKE_curve_forward_diff_bezier(bezt->vec[1][j], bezt->vec[2][j], + bezt_next->vec[0][j], bezt_next->vec[1][j], + fp + j, resol, 2 * sizeof(float)); + } + + copy_v2_v2(fp + 2 * resol, bezt_next->vec[1]); + + return diff_points; +} + +float *BKE_mask_point_segment_diff(MaskSpline *spline, MaskSplinePoint *point, int *tot_diff_point) +{ + return BKE_mask_point_segment_diff_with_resolution(spline, point, 0, 0, tot_diff_point); +} + +void BKE_mask_point_segment_co(MaskSpline *spline, MaskSplinePoint *point, float u, float co[2]) +{ + MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point); + + BezTriple *bezt = &point->bezt, *bezt_next; + float q0[2], q1[2], q2[2], r0[2], r1[2]; + + bezt_next = mask_spline_point_next_bezt(spline, points_array, point); + + if (!bezt_next) { + copy_v2_v2(co, bezt->vec[1]); + return; + } + + interp_v2_v2v2(q0, bezt->vec[1], bezt->vec[2], u); + interp_v2_v2v2(q1, bezt->vec[2], bezt_next->vec[0], u); + interp_v2_v2v2(q2, bezt_next->vec[0], bezt_next->vec[1], u); + + interp_v2_v2v2(r0, q0, q1, u); + interp_v2_v2v2(r1, q1, q2, u); + + interp_v2_v2v2(co, r0, r1, u); +} + +void BKE_mask_point_normal(MaskSpline *spline, MaskSplinePoint *point, float u, float n[2]) +{ + MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point); + + BezTriple *bezt = &point->bezt, *bezt_next; + float q0[2], q1[2], q2[2], r0[2], r1[2], vec[2]; + + bezt_next = mask_spline_point_next_bezt(spline, points_array, point); + + if (!bezt_next) { + BKE_mask_point_handle(point, vec); + + sub_v2_v2v2(n, vec, bezt->vec[1]); + normalize_v2(n); + return; + } + + interp_v2_v2v2(q0, bezt->vec[1], bezt->vec[2], u); + interp_v2_v2v2(q1, bezt->vec[2], bezt_next->vec[0], u); + interp_v2_v2v2(q2, bezt_next->vec[0], bezt_next->vec[1], u); + + interp_v2_v2v2(r0, q0, q1, u); + interp_v2_v2v2(r1, q1, q2, u); + + sub_v2_v2v2(vec, r1, r0); + + n[0] = -vec[1]; + n[1] = vec[0]; + + normalize_v2(n); +} + +static float mask_point_interp_weight(BezTriple *bezt, BezTriple *bezt_next, const float u) +{ + return (bezt->weight * (1.0f - u)) + (bezt_next->weight * u); +} + +float BKE_mask_point_weight_scalar(MaskSpline *spline, MaskSplinePoint *point, const float u) +{ + MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point); + BezTriple *bezt = &point->bezt, *bezt_next; + + bezt_next = mask_spline_point_next_bezt(spline, points_array, point); + + if (!bezt_next) { + return bezt->weight; + } + else if (u <= 0.0) { + return bezt->weight; + } + else if (u >= 1.0f) { + return bezt_next->weight; + } + else { + return mask_point_interp_weight(bezt, bezt_next, u); + } +} + +float BKE_mask_point_weight(MaskSpline *spline, MaskSplinePoint *point, const float u) +{ + MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point); + BezTriple *bezt = &point->bezt, *bezt_next; + + bezt_next = mask_spline_point_next_bezt(spline, points_array, point); + + if (!bezt_next) { + return bezt->weight; + } + else if (u <= 0.0) { + return bezt->weight; + } + else if (u >= 1.0f) { + return bezt_next->weight; + } + else { + float cur_u = 0.0f, cur_w = 0.0f, next_u = 0.0f, next_w = 0.0f, fac; /* Quite warnings */ + int i; + + for (i = 0; i < point->tot_uw + 1; i++) { + + if (i == 0) { + cur_u = 0.0f; + cur_w = 1.0f; /* mask_point_interp_weight will scale it */ + } + else { + cur_u = point->uw[i - 1].u; + cur_w = point->uw[i - 1].w; + } + + if (i == point->tot_uw) { + next_u = 1.0f; + next_w = 1.0f; /* mask_point_interp_weight will scale it */ + } + else { + next_u = point->uw[i].u; + next_w = point->uw[i].w; + } + + if (u >= cur_u && u <= next_u) { + break; + } + } + + fac = (u - cur_u) / (next_u - cur_u); + + cur_w *= mask_point_interp_weight(bezt, bezt_next, cur_u); + next_w *= mask_point_interp_weight(bezt, bezt_next, next_u); + + if (spline->weight_interp == MASK_SPLINE_INTERP_EASE) { + return cur_w + (next_w - cur_w) * (3.0f * fac * fac - 2.0f * fac * fac * fac); + } + else { + return (1.0f - fac) * cur_w + fac * next_w; + } + } +} + +MaskSplinePointUW *BKE_mask_point_sort_uw(MaskSplinePoint *point, MaskSplinePointUW *uw) +{ + if (point->tot_uw > 1) { + int idx = uw - point->uw; + + if (idx > 0 && point->uw[idx - 1].u > uw->u) { + while (idx > 0 && point->uw[idx - 1].u > point->uw[idx].u) { + SWAP(MaskSplinePointUW, point->uw[idx - 1], point->uw[idx]); + idx--; + } + } + + if (idx < point->tot_uw - 1 && point->uw[idx + 1].u < uw->u) { + while (idx < point->tot_uw - 1 && point->uw[idx + 1].u < point->uw[idx].u) { + SWAP(MaskSplinePointUW, point->uw[idx + 1], point->uw[idx]); + idx++; + } + } + + return &point->uw[idx]; + } + + return uw; +} + +void BKE_mask_point_add_uw(MaskSplinePoint *point, float u, float w) +{ + if (!point->uw) + point->uw = MEM_callocN(sizeof(*point->uw), "mask point uw"); + else + point->uw = MEM_reallocN(point->uw, (point->tot_uw + 1) * sizeof(*point->uw)); + + point->uw[point->tot_uw].u = u; + point->uw[point->tot_uw].w = w; + + point->tot_uw++; + + BKE_mask_point_sort_uw(point, &point->uw[point->tot_uw - 1]); +} + +void BKE_mask_point_select_set(MaskSplinePoint *point, const short do_select) +{ + int i; + + if (do_select) { + MASKPOINT_SEL_ALL(point); + } + else { + MASKPOINT_DESEL_ALL(point); + } + + for (i = 0; i < point->tot_uw; i++) { + if (do_select) { + point->uw[i].flag |= SELECT; + } + else { + point->uw[i].flag &= ~SELECT; + } + } +} + +void BKE_mask_point_select_set_handle(MaskSplinePoint *point, const short do_select) +{ + if (do_select) { + MASKPOINT_SEL_HANDLE(point); + } + else { + MASKPOINT_DESEL_HANDLE(point); + } +} + +/* only mask block itself */ +static Mask *mask_alloc(const char *name) +{ + Mask *mask; + + mask = BKE_libblock_alloc(&G.main->mask, ID_MSK, name); + + return mask; +} + +Mask *BKE_mask_new(const char *name) +{ + Mask *mask; + char mask_name[MAX_ID_NAME - 2]; + + if (name && name[0]) + BLI_strncpy(mask_name, name, sizeof(mask_name)); + else + strcpy(mask_name, "Mask"); + + mask = mask_alloc(mask_name); + + /* arbitrary defaults */ + mask->sfra = 1; + mask->efra = 100; + + return mask; +} + +void BKE_mask_point_free(MaskSplinePoint *point) +{ + if (point->uw) + MEM_freeN(point->uw); +} + +void BKE_mask_spline_free(MaskSpline *spline) +{ + int i = 0; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point; + point = &spline->points[i]; + BKE_mask_point_free(point); + + if (spline->points_deform) { + point = &spline->points_deform[i]; + BKE_mask_point_free(point); + } + } + + MEM_freeN(spline->points); + + if (spline->points_deform) { + MEM_freeN(spline->points_deform); + } + + MEM_freeN(spline); +} + +MaskSpline *BKE_mask_spline_copy(MaskSpline *spline) +{ + MaskSpline *nspline = MEM_callocN(sizeof(MaskSpline), "new spline"); + int i; + + *nspline = *spline; + + nspline->points_deform = NULL; + nspline->points = MEM_dupallocN(nspline->points); + + for (i = 0; i < nspline->tot_point; i++) { + MaskSplinePoint *point = &nspline->points[i]; + + if (point->uw) + point->uw = MEM_dupallocN(point->uw); + } + + return nspline; +} + +/* note: does NOT add to the list */ +MaskLayerShape *BKE_mask_layer_shape_alloc(MaskLayer *masklay, const int frame) +{ + MaskLayerShape *masklay_shape; + int tot_vert = BKE_mask_layer_shape_totvert(masklay); + + masklay_shape = MEM_mallocN(sizeof(MaskLayerShape), __func__); + masklay_shape->frame = frame; + masklay_shape->tot_vert = tot_vert; + masklay_shape->data = MEM_mallocN(tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__); + + return masklay_shape; +} + +void BKE_mask_layer_shape_free(MaskLayerShape *masklay_shape) +{ + MEM_freeN(masklay_shape->data); + + MEM_freeN(masklay_shape); +} + +void BKE_mask_layer_free(MaskLayer *masklay) +{ + MaskSpline *spline; + MaskLayerShape *masklay_shape; + + /* free splines */ + spline = masklay->splines.first; + while (spline) { + MaskSpline *next_spline = spline->next; + + BLI_remlink(&masklay->splines, spline); + BKE_mask_spline_free(spline); + + spline = next_spline; + } + + /* free animation data */ + masklay_shape = masklay->splines_shapes.first; + while (masklay_shape) { + MaskLayerShape *next_masklay_shape = masklay_shape->next; + + BLI_remlink(&masklay->splines_shapes, masklay_shape); + BKE_mask_layer_shape_free(masklay_shape); + + masklay_shape = next_masklay_shape; + } + + MEM_freeN(masklay); +} + +void BKE_mask_free(Mask *mask) +{ + MaskLayer *masklay = mask->masklayers.first; + + while (masklay) { + MaskLayer *next_masklay = masklay->next; + + BLI_remlink(&mask->masklayers, masklay); + BKE_mask_layer_free(masklay); + + masklay = next_masklay; + } +} + +void BKE_mask_unlink(Main *bmain, Mask *mask) +{ + bScreen *scr; + ScrArea *area; + SpaceLink *sl; + + for (scr = bmain->screen.first; scr; scr = scr->id.next) { + for (area = scr->areabase.first; area; area = area->next) { + for (sl = area->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_CLIP) { + SpaceClip *sc = (SpaceClip *) sl; + + if (sc->mask == mask) + sc->mask = NULL; + } + } + } + } + + mask->id.us = 0; +} + +void BKE_mask_coord_from_movieclip(MovieClip *clip, MovieClipUser *user, float r_co[2], const float co[2]) +{ + int width, height; + + /* scaling for the clip */ + BKE_movieclip_get_size(clip, user, &width, &height); + + if (width == height) { + r_co[0] = co[0]; + r_co[1] = co[1]; + } + else if (width < height) { + r_co[0] = ((co[0] - 0.5f) * ((float)width / (float)height)) + 0.5f; + r_co[1] = co[1]; + } + else { /* (width > height) */ + r_co[0] = co[0]; + r_co[1] = ((co[1] - 0.5f) * ((float)height / (float)width)) + 0.5f; + } +} + +/* as above but divide */ +void BKE_mask_coord_to_movieclip(MovieClip *clip, MovieClipUser *user, float r_co[2], const float co[2]) +{ + int width, height; + + /* scaling for the clip */ + BKE_movieclip_get_size(clip, user, &width, &height); + + if (width == height) { + r_co[0] = co[0]; + r_co[1] = co[1]; + } + else if (width < height) { + r_co[0] = ((co[0] - 0.5f) / ((float)width / (float)height)) + 0.5f; + r_co[1] = co[1]; + } + else { /* (width > height) */ + r_co[0] = co[0]; + r_co[1] = ((co[1] - 0.5f) / ((float)height / (float)width)) + 0.5f; + } +} + +static int BKE_mask_evaluate_parent(MaskParent *parent, float ctime, float r_co[2]) +{ + if (!parent) + return FALSE; + + if (parent->id_type == ID_MC) { + if (parent->id) { + MovieClip *clip = (MovieClip *) parent->id; + MovieTracking *tracking = (MovieTracking *) &clip->tracking; + MovieTrackingObject *ob = BKE_tracking_named_object(tracking, parent->parent); + + if (ob) { + MovieTrackingTrack *track = BKE_tracking_named_track(tracking, ob, parent->sub_parent); + + MovieClipUser user = {0}; + user.framenr = ctime; + + if (track) { + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, ctime); + float marker_pos_ofs[2]; + add_v2_v2v2(marker_pos_ofs, marker->pos, track->offset); + BKE_mask_coord_from_movieclip(clip, &user, r_co, marker_pos_ofs); + + return TRUE; + } + } + } + } + + return FALSE; +} + +int BKE_mask_evaluate_parent_delta(MaskParent *parent, float ctime, float r_delta[2]) +{ + float parent_co[2]; + + if (BKE_mask_evaluate_parent(parent, ctime, parent_co)) { + sub_v2_v2v2(r_delta, parent_co, parent->parent_orig); + return TRUE; + } + else { + return FALSE; + } +} + +static void mask_calc_point_handle(MaskSplinePoint *point, MaskSplinePoint *point_prev, MaskSplinePoint *point_next) +{ + BezTriple *bezt = &point->bezt; + BezTriple *bezt_prev = NULL, *bezt_next = NULL; + //int handle_type = bezt->h1; + + if (point_prev) + bezt_prev = &point_prev->bezt; + + if (point_next) + bezt_next = &point_next->bezt; + +#if 1 + if (bezt_prev || bezt_next) { + BKE_nurb_handle_calc(bezt, bezt_prev, bezt_next, 0); + } +#else + if (handle_type == HD_VECT) { + BKE_nurb_handle_calc(bezt, bezt_prev, bezt_next, 0); + } + else if (handle_type == HD_AUTO) { + BKE_nurb_handle_calc(bezt, bezt_prev, bezt_next, 0); + } + else if (handle_type == HD_ALIGN) { + float v1[3], v2[3]; + float vec[3], h[3]; + + sub_v3_v3v3(v1, bezt->vec[0], bezt->vec[1]); + sub_v3_v3v3(v2, bezt->vec[2], bezt->vec[1]); + add_v3_v3v3(vec, v1, v2); + + if (len_v3(vec) > 1e-3) { + h[0] = vec[1]; + h[1] = -vec[0]; + h[2] = 0.0f; + } + else { + copy_v3_v3(h, v1); + } + + add_v3_v3v3(bezt->vec[0], bezt->vec[1], h); + sub_v3_v3v3(bezt->vec[2], bezt->vec[1], h); + } +#endif +} + +void BKE_mask_get_handle_point_adjacent(MaskSpline *spline, MaskSplinePoint *point, + MaskSplinePoint **r_point_prev, MaskSplinePoint **r_point_next) +{ + /* TODO, could avoid calling this at such low level */ + MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point); + + *r_point_prev = mask_spline_point_prev(spline, points_array, point); + *r_point_next = mask_spline_point_next(spline, points_array, point); +} + +/* calculates the tanget of a point by its previous and next + * (ignoring handles - as if its a poly line) */ +void BKE_mask_calc_tangent_polyline(MaskSpline *spline, MaskSplinePoint *point, float t[2]) +{ + float tvec_a[2], tvec_b[2]; + + MaskSplinePoint *point_prev, *point_next; + + BKE_mask_get_handle_point_adjacent(spline, point, + &point_prev, &point_next); + + if (point_prev) { + sub_v2_v2v2(tvec_a, point->bezt.vec[1], point_prev->bezt.vec[1]); + normalize_v2(tvec_a); + } + else { + zero_v2(tvec_a); + } + + if (point_next) { + sub_v2_v2v2(tvec_b, point_next->bezt.vec[1], point->bezt.vec[1]); + normalize_v2(tvec_b); + } + else { + zero_v2(tvec_b); + } + + add_v2_v2v2(t, tvec_a, tvec_b); + normalize_v2(t); +} + +void BKE_mask_calc_handle_point(MaskSpline *spline, MaskSplinePoint *point) +{ + MaskSplinePoint *point_prev, *point_next; + + BKE_mask_get_handle_point_adjacent(spline, point, + &point_prev, &point_next); + + mask_calc_point_handle(point, point_prev, point_next); +} + +static void enforce_dist_v2_v2fl(float v1[2], const float v2[2], const float dist) +{ + if (!equals_v2v2(v2, v1)) { + float nor[2]; + + sub_v2_v2v2(nor, v1, v2); + normalize_v2(nor); + madd_v2_v2v2fl(v1, v2, nor, dist); + } +} + +void BKE_mask_calc_handle_adjacent_interp(MaskSpline *spline, MaskSplinePoint *point, const float u) +{ + /* TODO! - make this interpolate between siblings - not always midpoint! */ + int length_tot = 0; + float length_average = 0.0f; + float weight_average = 0.0f; + + + MaskSplinePoint *point_prev, *point_next; + + BLI_assert(u >= 0.0f && u <= 1.0f); + + BKE_mask_get_handle_point_adjacent(spline, point, + &point_prev, &point_next); + + if (point_prev && point_next) { + length_average = ((len_v2v2(point_prev->bezt.vec[0], point_prev->bezt.vec[1]) * (1.0f - u)) + + (len_v2v2(point_next->bezt.vec[2], point_next->bezt.vec[1]) * u)); + + weight_average = (point_prev->bezt.weight * (1.0f - u) + + point_next->bezt.weight * u); + length_tot = 1; + } + else { + if (point_prev) { + length_average += len_v2v2(point_prev->bezt.vec[0], point_prev->bezt.vec[1]); + weight_average += point_prev->bezt.weight; + length_tot++; + } + + if (point_next) { + length_average += len_v2v2(point_next->bezt.vec[2], point_next->bezt.vec[1]); + weight_average += point_next->bezt.weight; + length_tot++; + } + } + + if (length_tot) { + length_average /= (float)length_tot; + weight_average /= (float)length_tot; + + enforce_dist_v2_v2fl(point->bezt.vec[0], point->bezt.vec[1], length_average); + enforce_dist_v2_v2fl(point->bezt.vec[2], point->bezt.vec[1], length_average); + point->bezt.weight = weight_average; + } +} + + +/** + * \brief Resets auto handles even for non-auto bezier points + * + * Useful for giving sane defaults. + */ +void BKE_mask_calc_handle_point_auto(MaskSpline *spline, MaskSplinePoint *point, + const short do_recalc_length) +{ + MaskSplinePoint *point_prev, *point_next; + const char h_back[2] = {point->bezt.h1, point->bezt.h2}; + const float length_average = (do_recalc_length) ? 0.0f /* dummy value */ : + (len_v3v3(point->bezt.vec[0], point->bezt.vec[1]) + + len_v3v3(point->bezt.vec[1], point->bezt.vec[2])) / 2.0f; + + BKE_mask_get_handle_point_adjacent(spline, point, + &point_prev, &point_next); + + point->bezt.h1 = HD_AUTO; + point->bezt.h2 = HD_AUTO; + mask_calc_point_handle(point, point_prev, point_next); + + point->bezt.h1 = h_back[0]; + point->bezt.h2 = h_back[1]; + + /* preserve length by applying it back */ + if (do_recalc_length == FALSE) { + enforce_dist_v2_v2fl(point->bezt.vec[0], point->bezt.vec[1], length_average); + enforce_dist_v2_v2fl(point->bezt.vec[2], point->bezt.vec[1], length_average); + } +} + +void BKE_mask_layer_calc_handles(MaskLayer *masklay) +{ + MaskSpline *spline; + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + for (i = 0; i < spline->tot_point; i++) { + BKE_mask_calc_handle_point(spline, &spline->points[i]); + } + } +} + +void BKE_mask_layer_calc_handles_deform(MaskLayer *masklay) +{ + MaskSpline *spline; + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + for (i = 0; i < spline->tot_point; i++) { + BKE_mask_calc_handle_point(spline, &spline->points_deform[i]); + } + } +} + +void BKE_mask_calc_handles(Mask *mask) +{ + MaskLayer *masklay; + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + BKE_mask_layer_calc_handles(masklay); + } +} + +void BKE_mask_update_deform(Mask *mask) +{ + MaskLayer *masklay; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + + for (i = 0; i < spline->tot_point; i++) { + const int i_prev = (i - 1) % spline->tot_point; + const int i_next = (i + 1) % spline->tot_point; + + BezTriple *bezt_prev = &spline->points[i_prev].bezt; + BezTriple *bezt = &spline->points[i].bezt; + BezTriple *bezt_next = &spline->points[i_next].bezt; + + BezTriple *bezt_def_prev = &spline->points_deform[i_prev].bezt; + BezTriple *bezt_def = &spline->points_deform[i].bezt; + BezTriple *bezt_def_next = &spline->points_deform[i_next].bezt; + + float w_src[4]; + int j; + + for (j = 0; j <= 2; j += 2) { /* (0, 2) */ + printf("--- %d %d, %d, %d\n", i, j, i_prev, i_next); + barycentric_weights_v2(bezt_prev->vec[1], bezt->vec[1], bezt_next->vec[1], + bezt->vec[j], w_src); + interp_v3_v3v3v3(bezt_def->vec[j], + bezt_def_prev->vec[1], bezt_def->vec[1], bezt_def_next->vec[1], w_src); + } + } + } + } +} + +void BKE_mask_spline_ensure_deform(MaskSpline *spline) +{ + int allocated_points = (MEM_allocN_len(spline->points_deform) / sizeof(*spline->points_deform)); + // printf("SPLINE ALLOC %p %d\n", spline->points_deform, allocated_points); + + if (spline->points_deform == NULL || allocated_points != spline->tot_point) { + printf("alloc new deform spline\n"); + + if (spline->points_deform) { + int i; + + for (i = 0; i < allocated_points; i++) { + MaskSplinePoint *point = &spline->points_deform[i]; + BKE_mask_point_free(point); + } + + MEM_freeN(spline->points_deform); + } + + spline->points_deform = MEM_callocN(sizeof(*spline->points_deform) * spline->tot_point, __func__); + } + else { + // printf("alloc spline done\n"); + } +} + +void BKE_mask_evaluate(Mask *mask, const float ctime, const int do_newframe) +{ + MaskLayer *masklay; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + + /* animation if available */ + if (do_newframe) { + MaskLayerShape *masklay_shape_a; + MaskLayerShape *masklay_shape_b; + int found; + + if ((found = BKE_mask_layer_shape_find_frame_range(masklay, ctime, + &masklay_shape_a, &masklay_shape_b))) + { + if (found == 1) { +#if 0 + printf("%s: exact %d %d (%d)\n", __func__, (int)ctime, BLI_countlist(&masklay->splines_shapes), + masklay_shape_a->frame); +#endif + + BKE_mask_layer_shape_to_mask(masklay, masklay_shape_a); + } + else if (found == 2) { + float w = masklay_shape_b->frame - masklay_shape_a->frame; +#if 0 + printf("%s: tween %d %d (%d %d)\n", __func__, (int)ctime, BLI_countlist(&masklay->splines_shapes), + masklay_shape_a->frame, masklay_shape_b->frame); +#endif + BKE_mask_layer_shape_to_mask_interp(masklay, masklay_shape_a, masklay_shape_b, + (ctime - masklay_shape_a->frame) / w); + } + else { + /* always fail, should never happen */ + BLI_assert(found == 2); + } + } + } + /* animation done... */ + } + + BKE_mask_calc_handles(mask); + + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + int has_auto = FALSE; + + BKE_mask_spline_ensure_deform(spline); + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *point_deform = &spline->points_deform[i]; + float delta[2]; + + BKE_mask_point_free(point_deform); + + *point_deform = *point; + point_deform->uw = point->uw ? MEM_dupallocN(point->uw) : NULL; + + if (BKE_mask_evaluate_parent_delta(&point->parent, ctime, delta)) { + add_v2_v2(point_deform->bezt.vec[0], delta); + add_v2_v2(point_deform->bezt.vec[1], delta); + add_v2_v2(point_deform->bezt.vec[2], delta); + } + + if (point->bezt.h1 == HD_AUTO) { + has_auto = TRUE; + } + } + + /* if the spline has auto handles, these need to be recalculated after deformation */ + if (has_auto) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point_deform = &spline->points_deform[i]; + if (point_deform->bezt.h1 == HD_AUTO) { + BKE_mask_calc_handle_point(spline, point_deform); + } + } + } + /* end extra calc handles loop */ + } + } +} + +/* the purpose of this function is to ensure spline->points_deform is never out of date. + * for now re-evaluate all. eventually this might work differently */ +void BKE_mask_update_display(Mask *mask, float ctime) +{ +#if 0 + MaskLayer *masklay; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + for (spline = masklay->splines.first; spline; spline = spline->next) { + if (spline->points_deform) { + int i = 0; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point; + + if (spline->points_deform) { + point = &spline->points_deform[i]; + BKE_mask_point_free(point); + } + } + if (spline->points_deform) { + MEM_freeN(spline->points_deform); + } + + spline->points_deform = NULL; + } + } + } +#endif + + BKE_mask_evaluate(mask, ctime, FALSE); +} + +void BKE_mask_evaluate_all_masks(Main *bmain, float ctime, const int do_newframe) +{ + Mask *mask; + + for (mask = bmain->mask.first; mask; mask = mask->id.next) { + BKE_mask_evaluate(mask, ctime, do_newframe); + } +} + +void BKE_mask_update_scene(Main *bmain, Scene *scene, const int do_newframe) +{ + Mask *mask; + + for (mask = bmain->mask.first; mask; mask = mask->id.next) { + if (mask->id.flag & LIB_ID_RECALC) { + BKE_mask_evaluate_all_masks(bmain, CFRA, do_newframe); + } + } +} + +void BKE_mask_parent_init(MaskParent *parent) +{ + parent->id_type = ID_MC; +} + + +/* *** own animation/shapekey implimentation *** + * BKE_mask_layer_shape_XXX */ + +int BKE_mask_layer_shape_totvert(MaskLayer *masklay) +{ + int tot = 0; + MaskSpline *spline; + + for (spline = masklay->splines.first; spline; spline = spline->next) { + tot += spline->tot_point; + } + + return tot; +} + +static void mask_layer_shape_from_mask_point(BezTriple *bezt, float fp[MASK_OBJECT_SHAPE_ELEM_SIZE]) +{ + copy_v2_v2(&fp[0], bezt->vec[0]); + copy_v2_v2(&fp[2], bezt->vec[1]); + copy_v2_v2(&fp[4], bezt->vec[2]); + fp[6] = bezt->weight; + fp[7] = bezt->radius; +} + +static void mask_layer_shape_to_mask_point(BezTriple *bezt, float fp[MASK_OBJECT_SHAPE_ELEM_SIZE]) +{ + copy_v2_v2(bezt->vec[0], &fp[0]); + copy_v2_v2(bezt->vec[1], &fp[2]); + copy_v2_v2(bezt->vec[2], &fp[4]); + bezt->weight = fp[6]; + bezt->radius = fp[7]; +} + +/* these functions match. copy is swapped */ +void BKE_mask_layer_shape_from_mask(MaskLayer *masklay, MaskLayerShape *masklay_shape) +{ + int tot = BKE_mask_layer_shape_totvert(masklay); + + if (masklay_shape->tot_vert == tot) { + float *fp = masklay_shape->data; + + MaskSpline *spline; + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + for (i = 0; i < spline->tot_point; i++) { + mask_layer_shape_from_mask_point(&spline->points[i].bezt, fp); + fp += MASK_OBJECT_SHAPE_ELEM_SIZE; + } + } + } + else { + printf("%s: vert mismatch %d != %d (frame %d)\n", + __func__, masklay_shape->tot_vert, tot, masklay_shape->frame); + } +} + +void BKE_mask_layer_shape_to_mask(MaskLayer *masklay, MaskLayerShape *masklay_shape) +{ + int tot = BKE_mask_layer_shape_totvert(masklay); + + if (masklay_shape->tot_vert == tot) { + float *fp = masklay_shape->data; + + MaskSpline *spline; + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + for (i = 0; i < spline->tot_point; i++) { + mask_layer_shape_to_mask_point(&spline->points[i].bezt, fp); + fp += MASK_OBJECT_SHAPE_ELEM_SIZE; + } + } + } + else { + printf("%s: vert mismatch %d != %d (frame %d)\n", + __func__, masklay_shape->tot_vert, tot, masklay_shape->frame); + } +} + +BLI_INLINE void interp_v2_v2v2_flfl(float target[2], const float a[2], const float b[2], + const float t, const float s) +{ + target[0] = s * a[0] + t * b[0]; + target[1] = s * a[1] + t * b[1]; +} + +/* linear interpolation only */ +void BKE_mask_layer_shape_to_mask_interp(MaskLayer *masklay, + MaskLayerShape *masklay_shape_a, + MaskLayerShape *masklay_shape_b, + const float fac) +{ + int tot = BKE_mask_layer_shape_totvert(masklay); + if (masklay_shape_a->tot_vert == tot && masklay_shape_b->tot_vert == tot) { + float *fp_a = masklay_shape_a->data; + float *fp_b = masklay_shape_b->data; + const float ifac = 1.0f - fac; + + MaskSpline *spline; + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + for (i = 0; i < spline->tot_point; i++) { + BezTriple *bezt = &spline->points[i].bezt; + /* *** BKE_mask_layer_shape_from_mask - swapped *** */ + interp_v2_v2v2_flfl(bezt->vec[0], fp_a, fp_b, fac, ifac); fp_a += 2; fp_b += 2; + interp_v2_v2v2_flfl(bezt->vec[1], fp_a, fp_b, fac, ifac); fp_a += 2; fp_b += 2; + interp_v2_v2v2_flfl(bezt->vec[2], fp_a, fp_b, fac, ifac); fp_a += 2; fp_b += 2; + bezt->weight = (fp_a[0] * ifac) + (fp_b[0] * fac); + bezt->radius = (fp_a[1] * ifac) + (fp_b[1] * fac); fp_a += 2; fp_b += 2; + } + } + } + else { + printf("%s: vert mismatch %d != %d != %d (frame %d - %d)\n", + __func__, masklay_shape_a->tot_vert, masklay_shape_b->tot_vert, tot, + masklay_shape_a->frame, masklay_shape_b->frame); + } +} + +MaskLayerShape *BKE_mask_layer_shape_find_frame(MaskLayer *masklay, const int frame) +{ + MaskLayerShape *masklay_shape; + + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + if (frame == masklay_shape->frame) { + return masklay_shape; + } + else if (frame < masklay_shape->frame) { + break; + } + } + + return NULL; +} + +/* when returning 2 - the frame isnt found but before/after frames are */ +int BKE_mask_layer_shape_find_frame_range(MaskLayer *masklay, const float frame, + MaskLayerShape **r_masklay_shape_a, + MaskLayerShape **r_masklay_shape_b) +{ + MaskLayerShape *masklay_shape; + + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + if (frame == masklay_shape->frame) { + *r_masklay_shape_a = masklay_shape; + *r_masklay_shape_b = NULL; + return 1; + } + else if (frame < masklay_shape->frame) { + if (masklay_shape->prev) { + *r_masklay_shape_a = masklay_shape->prev; + *r_masklay_shape_b = masklay_shape; + return 2; + } + else { + *r_masklay_shape_a = masklay_shape; + *r_masklay_shape_b = NULL; + return 1; + } + } + } + + if ((masklay_shape = masklay->splines_shapes.last)) { + *r_masklay_shape_a = masklay_shape; + *r_masklay_shape_b = NULL; + return 1; + } + else { + *r_masklay_shape_a = NULL; + *r_masklay_shape_b = NULL; + + return 0; + } +} + +MaskLayerShape *BKE_mask_layer_shape_varify_frame(MaskLayer *masklay, const int frame) +{ + MaskLayerShape *masklay_shape; + + masklay_shape = BKE_mask_layer_shape_find_frame(masklay, frame); + + if (masklay_shape == NULL) { + masklay_shape = BKE_mask_layer_shape_alloc(masklay, frame); + BLI_addtail(&masklay->splines_shapes, masklay_shape); + BKE_mask_layer_shape_sort(masklay); + } + +#if 0 + { + MaskLayerShape *masklay_shape; + int i = 0; + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + printf("mask %d, %d\n", i++, masklay_shape->frame); + } + } +#endif + + return masklay_shape; +} + +MaskLayerShape *BKE_mask_layer_shape_duplicate(MaskLayerShape *masklay_shape) +{ + MaskLayerShape *masklay_shape_copy; + + masklay_shape_copy = MEM_dupallocN(masklay_shape); + + if (LIKELY(masklay_shape_copy->data)) { + masklay_shape_copy->data = MEM_dupallocN(masklay_shape_copy->data); + } + + return masklay_shape_copy; +} + +void BKE_mask_layer_shape_unlink(MaskLayer *masklay, MaskLayerShape *masklay_shape) +{ + BLI_remlink(&masklay->splines_shapes, masklay_shape); + + BKE_mask_layer_shape_free(masklay_shape); +} + +static int mask_layer_shape_sort_cb(void *masklay_shape_a_ptr, void *masklay_shape_b_ptr) +{ + MaskLayerShape *masklay_shape_a = (MaskLayerShape *)masklay_shape_a_ptr; + MaskLayerShape *masklay_shape_b = (MaskLayerShape *)masklay_shape_b_ptr; + + if (masklay_shape_a->frame < masklay_shape_b->frame) return -1; + else if (masklay_shape_a->frame > masklay_shape_b->frame) return 1; + else return 0; +} + +void BKE_mask_layer_shape_sort(MaskLayer *masklay) +{ + BLI_sortlist(&masklay->splines_shapes, mask_layer_shape_sort_cb); +} + +int BKE_mask_layer_shape_spline_from_index(MaskLayer *masklay, int index, + MaskSpline **r_masklay_shape, int *r_index) +{ + MaskSpline *spline; + + for (spline = masklay->splines.first; spline; spline = spline->next) { + if (index < spline->tot_point) { + *r_masklay_shape = spline; + *r_index = index; + return TRUE; + } + index -= spline->tot_point; + } + + return FALSE; +} + +int BKE_mask_layer_shape_spline_to_index(MaskLayer *masklay, MaskSpline *spline) +{ + MaskSpline *spline_iter; + int i_abs = 0; + for (spline_iter = masklay->splines.first; + spline_iter && spline_iter != spline; + i_abs += spline_iter->tot_point, spline_iter = spline_iter->next) + { + /* pass */ + } + + return i_abs; +} + +/* basic 2D interpolation functions, could make more comprehensive later */ +static void interp_weights_uv_v2_calc(float r_uv[2], const float pt[2], const float pt_a[2], const float pt_b[2]) +{ + float pt_on_line[2]; + r_uv[0] = closest_to_line_v2(pt_on_line, pt, pt_a, pt_b); + r_uv[1] = (len_v2v2(pt_on_line, pt) / len_v2v2(pt_a, pt_b)) * + ((line_point_side_v2(pt_a, pt_b, pt) < 0.0f) ? -1.0 : 1.0); /* this line only sets the sign */ +} + + +static void interp_weights_uv_v2_apply(const float uv[2], float r_pt[2], const float pt_a[2], const float pt_b[2]) +{ + const float dvec[2] = {pt_b[0] - pt_a[0], + pt_b[1] - pt_a[1]}; + + /* u */ + madd_v2_v2v2fl(r_pt, pt_a, dvec, uv[0]); + + /* v */ + r_pt[0] += -dvec[1] * uv[1]; + r_pt[1] += dvec[0] * uv[1]; +} + +/* when a now points added - resize all shapekey array */ +void BKE_mask_layer_shape_changed_add(MaskLayer *masklay, int index, + int do_init, int do_init_interpolate) +{ + MaskLayerShape *masklay_shape; + + /* spline index from masklay */ + MaskSpline *spline; + int spline_point_index; + + if (BKE_mask_layer_shape_spline_from_index(masklay, index, + &spline, &spline_point_index)) + { + /* sanity check */ + /* the point has already been removed in this array so subtract one when comparing with the shapes */ + int tot = BKE_mask_layer_shape_totvert(masklay) - 1; + + /* for interpolation */ + /* TODO - assumes closed curve for now */ + float uv[3][2]; /* 3x 2D handles */ + const int pi_curr = spline_point_index; + const int pi_prev = ((spline_point_index - 1) + spline->tot_point) % spline->tot_point; + const int pi_next = (spline_point_index + 1) % spline->tot_point; + + const int index_offset = index - spline_point_index; + /* const int pi_curr_abs = index; */ + const int pi_prev_abs = pi_prev + index_offset; + const int pi_next_abs = pi_next + index_offset; + + int i; + if (do_init_interpolate) { + for (i = 0; i < 3; i++) { + interp_weights_uv_v2_calc(uv[i], + spline->points[pi_curr].bezt.vec[i], + spline->points[pi_prev].bezt.vec[i], + spline->points[pi_next].bezt.vec[i]); + } + } + + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + if (tot == masklay_shape->tot_vert) { + float *data_resized; + + masklay_shape->tot_vert++; + data_resized = MEM_mallocN(masklay_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__); + if (index > 0) { + memcpy(data_resized, + masklay_shape->data, + index * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + } + + if (index != masklay_shape->tot_vert - 1) { + memcpy(&data_resized[(index + 1) * MASK_OBJECT_SHAPE_ELEM_SIZE], + masklay_shape->data + (index * MASK_OBJECT_SHAPE_ELEM_SIZE), + (masklay_shape->tot_vert - (index + 1)) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + } + + if (do_init) { + float *fp = &data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE]; + + mask_layer_shape_from_mask_point(&spline->points[spline_point_index].bezt, fp); + + if (do_init_interpolate && spline->tot_point > 2) { + for (i = 0; i < 3; i++) { + interp_weights_uv_v2_apply(uv[i], + &fp[i * 2], + &data_resized[(pi_prev_abs * MASK_OBJECT_SHAPE_ELEM_SIZE) + (i * 2)], + &data_resized[(pi_next_abs * MASK_OBJECT_SHAPE_ELEM_SIZE) + (i * 2)]); + } + } + } + else { + memset(&data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE], + 0, + sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + } + + MEM_freeN(masklay_shape->data); + masklay_shape->data = data_resized; + } + else { + printf("%s: vert mismatch %d != %d (frame %d)\n", + __func__, masklay_shape->tot_vert, tot, masklay_shape->frame); + } + } + } +} + + +/* move array to account for removed point */ +void BKE_mask_layer_shape_changed_remove(MaskLayer *masklay, int index, int count) +{ + MaskLayerShape *masklay_shape; + + /* the point has already been removed in this array so add one when comparing with the shapes */ + int tot = BKE_mask_layer_shape_totvert(masklay); + + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + if (tot == masklay_shape->tot_vert - count) { + float *data_resized; + + masklay_shape->tot_vert -= count; + data_resized = MEM_mallocN(masklay_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__); + if (index > 0) { + memcpy(data_resized, + masklay_shape->data, + index * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + } + + if (index != masklay_shape->tot_vert) { + memcpy(&data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE], + masklay_shape->data + ((index + count) * MASK_OBJECT_SHAPE_ELEM_SIZE), + (masklay_shape->tot_vert - index) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE); + } + + MEM_freeN(masklay_shape->data); + masklay_shape->data = data_resized; + } + else { + printf("%s: vert mismatch %d != %d (frame %d)\n", + __func__, masklay_shape->tot_vert - count, tot, masklay_shape->frame); + } + } +} + +/* local functions */ +static void invert_vn_vn(float *array, const int size) +{ + float *arr = array + (size - 1); + int i = size; + while (i--) { + *(arr) = 1.0f - *(arr); + arr--; + } +} + +static void m_invert_vn_vn(float *array, const float f, const int size) +{ + float *arr = array + (size - 1); + int i = size; + while (i--) { + *(arr) = 1.0f - (*(arr) * f); + arr--; + } +} + +static void clamp_vn_vn_linear(float *array, const int size) +{ + float *arr = array + (size - 1); + + int i = size; + while (i--) { + if (*arr <= 0.0f) *arr = 0.0f; + else if (*arr >= 1.0f) *arr = 1.0f; + else *arr = srgb_to_linearrgb(*arr); + arr--; + } +} + +static void clamp_vn_vn(float *array, const int size) +{ + float *arr = array + (size - 1); + + int i = size; + while (i--) { + if (*arr < 0.0f) *arr = 0.0f; + else if (*arr > 1.0f) *arr = 1.0f; + arr--; + } +} + +int BKE_mask_get_duration(Mask *mask) +{ + return MAX2(1, mask->efra - mask->sfra); +} + +/* rasterization */ +void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer, + const short do_aspect_correct, const short do_linear) +{ + MaskLayer *masklay; + + /* temp blending buffer */ + const int buffer_size = width * height; + float *buffer_tmp = MEM_mallocN(sizeof(float) * buffer_size, __func__); + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + float alpha; + + if (masklay->restrictflag & MASK_RESTRICT_RENDER) { + continue; + } + + memset(buffer_tmp, 0, sizeof(float) * buffer_size); + + for (spline = masklay->splines.first; spline; spline = spline->next) { + float (*diff_points)[2]; + int tot_diff_point; + + float (*diff_feather_points)[2]; + int tot_diff_feather_points; + + diff_points = BKE_mask_spline_differentiate_with_resolution(spline, width, height, + &tot_diff_point); + + if (tot_diff_point) { + diff_feather_points = + BKE_mask_spline_feather_differentiated_points_with_resolution(spline, width, height, + &tot_diff_feather_points); + + if (do_aspect_correct) { + if (width != height) { + float *fp; + float *ffp; + int i; + float asp; + + if (width < height) { + fp = &diff_points[0][0]; + ffp = tot_diff_feather_points ? &diff_feather_points[0][0] : NULL; + asp = (float)width / (float)height; + } + else { + fp = &diff_points[0][1]; + ffp = tot_diff_feather_points ? &diff_feather_points[0][1] : NULL; + asp = (float)height / (float)width; + } + + for (i = 0; i < tot_diff_point; i++, fp += 2) { + (*fp) = (((*fp) - 0.5f) / asp) + 0.5f; + } + + if (tot_diff_feather_points) { + for (i = 0; i < tot_diff_feather_points; i++, ffp += 2) { + (*ffp) = (((*ffp) - 0.5f) / asp) + 0.5f; + } + } + } + } + + if (tot_diff_point) { + PLX_raskterize(diff_points, tot_diff_point, + buffer_tmp, width, height); + + if (tot_diff_feather_points) { + PLX_raskterize_feather(diff_points, tot_diff_point, + diff_feather_points, tot_diff_feather_points, + buffer_tmp, width, height); + MEM_freeN(diff_feather_points); + } + + MEM_freeN(diff_points); + } + } + } + + /* blend with original */ + if (masklay->blend_flag & MASK_BLENDFLAG_INVERT) { + /* apply alpha multiply before inverting */ + if (masklay->alpha != 1.0f) { + m_invert_vn_vn(buffer_tmp, masklay->alpha, buffer_size); + } + else { + invert_vn_vn(buffer_tmp, buffer_size); + } + + alpha = 1.0f; + } + else { + alpha = masklay->alpha; + } + + switch (masklay->blend) { + case MASK_BLEND_SUBTRACT: + { + if (alpha == 1.0f) { + sub_vn_vn(buffer, buffer_tmp, buffer_size); + } + else { + msub_vn_vn(buffer, buffer_tmp, alpha, buffer_size); + } + break; + } + case MASK_BLEND_ADD: + default: + { + if (alpha == 1.0f) { + add_vn_vn(buffer, buffer_tmp, buffer_size); + } + else { + madd_vn_vn(buffer, buffer_tmp, alpha, buffer_size); + } + break; + } + } + + /* clamp at the end */ + if (do_linear) { + clamp_vn_vn_linear(buffer, buffer_size); + } + else { + clamp_vn_vn(buffer, buffer_size); + } + } + + MEM_freeN(buffer_tmp); +} diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index fd952b7b518..d0b9e73e295 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -1946,8 +1946,8 @@ void BKE_mesh_calc_normals_tessface(MVert *mverts, int numVerts, MFace *mfaces, MEM_freeN(fnors); } - -static void bm_corners_to_loops(Mesh *me, int findex, int loopstart, int numTex, int numCol) +static void bm_corners_to_loops_ex(ID *id, CustomData *fdata, CustomData *ldata, CustomData *pdata, + MFace *mface, int totloop, int findex, int loopstart, int numTex, int numCol) { MTFace *texface; MTexPoly *texpoly; @@ -1957,15 +1957,15 @@ static void bm_corners_to_loops(Mesh *me, int findex, int loopstart, int numTex, MFace *mf; int i; - mf = me->mface + findex; + mf = mface + findex; for (i = 0; i < numTex; i++) { - texface = CustomData_get_n(&me->fdata, CD_MTFACE, findex, i); - texpoly = CustomData_get_n(&me->pdata, CD_MTEXPOLY, findex, i); - + texface = CustomData_get_n(fdata, CD_MTFACE, findex, i); + texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, findex, i); + ME_MTEXFACE_CPY(texpoly, texface); - - mloopuv = CustomData_get_n(&me->ldata, CD_MLOOPUV, loopstart, i); + + mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, loopstart, i); copy_v2_v2(mloopuv->uv, texface->uv[0]); mloopuv++; copy_v2_v2(mloopuv->uv, texface->uv[1]); mloopuv++; copy_v2_v2(mloopuv->uv, texface->uv[2]); mloopuv++; @@ -1976,8 +1976,8 @@ static void bm_corners_to_loops(Mesh *me, int findex, int loopstart, int numTex, } for (i = 0; i < numCol; i++) { - mloopcol = CustomData_get_n(&me->ldata, CD_MLOOPCOL, loopstart, i); - mcol = CustomData_get_n(&me->fdata, CD_MCOL, findex, i); + mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, loopstart, i); + mcol = CustomData_get_n(fdata, CD_MCOL, findex, i); MESH_MLOOPCOL_FROM_MCOL(mloopcol, &mcol[0]); mloopcol++; MESH_MLOOPCOL_FROM_MCOL(mloopcol, &mcol[1]); mloopcol++; @@ -1986,21 +1986,23 @@ static void bm_corners_to_loops(Mesh *me, int findex, int loopstart, int numTex, MESH_MLOOPCOL_FROM_MCOL(mloopcol, &mcol[3]); mloopcol++; } } - - if (CustomData_has_layer(&me->fdata, CD_MDISPS)) { - MDisps *ld = CustomData_get(&me->ldata, loopstart, CD_MDISPS); - MDisps *fd = CustomData_get(&me->fdata, findex, CD_MDISPS); + + if (CustomData_has_layer(fdata, CD_MDISPS)) { + MDisps *ld = CustomData_get(ldata, loopstart, CD_MDISPS); + MDisps *fd = CustomData_get(fdata, findex, CD_MDISPS); float (*disps)[3] = fd->disps; int i, tot = mf->v4 ? 4 : 3; int side, corners; - if (CustomData_external_test(&me->fdata, CD_MDISPS)) { - CustomData_external_add(&me->ldata, &me->id, CD_MDISPS, - me->totloop, me->fdata.external->filename); + if (CustomData_external_test(fdata, CD_MDISPS)) { + if (id) { + CustomData_external_add(ldata, id, CD_MDISPS, + totloop, fdata->external->filename); + } } - + corners = multires_mdisp_corners(fd); - + if (corners == 0) { /* Empty MDisp layers appear in at least one of the sintel.blend files. * Not sure why this happens, but it seems fine to just ignore them here. @@ -2009,14 +2011,14 @@ static void bm_corners_to_loops(Mesh *me, int findex, int loopstart, int numTex, } else { side = sqrt(fd->totdisp / corners); - + for (i = 0; i < tot; i++, disps += side * side, ld++) { ld->totdisp = side * side; ld->level = (int)(logf(side - 1.0f) / (float)M_LN2) + 1; - + if (ld->disps) MEM_freeN(ld->disps); - + ld->disps = MEM_callocN(sizeof(float) * 3 * side * side, "converted loop mdisps"); if (fd->disps) { memcpy(ld->disps, disps, sizeof(float) * 3 * side * side); @@ -2028,70 +2030,109 @@ static void bm_corners_to_loops(Mesh *me, int findex, int loopstart, int numTex, 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); + + mesh_update_customdata_pointers(mesh, TRUE); +} + +/* the same as BKE_mesh_convert_mfaces_to_mpolys but oriented to be used in do_versions from readfile.c + * the difference is how active/render/clone/stencil indices are handled here + * + * normally thay're being set from pdata which totally makes sense for meshes which are already + * converted to bmesh structures, but when loading older files indices shall be updated in other + * way around, so newly added pdata and ldata would have this indices set based on fdata layer + * + * this is normally only needed when reading older files, in all other cases BKE_mesh_convert_mfaces_to_mpolys + * shall be always used + */ +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); + + CustomData_bmesh_do_versions_update_active_layers(&mesh->fdata, &mesh->pdata, &mesh->ldata); + + 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 *totloop_r, int *totpoly_r, + MLoop **mloop_r, MPoly **mpoly_r) +{ MFace *mf; - MLoop *ml; - MPoly *mp; + MLoop *ml, *mloop; + MPoly *mp, *mpoly; MEdge *me; EdgeHash *eh; int numTex, numCol; - int i, j, totloop; + int i, j, totloop, totpoly, *polyindex; /* just in case some of these layers are filled in (can happen with python created meshes) */ - CustomData_free(&mesh->ldata, mesh->totloop); - CustomData_free(&mesh->pdata, mesh->totpoly); - memset(&mesh->ldata, 0, sizeof(mesh->ldata)); - memset(&mesh->pdata, 0, sizeof(mesh->pdata)); + CustomData_free(ldata, totloop_i); + CustomData_free(pdata, totpoly_i); + memset(ldata, 0, sizeof(*ldata)); + memset(pdata, 0, sizeof(*pdata)); - mesh->totpoly = mesh->totface; - mesh->mpoly = MEM_callocN(sizeof(MPoly) * mesh->totpoly, "mpoly converted"); - CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_ASSIGN, mesh->mpoly, mesh->totpoly); + totpoly = totface_i; + mpoly = MEM_callocN(sizeof(MPoly) * totpoly, "mpoly converted"); + CustomData_add_layer(pdata, CD_MPOLY, CD_ASSIGN, mpoly, totpoly); + + numTex = CustomData_number_of_layers(fdata, CD_MTFACE); + numCol = CustomData_number_of_layers(fdata, CD_MCOL); - numTex = CustomData_number_of_layers(&mesh->fdata, CD_MTFACE); - numCol = CustomData_number_of_layers(&mesh->fdata, CD_MCOL); - totloop = 0; - mf = mesh->mface; - for (i = 0; i < mesh->totface; i++, mf++) { + mf = mface; + for (i = 0; i < totface_i; i++, mf++) { totloop += mf->v4 ? 4 : 3; } - - mesh->totloop = totloop; - mesh->mloop = MEM_callocN(sizeof(MLoop) * mesh->totloop, "mloop converted"); - CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_ASSIGN, mesh->mloop, totloop); - CustomData_to_bmeshpoly(&mesh->fdata, &mesh->pdata, &mesh->ldata, - mesh->totloop, mesh->totpoly); + mloop = MEM_callocN(sizeof(MLoop) * totloop, "mloop converted"); + + CustomData_add_layer(ldata, CD_MLOOP, CD_ASSIGN, mloop, totloop); - /* ensure external data is transferred */ - CustomData_external_read(&mesh->fdata, &mesh->id, CD_MASK_MDISPS, mesh->totface); + CustomData_to_bmeshpoly(fdata, pdata, ldata, totloop, totpoly); + + if (id) { + /* ensure external data is transferred */ + CustomData_external_read(fdata, id, CD_MASK_MDISPS, totface_i); + } eh = BLI_edgehash_new(); - /*build edge hash*/ - me = mesh->medge; - for (i = 0; i < mesh->totedge; i++, me++) { + /* build edge hash */ + me = medge; + for (i = 0; i < totedge_i; i++, me++) { BLI_edgehash_insert(eh, me->v1, me->v2, SET_INT_IN_POINTER(i)); /* unrelated but avoid having the FGON flag enabled, so we can reuse it later for something else */ me->flag &= ~ME_FGON; } - j = 0; /*current loop index*/ - ml = mesh->mloop; - mf = mesh->mface; - mp = mesh->mpoly; - for (i = 0; i < mesh->totface; i++, mf++, mp++) { + polyindex = CustomData_get_layer(fdata, CD_POLYINDEX); + + j = 0; /* current loop index */ + ml = mloop; + mf = mface; + mp = mpoly; + for (i = 0; i < totface_i; i++, mf++, mp++) { mp->loopstart = j; - + mp->totloop = mf->v4 ? 4 : 3; mp->mat_nr = mf->mat_nr; mp->flag = mf->flag; - + # define ML(v1, v2) { \ ml->v = mf->v1; ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v1, mf->v2)); ml++; j++; \ } (void)0 - + ML(v1, v2); ML(v2, v3); if (mf->v4) { @@ -2101,18 +2142,26 @@ void BKE_mesh_convert_mfaces_to_mpolys(Mesh *mesh) else { ML(v3, v1); } - + # undef ML - bm_corners_to_loops(mesh, i, mp->loopstart, numTex, numCol); + bm_corners_to_loops_ex(id, fdata, ldata, pdata, mface, totloop, i, mp->loopstart, numTex, numCol); + + if (polyindex) { + *polyindex = i; + polyindex++; + } } /* note, we don't convert FGons at all, these are not even real ngons, * they have their own UV's, colors etc - its more an editing feature. */ - mesh_update_customdata_pointers(mesh, TRUE); - BLI_edgehash_free(eh, NULL); + + *totpoly_r = totpoly; + *totloop_r = totloop; + *mpoly_r = mpoly; + *mloop_r = mloop; } float (*mesh_getVertexCos(Mesh * me, int *numVerts_r))[3] diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index ccf64639967..8b91ee29c59 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -154,11 +154,12 @@ static void get_sequence_fname(MovieClip *clip, int framenr, char *name) BLI_stringdec(name, head, tail, &numlen); /* movieclips always points to first image from sequence, - * autoguess offset for now. could be something smarter in the future */ + * autoguess offset for now. could be something smarter in the future + */ offset = sequence_guess_offset(clip->name, strlen(head), numlen); if (numlen) - BLI_stringenc(name, head, tail, numlen, offset + framenr - 1); + BLI_stringenc(name, head, tail, numlen, offset + framenr - clip->start_frame); else BLI_strncpy(name, clip->name, sizeof(clip->name)); @@ -170,6 +171,7 @@ static void get_proxy_fname(MovieClip *clip, int proxy_render_size, int undistor { int size = rendersize_to_number(proxy_render_size); char dir[FILE_MAX], clipdir[FILE_MAX], clipfile[FILE_MAX]; + int proxynr = framenr - clip->start_frame + 1; BLI_split_dirfile(clip->name, clipdir, clipfile, FILE_MAX, FILE_MAX); @@ -181,9 +183,9 @@ static void get_proxy_fname(MovieClip *clip, int proxy_render_size, int undistor } if (undistorted) - BLI_snprintf(name, FILE_MAX, "%s/%s/proxy_%d_undistorted/%08d", dir, clipfile, size, framenr); + BLI_snprintf(name, FILE_MAX, "%s/%s/proxy_%d_undistorted/%08d", dir, clipfile, size, proxynr); else - BLI_snprintf(name, FILE_MAX, "%s/%s/proxy_%d/%08d", dir, clipfile, size, framenr); + BLI_snprintf(name, FILE_MAX, "%s/%s/proxy_%d/%08d", dir, clipfile, size, proxynr); BLI_path_abs(name, G.main->name); BLI_path_frame(name, 1, 0); @@ -248,7 +250,7 @@ static ImBuf *movieclip_load_movie_file(MovieClip *clip, MovieClipUser *user, in int fra; dur = IMB_anim_get_duration(clip->anim, tc); - fra = framenr - 1; + fra = framenr - clip->start_frame; if (fra < 0) fra = 0; @@ -312,7 +314,7 @@ typedef struct MovieClipCache { /* cache for undistorted shot */ float principal[2]; float k1, k2, k3; - short undistoriton_used; + short undistortion_used; int proxy; short render_flag; @@ -443,6 +445,8 @@ static MovieClip *movieclip_alloc(const char *name) IMB_TC_RECORD_RUN_NO_GAPS; clip->proxy.quality = 90; + clip->start_frame = 1; + return clip; } @@ -623,7 +627,7 @@ static ImBuf *get_postprocessed_cached_frame(MovieClip *clip, MovieClipUser *use if (!check_undistortion_cache_flags(clip)) return NULL; } - else if (cache->postprocessed.undistoriton_used) + else if (cache->postprocessed.undistortion_used) return NULL; IMB_refImBuf(cache->postprocessed.ibuf); @@ -656,11 +660,11 @@ static ImBuf *put_postprocessed_frame_to_cache(MovieClip *clip, MovieClipUser *u if (need_undistortion_postprocess(user, flag)) { copy_v2_v2(cache->postprocessed.principal, camera->principal); copy_v3_v3(&cache->postprocessed.k1, &camera->k1); - cache->postprocessed.undistoriton_used = TRUE; + cache->postprocessed.undistortion_used = TRUE; postproc_ibuf = get_undistorted_ibuf(clip, NULL, ibuf); } else { - cache->postprocessed.undistoriton_used = FALSE; + cache->postprocessed.undistortion_used = FALSE; } if (postprocess_flag) { @@ -912,7 +916,17 @@ int BKE_movieclip_has_frame(MovieClip *clip, MovieClipUser *user) void BKE_movieclip_get_size(MovieClip *clip, MovieClipUser *user, int *width, int *height) { +#if 0 + /* originally was needed to support image sequences with different image dimensions, + * which might be useful for such things as reconstruction of unordered image sequence, + * or painting/rotoscoping of non-equal-sized images, but this ended up in unneeded + * cache lookups and even unwanted non-proxied files loading when doing mask parenting, + * so let's disable this for now and assume image sequence consists of images with + * equal sizes (sergey) + */ if (user->framenr == clip->lastframe) { +#endif + if (clip->lastsize[0] != 0 && clip->lastsize[1] != 0) { *width = clip->lastsize[0]; *height = clip->lastsize[1]; } @@ -1018,6 +1032,11 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip scopes->track_preview = NULL; } + if (scopes->track_search) { + IMB_freeImBuf(scopes->track_search); + scopes->track_search = NULL; + } + scopes->marker = NULL; scopes->track = NULL; @@ -1026,7 +1045,8 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip if (act_track) { MovieTrackingTrack *track = act_track; - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, user->framenr); + int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr); + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); if (marker->flag & MARKER_DISABLED) { scopes->track_disabled = TRUE; @@ -1037,7 +1057,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip scopes->track_disabled = FALSE; if (ibuf && (ibuf->rect || ibuf->rect_float)) { - ImBuf *tmpibuf; + ImBuf *search_ibuf; MovieTrackingMarker undist_marker = *marker; if (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) { @@ -1055,27 +1075,36 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip undist_marker.pos[1] /= height * aspy; } - /* NOTE: margin should be kept in sync with value from ui_draw_but_TRACKPREVIEW */ - tmpibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, &undist_marker, 3 /* margin */, - 1 /* anchor */, scopes->track_pos, NULL); + search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, &undist_marker, TRUE, TRUE); - if (tmpibuf->rect_float) - IMB_rect_from_float(tmpibuf); + if (!search_ibuf->rect_float) { + /* sampling happens in float buffer */ + IMB_float_from_rect(search_ibuf); + } + + scopes->undist_marker = undist_marker; + scopes->track_search = search_ibuf; - if (tmpibuf->rect) - scopes->track_preview = tmpibuf; - else - IMB_freeImBuf(tmpibuf); + scopes->frame_width = ibuf->x; + scopes->frame_height = ibuf->y; } IMB_freeImBuf(ibuf); } if ((track->flag & TRACK_LOCKED) == 0) { + float pat_min[2], pat_max[2]; + scopes->marker = marker; scopes->track = track; - scopes->slide_scale[0] = track->pat_max[0] - track->pat_min[0]; - scopes->slide_scale[1] = track->pat_max[1] - track->pat_min[1]; + + /* XXX: would work fine with non-transformed patterns, but would likely fail + * with transformed patterns, but that would be easier to debug when + * we'll have real pattern sampling (at least to test) */ + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + + scopes->slide_scale[0] = pat_max[0] - pat_min[0]; + scopes->slide_scale[1] = pat_max[1] - pat_min[1]; } } } @@ -1218,3 +1247,13 @@ void BKE_movieclip_unlink(Main *bmain, MovieClip *clip) clip->id.us = 0; } + +int BKE_movieclip_remap_scene_to_clip_frame(MovieClip *clip, int framenr) +{ + return framenr - clip->start_frame + 1; +} + +int BKE_movieclip_remap_clip_to_scene_frame(MovieClip *clip, int framenr) +{ + return framenr + clip->start_frame - 1; +} diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index d818ca09f20..4cbfb4f0f3e 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -1058,7 +1058,8 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm /* if needed, reallocate multires paint mask */ if (gpm && gpm->level < key.level) { gpm->level = key.level; - MEM_freeN(gpm->data); + if (gpm->data) + MEM_freeN(gpm->data); gpm->data = MEM_callocN(sizeof(float) * key.grid_area, "gpm.data"); } diff --git a/source/blender/blenkernel/intern/navmesh_conversion.c b/source/blender/blenkernel/intern/navmesh_conversion.c index 24382b3bf91..a21878d1d7d 100644 --- a/source/blender/blenkernel/intern/navmesh_conversion.c +++ b/source/blender/blenkernel/intern/navmesh_conversion.c @@ -307,15 +307,15 @@ struct SortContext static int compareByData(void *ctx, const void * a, const void * b) { return (((struct SortContext *)ctx)->recastData[((struct SortContext *)ctx)->trisToFacesMap[*(int*)a]] - - ((struct SortContext *)ctx)->recastData[((struct SortContext *)ctx)->trisToFacesMap[*(int*)b]] ); + ((struct SortContext *)ctx)->recastData[((struct SortContext *)ctx)->trisToFacesMap[*(int*)b]] ); } int buildNavMeshData(const int nverts, const float* verts, - const int ntris, const unsigned short *tris, - const int* recastData, const int* trisToFacesMap, - int *ndtris_r, unsigned short **dtris_r, - int *npolys_r, unsigned short **dmeshes_r, unsigned short **polys_r, - int *vertsPerPoly_r, int **dtrisToPolysMap_r, int **dtrisToTrisMap_r) + const int ntris, const unsigned short *tris, + const int* recastData, const int* trisToFacesMap, + int *ndtris_r, unsigned short **dtris_r, + int *npolys_r, unsigned short **dmeshes_r, unsigned short **polys_r, + int *vertsPerPoly_r, int **dtrisToPolysMap_r, int **dtrisToTrisMap_r) { int *trisMapping; diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 22286e57c0a..d62e91dbde5 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1910,6 +1910,8 @@ static void registerCompositNodes(bNodeTreeType *ttype) register_node_type_cmp_bokehimage(ttype); register_node_type_cmp_bokehblur(ttype); register_node_type_cmp_switch(ttype); + + register_node_type_cmp_mask(ttype); } static void registerShaderNodes(bNodeTreeType *ttype) @@ -1954,6 +1956,7 @@ static void registerShaderNodes(bNodeTreeType *ttype) register_node_type_sh_fresnel(ttype); register_node_type_sh_layer_weight(ttype); register_node_type_sh_tex_coord(ttype); + register_node_type_sh_particle_info(ttype); register_node_type_sh_background(ttype); register_node_type_sh_bsdf_diffuse(ttype); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 3304ccc73cf..b656cb6d8de 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -117,8 +117,6 @@ #include "FRS_freestyle.h" /* Local function protos */ -static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[][4], float slowmat[][4], int simul); - float originmat[3][3]; /* after BKE_object_where_is_calc(), can be used in other functions (bad!) */ void BKE_object_workob_clear(Object *workob) @@ -1914,109 +1912,6 @@ static void ob_parvert3(Object *ob, Object *par, float mat[][4]) } } -static int where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat[4][4]) -{ - float *fp1, *fp2; - float fac1, fac2; - int a; - - // include framerate - fac1 = (1.0f / (1.0f + fabsf(ob->sf)) ); - if (fac1 >= 1.0f) return 0; - fac2 = 1.0f - fac1; - - fp1 = obmat[0]; - fp2 = slowmat[0]; - for (a = 0; a < 16; a++, fp1++, fp2++) { - fp1[0] = fac1 * fp1[0] + fac2 * fp2[0]; - } - - return 1; -} - -void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime) -{ - float slowmat[4][4] = MAT4_UNITY; - float stime = ctime; - - /* new version: correct parent+vertexparent and track+parent */ - /* this one only calculates direct attached parent and track */ - /* is faster, but should keep track of timeoffs */ - - if (ob == NULL) return; - - /* execute drivers only, as animation has already been done */ - BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, ADT_RECALC_DRIVERS); - - if (ob->parent) { - Object *par = ob->parent; - - /* hurms, code below conflicts with depgraph... (ton) */ - /* and even worse, it gives bad effects for NLA stride too (try ctime != par->ctime, with MBlur) */ - if (stime != par->ctime) { - // only for ipo systems? - Object tmp = *par; - - if (par->proxy_from) ; // was a copied matrix, no where_is! bad... - else BKE_object_where_is_calc_time(scene, par, ctime); - - solve_parenting(scene, ob, par, ob->obmat, slowmat, 0); - - *par = tmp; - } - else - solve_parenting(scene, ob, par, ob->obmat, slowmat, 0); - - /* "slow parent" is definitely not threadsafe, and may also give bad results jumping around - * An old-fashioned hack which probably doesn't really cut it anymore - */ - if (ob->partype & PARSLOW) { - if (!where_is_object_parslow(ob, ob->obmat, slowmat)) - return; - } - } - else { - BKE_object_to_mat4(ob, ob->obmat); - } - - /* solve constraints */ - if (ob->constraints.first && !(ob->transflag & OB_NO_CONSTRAINTS)) { - bConstraintOb *cob; - - cob = constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT); - - /* constraints need ctime, not stime. Some call BKE_object_where_is_calc_time and bsystem_time */ - solve_constraints(&ob->constraints, cob, ctime); - - constraints_clear_evalob(cob); - } - - /* set negative scale flag in object */ - if (is_negative_m4(ob->obmat)) ob->transflag |= OB_NEG_SCALE; - else ob->transflag &= ~OB_NEG_SCALE; -} - -/* get object transformation matrix without recalculating dependencies and - * constraints -- assume dependencies are already solved by depsgraph. - * no changes to object and it's parent would be done. - * used for bundles orientation in 3d space relative to parented blender camera */ -void BKE_object_where_is_calc_mat4(Scene *scene, Object *ob, float obmat[4][4]) -{ - float slowmat[4][4] = MAT4_UNITY; - - if (ob->parent) { - Object *par = ob->parent; - - solve_parenting(scene, ob, par, obmat, slowmat, 1); - - if (ob->partype & PARSLOW) - where_is_object_parslow(ob, obmat, slowmat); - } - else { - BKE_object_to_mat4(ob, obmat); - } -} - static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[][4], float slowmat[][4], int simul) { float totmat[4][4]; @@ -2038,11 +1933,11 @@ static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[] ok = 1; } } - + if (ok) mul_serie_m4(totmat, par->obmat, tmat, NULL, NULL, NULL, NULL, NULL, NULL); else copy_m4_m4(totmat, par->obmat); - + break; case PARBONE: ob_parbone(ob, par, tmat); @@ -2062,7 +1957,7 @@ static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[] break; case PARVERT3: ob_parvert3(ob, par, tmat); - + mul_serie_m4(totmat, par->obmat, tmat, NULL, NULL, NULL, NULL, NULL, NULL); break; @@ -2093,7 +1988,87 @@ static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[] copy_v3_v3(ob->orig, totmat[3]); } } +} + +static int where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat[4][4]) +{ + float *fp1, *fp2; + float fac1, fac2; + int a; + + // include framerate + fac1 = (1.0f / (1.0f + fabsf(ob->sf)) ); + if (fac1 >= 1.0f) return 0; + fac2 = 1.0f - fac1; + + fp1 = obmat[0]; + fp2 = slowmat[0]; + for (a = 0; a < 16; a++, fp1++, fp2++) { + fp1[0] = fac1 * fp1[0] + fac2 * fp2[0]; + } + + return 1; +} + +void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime) +{ + if (ob == NULL) return; + + /* execute drivers only, as animation has already been done */ + BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, ADT_RECALC_DRIVERS); + + if (ob->parent) { + Object *par = ob->parent; + float slowmat[4][4] = MAT4_UNITY; + + /* calculate parent matrix */ + solve_parenting(scene, ob, par, ob->obmat, slowmat, 0); + + /* "slow parent" is definitely not threadsafe, and may also give bad results jumping around + * An old-fashioned hack which probably doesn't really cut it anymore + */ + if (ob->partype & PARSLOW) { + if (!where_is_object_parslow(ob, ob->obmat, slowmat)) + return; + } + } + else { + BKE_object_to_mat4(ob, ob->obmat); + } + + /* solve constraints */ + if (ob->constraints.first && !(ob->transflag & OB_NO_CONSTRAINTS)) { + bConstraintOb *cob; + + cob = constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT); + solve_constraints(&ob->constraints, cob, ctime); + constraints_clear_evalob(cob); + } + + /* set negative scale flag in object */ + if (is_negative_m4(ob->obmat)) ob->transflag |= OB_NEG_SCALE; + else ob->transflag &= ~OB_NEG_SCALE; +} +/* get object transformation matrix without recalculating dependencies and + * constraints -- assume dependencies are already solved by depsgraph. + * no changes to object and it's parent would be done. + * used for bundles orientation in 3d space relative to parented blender camera */ +void BKE_object_where_is_calc_mat4(Scene *scene, Object *ob, float obmat[4][4]) +{ + float slowmat[4][4] = MAT4_UNITY; + + if (ob->parent) { + Object *par = ob->parent; + + solve_parenting(scene, ob, par, obmat, slowmat, 1); + + if (ob->partype & PARSLOW) + where_is_object_parslow(ob, obmat, slowmat); + } + else { + BKE_object_to_mat4(ob, obmat); + } } void BKE_object_where_is_calc(struct Scene *scene, Object *ob) @@ -2101,7 +2076,6 @@ void BKE_object_where_is_calc(struct Scene *scene, Object *ob) BKE_object_where_is_calc_time(scene, ob, (float)scene->r.cfra); } - void BKE_object_where_is_calc_simul(Scene *scene, Object *ob) /* was written for the old game engine (until 2.04) */ /* It seems that this function is only called diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index c7f904755d9..f7e3e103e99 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -41,6 +41,7 @@ #include "BLI_utildefines.h" #include "BKE_brush.h" +#include "BKE_context.h" #include "BKE_library.h" #include "BKE_paint.h" #include "BKE_subsurf.h" @@ -83,6 +84,54 @@ Paint *paint_get_active(Scene *sce) return NULL; } +Paint *paint_get_active_from_context(const bContext *C) +{ + Scene *sce = CTX_data_scene(C); + + if (sce) { + ToolSettings *ts = sce->toolsettings; + Object *obact = NULL; + + if (sce->basact && sce->basact->object) + obact = sce->basact->object; + + if (CTX_wm_space_image(C) != NULL) { + if (obact->mode == OB_MODE_EDIT) { + if (ts->use_uv_sculpt) + return &ts->uvsculpt->paint; + else + return &ts->imapaint.paint; + } + else { + return &ts->imapaint.paint; + } + } + else if (obact) { + switch (obact->mode) { + case OB_MODE_SCULPT: + return &ts->sculpt->paint; + case OB_MODE_VERTEX_PAINT: + return &ts->vpaint->paint; + case OB_MODE_WEIGHT_PAINT: + return &ts->wpaint->paint; + case OB_MODE_TEXTURE_PAINT: + return &ts->imapaint.paint; + case OB_MODE_EDIT: + if (ts->use_uv_sculpt) + return &ts->uvsculpt->paint; + else + return &ts->imapaint.paint; + } + } + else { + /* default to image paint */ + return &ts->imapaint.paint; + } + } + + return NULL; +} + Brush *paint_brush(Paint *p) { return p ? p->brush : NULL; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index cdedd818b43..6c7336958b5 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2363,13 +2363,12 @@ static EdgeHash *sph_springhash_build(ParticleSystem *psys) } #define SPH_NEIGHBORS 512 -typedef struct SPHNeighbor -{ +typedef struct SPHNeighbor { ParticleSystem *psys; int index; } SPHNeighbor; -typedef struct SPHRangeData -{ + +typedef struct SPHRangeData { SPHNeighbor neighbors[SPH_NEIGHBORS]; int tot_neighbors; @@ -2641,8 +2640,7 @@ static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float d /************************************************/ /* Basic physics */ /************************************************/ -typedef struct EfData -{ +typedef struct EfData { ParticleTexture ptex; ParticleSimulationData *sim; ParticleData *pa; @@ -2674,7 +2672,7 @@ static void basic_force_cb(void *efdata_v, ParticleKey *state, float *force, flo force[2] += (BLI_frand()-0.5f) * part->brownfac; } - if(part->flag & PART_ROT_DYN && epoint.ave) + if (part->flag & PART_ROT_DYN && epoint.ave) copy_v3_v3(pa->state.ave, epoint.ave); } /* gathers all forces that effect particles and calculates a new state for the particle */ diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 7c9d6bd05be..e0aed029451 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -63,6 +63,7 @@ #include "BKE_idprop.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_mask.h" #include "BKE_node.h" #include "BKE_object.h" #include "BKE_paint.h" @@ -616,8 +617,6 @@ void BKE_scene_set_background(Main *bmain, Scene *scene) /* not too nice... for recovering objects with lost data */ //if (ob->pose == NULL) base->flag &= ~OB_POSEMODE; ob->flag = base->flag; - - ob->ctime = -1234567.0; /* force ipo to be calculated later */ } /* no full animation update, this to enable render code to work (render code calls own animation updates) */ } @@ -1011,6 +1010,9 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen /* update sound system animation */ sound_update_scene(scene); + + /* update masking curves */ + BKE_mask_update_scene(bmain, scene, FALSE); } /* this is called in main loop, doing tagged updates before redraw */ @@ -1081,6 +1083,8 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay) * so don't call within 'scene_update_tagged_recursive' */ DAG_scene_update_flags(bmain, sce, lay, TRUE); // only stuff that moves or needs display still + BKE_mask_evaluate_all_masks(bmain, ctime, TRUE); + /* All 'standard' (i.e. without any dependencies) animation is handled here, * with an 'local' to 'macro' order of evaluation. This should ensure that * settings stored nestled within a hierarchy (i.e. settings in a Texture block diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c index f1f3dd47d8b..582034ae623 100644 --- a/source/blender/blenkernel/intern/seqcache.c +++ b/source/blender/blenkernel/intern/seqcache.c @@ -29,7 +29,7 @@ #include <stddef.h> -#include "BLO_sys_types.h" /* for intptr_t */ +#include "BLO_sys_types.h" /* for intptr_t */ #include "MEM_guardedalloc.h" @@ -38,22 +38,21 @@ #include "IMB_moviecache.h" -typedef struct seqCacheKey -{ - struct Sequence * seq; +typedef struct SeqCacheKey { + struct Sequence *seq; SeqRenderData context; float cfra; seq_stripelem_ibuf_t type; -} seqCacheKey; +} SeqCacheKey; static struct MovieCache *moviecache = NULL; static unsigned int seqcache_hashhash(const void *key_) { - const seqCacheKey *key = (seqCacheKey*) key_; + const SeqCacheKey *key = (SeqCacheKey *) key_; unsigned int rval = seq_hash_render_data(&key->context); - rval ^= *(unsigned int*) &key->cfra; + rval ^= *(unsigned int *) &key->cfra; rval += key->type; rval ^= ((intptr_t) key->seq) << 6; @@ -62,11 +61,11 @@ static unsigned int seqcache_hashhash(const void *key_) static int seqcache_hashcmp(const void *a_, const void *b_) { - const seqCacheKey * a = (seqCacheKey*) a_; - const seqCacheKey * b = (seqCacheKey*) b_; + const SeqCacheKey *a = (SeqCacheKey *) a_; + const SeqCacheKey *b = (SeqCacheKey *) b_; if (a->seq < b->seq) { - return -1; + return -1; } if (a->seq > b->seq) { return 1; @@ -99,18 +98,18 @@ void seq_stripelem_cache_cleanup(void) { if (moviecache) { IMB_moviecache_free(moviecache); - moviecache = IMB_moviecache_create(sizeof(seqCacheKey), seqcache_hashhash, - seqcache_hashcmp, NULL); + moviecache = IMB_moviecache_create(sizeof(SeqCacheKey), seqcache_hashhash, + seqcache_hashcmp, NULL); } } -struct ImBuf * seq_stripelem_cache_get( - SeqRenderData context, struct Sequence * seq, - float cfra, seq_stripelem_ibuf_t type) +struct ImBuf *seq_stripelem_cache_get( + SeqRenderData context, struct Sequence *seq, + float cfra, seq_stripelem_ibuf_t type) { if (moviecache && seq) { - seqCacheKey key; + SeqCacheKey key; key.seq = seq; key.context = context; @@ -124,18 +123,18 @@ struct ImBuf * seq_stripelem_cache_get( } void seq_stripelem_cache_put( - SeqRenderData context, struct Sequence * seq, - float cfra, seq_stripelem_ibuf_t type, struct ImBuf * i) + SeqRenderData context, struct Sequence *seq, + float cfra, seq_stripelem_ibuf_t type, struct ImBuf *i) { - seqCacheKey key; + SeqCacheKey key; if (!i) { return; } if (!moviecache) { - moviecache = IMB_moviecache_create(sizeof(seqCacheKey), seqcache_hashhash, - seqcache_hashcmp, NULL); + moviecache = IMB_moviecache_create(sizeof(SeqCacheKey), seqcache_hashhash, + seqcache_hashcmp, NULL); } key.seq = seq; diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index 4b6c362cd85..6e5149d7924 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -77,7 +77,7 @@ static ImBuf *prepare_effect_imbufs( if (!ibuf1 && !ibuf2 && !ibuf3) { /* hmmm, global float option ? */ - out = IMB_allocImBuf((short)x, (short)y, 32, IB_rect); + out = IMB_allocImBuf(x, y, 32, IB_rect); } else if ((ibuf1 && ibuf1->rect_float) || (ibuf2 && ibuf2->rect_float) || @@ -85,10 +85,10 @@ static ImBuf *prepare_effect_imbufs( { /* if any inputs are rectfloat, output is float too */ - out = IMB_allocImBuf((short)x, (short)y, 32, IB_rectfloat); + out = IMB_allocImBuf(x, y, 32, IB_rectfloat); } else { - out = IMB_allocImBuf((short)x, (short)y, 32, IB_rect); + out = IMB_allocImBuf(x, y, 32, IB_rect); } if (ibuf1 && !ibuf1->rect_float && out->rect_float) { @@ -2987,12 +2987,12 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type) rval.copy = NULL; switch (sequence_type) { - case SEQ_CROSS: + case SEQ_TYPE_CROSS: rval.execute = do_cross_effect; rval.early_out = early_out_fade; rval.get_default_fac = get_default_fac_fade; break; - case SEQ_GAMCROSS: + case SEQ_TYPE_GAMCROSS: rval.init = init_gammacross; rval.load = load_gammacross; rval.free = free_gammacross; @@ -3000,30 +3000,30 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type) rval.get_default_fac = get_default_fac_fade; rval.execute = do_gammacross_effect; break; - case SEQ_ADD: + case SEQ_TYPE_ADD: rval.execute = do_add_effect; rval.early_out = early_out_mul_input2; break; - case SEQ_SUB: + case SEQ_TYPE_SUB: rval.execute = do_sub_effect; rval.early_out = early_out_mul_input2; break; - case SEQ_MUL: + case SEQ_TYPE_MUL: rval.execute = do_mul_effect; rval.early_out = early_out_mul_input2; break; - case SEQ_ALPHAOVER: + case SEQ_TYPE_ALPHAOVER: rval.init = init_alpha_over_or_under; rval.execute = do_alphaover_effect; break; - case SEQ_OVERDROP: + case SEQ_TYPE_OVERDROP: rval.execute = do_overdrop_effect; break; - case SEQ_ALPHAUNDER: + case SEQ_TYPE_ALPHAUNDER: rval.init = init_alpha_over_or_under; rval.execute = do_alphaunder_effect; break; - case SEQ_WIPE: + case SEQ_TYPE_WIPE: rval.init = init_wipe_effect; rval.num_inputs = num_inputs_wipe; rval.free = free_wipe_effect; @@ -3032,21 +3032,21 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type) rval.get_default_fac = get_default_fac_fade; rval.execute = do_wipe_effect; break; - case SEQ_GLOW: + case SEQ_TYPE_GLOW: rval.init = init_glow_effect; rval.num_inputs = num_inputs_glow; rval.free = free_glow_effect; rval.copy = copy_glow_effect; rval.execute = do_glow_effect; break; - case SEQ_TRANSFORM: + case SEQ_TYPE_TRANSFORM: rval.init = init_transform_effect; rval.num_inputs = num_inputs_transform; rval.free = free_transform_effect; rval.copy = copy_transform_effect; rval.execute = do_transform_effect; break; - case SEQ_SPEED: + case SEQ_TYPE_SPEED: rval.init = init_speed_effect; rval.num_inputs = num_inputs_speed; rval.load = load_speed_effect; @@ -3056,7 +3056,7 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type) rval.early_out = early_out_speed; rval.store_icu_yrange = store_icu_yrange_speed; break; - case SEQ_COLOR: + case SEQ_TYPE_COLOR: rval.init = init_solid_color; rval.num_inputs = num_inputs_color; rval.early_out = early_out_color; @@ -3064,12 +3064,12 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type) rval.copy = copy_solid_color; rval.execute = do_solid_color; break; - case SEQ_MULTICAM: + case SEQ_TYPE_MULTICAM: rval.num_inputs = num_inputs_multicam; rval.early_out = early_out_multicam; rval.execute = do_multicam; break; - case SEQ_ADJUSTMENT: + case SEQ_TYPE_ADJUSTMENT: rval.num_inputs = num_inputs_adjustment; rval.early_out = early_out_adjustment; rval.execute = do_adjustment; @@ -3084,7 +3084,7 @@ struct SeqEffectHandle get_sequence_effect(Sequence *seq) { struct SeqEffectHandle rval = {NULL}; - if (seq->type & SEQ_EFFECT) { + if (seq->type & SEQ_TYPE_EFFECT) { rval = get_sequence_effect_impl(seq->type); if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) { rval.load(seq); diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 5318c5514ca..af5b7716bbc 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -29,7 +29,6 @@ * \ingroup bke */ - #include <stddef.h> #include <stdlib.h> #include <string.h> @@ -40,6 +39,7 @@ #include "DNA_sequence_types.h" #include "DNA_movieclip_types.h" +#include "DNA_mask_types.h" #include "DNA_scene_types.h" #include "DNA_anim_types.h" #include "DNA_object_types.h" @@ -61,6 +61,7 @@ #include "BKE_movieclip.h" #include "BKE_fcurve.h" #include "BKE_scene.h" +#include "BKE_mask.h" #include "BKE_utildefines.h" #include "RNA_access.h" @@ -178,7 +179,7 @@ void seq_free_sequence(Scene *scene, Sequence *seq) if (seq->anim) IMB_free_anim(seq->anim); - if (seq->type & SEQ_EFFECT) { + if (seq->type & SEQ_TYPE_EFFECT) { struct SeqEffectHandle sh = get_sequence_effect(seq); sh.free(seq); @@ -195,7 +196,7 @@ void seq_free_sequence(Scene *scene, Sequence *seq) if (ed->act_seq == seq) ed->act_seq = NULL; - if (seq->scene_sound && ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) + if (seq->scene_sound && ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) sound_remove_scene_sound(scene, seq->scene_sound); seq_free_animdata(scene, seq); @@ -543,10 +544,10 @@ static void seq_update_sound_bounds_recursive_rec(Scene *scene, Sequence *metase /* for sound we go over full meta tree to update bounds of the sound strips, * since sound is played outside of evaluating the imbufs, */ for (seq = metaseq->seqbase.first; seq; seq = seq->next) { - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { seq_update_sound_bounds_recursive_rec(scene, seq, MAX2(start, metaseq_start(seq)), MIN2(end, metaseq_end(seq))); } - else if (ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) { + else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) { if (seq->scene_sound) { int startofs = seq->startofs; int endofs = seq->endofs; @@ -582,10 +583,10 @@ void calc_sequence_disp(Scene *scene, Sequence *seq) seq->handsize = (float)((seq->enddisp - seq->startdisp) / 25); } - if (ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) { + if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) { seq_update_sound_bounds(scene, seq); } - else if (seq->type == SEQ_META) + else if (seq->type == SEQ_TYPE_META) seq_update_sound_bounds_recursive(scene, seq); } @@ -603,7 +604,7 @@ void calc_sequence(Scene *scene, Sequence *seq) /* effects and meta: automatic start and end */ - if (seq->type & SEQ_EFFECT) { + if (seq->type & SEQ_TYPE_EFFECT) { /* pointers */ if (seq->seq2 == NULL) seq->seq2 = seq->seq1; if (seq->seq3 == NULL) seq->seq3 = seq->seq1; @@ -641,7 +642,7 @@ void calc_sequence(Scene *scene, Sequence *seq) } } else { - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { seqm = seq->seqbase.first; if (seqm) { min = MAXFRAME * 2; @@ -669,7 +670,10 @@ void reload_sequence_new_file(Scene *scene, Sequence *seq, int lock_range) int prev_startdisp = 0, prev_enddisp = 0; /* note: don't rename the strip, will break animation curves */ - if (ELEM6(seq->type, SEQ_MOVIE, SEQ_IMAGE, SEQ_SOUND, SEQ_SCENE, SEQ_META, SEQ_MOVIECLIP) == 0) { + if (ELEM7(seq->type, + SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE, SEQ_TYPE_SOUND_RAM, + SEQ_TYPE_SCENE, SEQ_TYPE_META, SEQ_TYPE_MOVIECLIP, SEQ_TYPE_MASK) == 0) + { return; } @@ -681,7 +685,7 @@ void reload_sequence_new_file(Scene *scene, Sequence *seq, int lock_range) } switch (seq->type) { - case SEQ_IMAGE: + case SEQ_TYPE_IMAGE: { /* Hack? */ size_t olen = MEM_allocN_len(seq->strip->stripdata) / sizeof(struct StripElem); @@ -694,7 +698,7 @@ void reload_sequence_new_file(Scene *scene, Sequence *seq, int lock_range) } break; } - case SEQ_MOVIE: + case SEQ_TYPE_MOVIE: BLI_join_dirfile(str, sizeof(str), seq->strip->dir, seq->strip->stripdata->name); BLI_path_abs(str, G.main->name); @@ -719,7 +723,7 @@ void reload_sequence_new_file(Scene *scene, Sequence *seq, int lock_range) seq->len = 0; } break; - case SEQ_MOVIECLIP: + case SEQ_TYPE_MOVIECLIP: seq->len = BKE_movieclip_get_duration(seq->clip); seq->len -= seq->anim_startofs; @@ -728,7 +732,16 @@ void reload_sequence_new_file(Scene *scene, Sequence *seq, int lock_range) seq->len = 0; } break; - case SEQ_SOUND: + case SEQ_TYPE_MASK: + seq->len = BKE_mask_get_duration(seq->mask); + + seq->len -= seq->anim_startofs; + seq->len -= seq->anim_endofs; + if (seq->len < 0) { + seq->len = 0; + } + break; + case SEQ_TYPE_SOUND_RAM: #ifdef WITH_AUDASPACE if (!seq->sound) return; @@ -742,7 +755,7 @@ void reload_sequence_new_file(Scene *scene, Sequence *seq, int lock_range) return; #endif break; - case SEQ_SCENE: + case SEQ_TYPE_SCENE: { seq->len = (seq->scene) ? seq->scene->r.efra - seq->scene->r.sfra + 1 : 0; seq->len -= seq->anim_startofs; @@ -781,7 +794,7 @@ void BKE_sequencer_sort(Scene *scene) while ( (seq = ed->seqbasep->first) ) { BLI_remlink(ed->seqbasep, seq); - if (seq->type & SEQ_EFFECT) { + if (seq->type & SEQ_TYPE_EFFECT) { seqt = effbase.first; while (seqt) { if (seqt->machine >= seq->machine) { @@ -895,27 +908,28 @@ void seqbase_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq) static const char *give_seqname_by_type(int type) { switch (type) { - case SEQ_META: return "Meta"; - case SEQ_IMAGE: return "Image"; - case SEQ_SCENE: return "Scene"; - case SEQ_MOVIE: return "Movie"; - case SEQ_MOVIECLIP: return "Clip"; - case SEQ_SOUND: return "Audio"; - case SEQ_CROSS: return "Cross"; - case SEQ_GAMCROSS: return "Gamma Cross"; - case SEQ_ADD: return "Add"; - case SEQ_SUB: return "Sub"; - case SEQ_MUL: return "Mul"; - case SEQ_ALPHAOVER: return "Alpha Over"; - case SEQ_ALPHAUNDER: return "Alpha Under"; - case SEQ_OVERDROP: return "Over Drop"; - case SEQ_WIPE: return "Wipe"; - case SEQ_GLOW: return "Glow"; - case SEQ_TRANSFORM: return "Transform"; - case SEQ_COLOR: return "Color"; - case SEQ_MULTICAM: return "Multicam"; - case SEQ_ADJUSTMENT: return "Adjustment"; - case SEQ_SPEED: return "Speed"; + case SEQ_TYPE_META: return "Meta"; + case SEQ_TYPE_IMAGE: return "Image"; + case SEQ_TYPE_SCENE: return "Scene"; + case SEQ_TYPE_MOVIE: return "Movie"; + case SEQ_TYPE_MOVIECLIP: return "Clip"; + case SEQ_TYPE_MASK: return "Mask"; + case SEQ_TYPE_SOUND_RAM: return "Audio"; + case SEQ_TYPE_CROSS: return "Cross"; + case SEQ_TYPE_GAMCROSS: return "Gamma Cross"; + case SEQ_TYPE_ADD: return "Add"; + case SEQ_TYPE_SUB: return "Sub"; + case SEQ_TYPE_MUL: return "Mul"; + case SEQ_TYPE_ALPHAOVER: return "Alpha Over"; + case SEQ_TYPE_ALPHAUNDER: return "Alpha Under"; + case SEQ_TYPE_OVERDROP: return "Over Drop"; + case SEQ_TYPE_WIPE: return "Wipe"; + case SEQ_TYPE_GLOW: return "Glow"; + case SEQ_TYPE_TRANSFORM: return "Transform"; + case SEQ_TYPE_COLOR: return "Color"; + case SEQ_TYPE_MULTICAM: return "Multicam"; + case SEQ_TYPE_ADJUSTMENT: return "Adjustment"; + case SEQ_TYPE_SPEED: return "Speed"; default: return NULL; } @@ -926,7 +940,7 @@ const char *give_seqname(Sequence *seq) const char *name = give_seqname_by_type(seq->type); if (!name) { - if (seq->type < SEQ_EFFECT) { + if (seq->type < SEQ_TYPE_EFFECT) { return seq->strip->dir; } else { @@ -1008,7 +1022,7 @@ static float give_stripelem_index(Sequence *seq, float cfra) int sta = seq->start; int end = seq->start + seq->len - 1; - if (seq->type & SEQ_EFFECT) { + if (seq->type & SEQ_TYPE_EFFECT) { end = seq->enddisp; } @@ -1041,7 +1055,7 @@ StripElem *give_stripelem(Sequence *seq, int cfra) { StripElem *se = seq->strip->stripdata; - if (seq->type == SEQ_IMAGE) { /* only + if (seq->type == SEQ_TYPE_IMAGE) { /* only * IMAGE strips use the whole array, * MOVIE strips use only * the first element, all other strips @@ -1085,7 +1099,7 @@ int evaluate_seq_frame(Scene *scene, int cfra) static int video_seq_is_rendered(Sequence *seq) { - return (seq && !(seq->flag & SEQ_MUTE) && seq->type != SEQ_SOUND); + return (seq && !(seq->flag & SEQ_MUTE) && seq->type != SEQ_TYPE_SOUND_RAM); } static int get_shown_sequences(ListBase *seqbasep, int cfra, int chanshown, Sequence **seq_arr_out) @@ -1231,7 +1245,7 @@ static int seq_proxy_get_fname(Sequence *seq, int cfra, int render_size, char *n if (seq->flag & (SEQ_USE_PROXY_CUSTOM_DIR | SEQ_USE_PROXY_CUSTOM_FILE)) { BLI_strncpy(dir, seq->strip->proxy->dir, sizeof(dir)); } - else if (seq->type == SEQ_IMAGE) { + else if (seq->type == SEQ_TYPE_IMAGE) { BLI_snprintf(dir, PROXY_MAXFILE, "%s/BL_proxy", seq->strip->dir); } else { @@ -1248,7 +1262,7 @@ static int seq_proxy_get_fname(Sequence *seq, int cfra, int render_size, char *n /* generate a separate proxy directory for each preview size */ - if (seq->type == SEQ_IMAGE) { + if (seq->type == SEQ_TYPE_IMAGE) { BLI_snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy", dir, render_size, give_stripelem(seq, cfra)->name); @@ -1393,7 +1407,7 @@ struct SeqIndexBuildContext *seq_proxy_rebuild_context(Main *bmain, Scene *scene context->orig_seq = seq; context->seq = nseq; - if (nseq->type == SEQ_MOVIE) { + if (nseq->type == SEQ_TYPE_MOVIE) { seq_open_anim_file(nseq); if (nseq->anim) { @@ -1412,7 +1426,7 @@ void seq_proxy_rebuild(SeqIndexBuildContext *context, short *stop, short *do_upd Scene *scene = context->scene; int cfra; - if (seq->type == SEQ_MOVIE) { + if (seq->type == SEQ_TYPE_MOVIE) { if (context->index_context) { IMB_anim_index_rebuild(context->index_context, stop, do_update, progress); } @@ -1642,7 +1656,7 @@ static void color_balance(Sequence *seq, ImBuf *ibuf, float mul) } /* - * input preprocessing for SEQ_IMAGE, SEQ_MOVIE, SEQ_MOVIECLIP and SEQ_SCENE + * input preprocessing for SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP and SEQ_TYPE_SCENE * * Do all the things you can't really do afterwards using sequence effects * (read: before rescaling to render resolution has been done) @@ -1696,7 +1710,7 @@ static ImBuf *input_preprocess( ibuf = IMB_makeSingleUser(ibuf); if ((seq->flag & SEQ_FILTERY) && - !ELEM(seq->type, SEQ_MOVIE, SEQ_MOVIECLIP)) + !ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP)) { IMB_filtery(ibuf); } @@ -1905,8 +1919,7 @@ static ImBuf *seq_render_effect_strip_impl( input[0] = seq->seq1; input[1] = seq->seq2; input[2] = seq->seq3; if (!sh.execute) { /* effect not supported in this version... */ - out = IMB_allocImBuf((short)context.rectx, - (short)context.recty, 32, IB_rect); + out = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rect); return out; } @@ -1983,7 +1996,7 @@ static ImBuf *seq_render_effect_strip_impl( } if (out == NULL) { - out = IMB_allocImBuf((short)context.rectx, (short)context.recty, 32, IB_rect); + out = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rect); } return out; @@ -2041,6 +2054,75 @@ static ImBuf *seq_render_movieclip_strip( return ibuf; } + +static ImBuf *seq_render_mask_strip( + SeqRenderData context, Sequence *seq, float nr) +{ + /* TODO - add option to rasterize to alpha imbuf? */ + ImBuf *ibuf = NULL; + float *maskbuf; + int i; + + if (!seq->mask) { + return NULL; + } + + BKE_mask_evaluate(seq->mask, seq->mask->sfra + nr, TRUE); + + maskbuf = MEM_callocN(sizeof(float) * context.rectx * context.recty, __func__); + + if (seq->flag & SEQ_MAKE_FLOAT) { + /* pixels */ + float *fp_src; + float *fp_dst; + + ibuf = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rectfloat); + + BKE_mask_rasterize(seq->mask, + context.rectx, context.recty, + maskbuf, + TRUE, FALSE); + + fp_src = maskbuf; + fp_dst = ibuf->rect_float; + i = context.rectx * context.recty; + while(--i) { + fp_dst[0] = fp_dst[1] = fp_dst[2] = *fp_src; + fp_dst[3] = 1.0f; + + fp_src += 1; + fp_dst += 4; + } + } + else { + /* pixels */ + float *fp_src; + unsigned char *ub_dst; + + ibuf = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rect); + + BKE_mask_rasterize(seq->mask, + context.rectx, context.recty, + maskbuf, + TRUE, FALSE); + + fp_src = maskbuf; + ub_dst = (unsigned char *)ibuf->rect; + i = context.rectx * context.recty; + while(--i) { + ub_dst[0] = ub_dst[1] = ub_dst[2] = (unsigned char)(*fp_src * 255.0f); /* already clamped */ + ub_dst[3] = 255; + + fp_src += 1; + ub_dst += 4; + } + } + + MEM_freeN(maskbuf); + + return ibuf; +} + static ImBuf *seq_render_scene_strip( SeqRenderData context, Sequence *seq, float nr) { @@ -2126,7 +2208,8 @@ static ImBuf *seq_render_scene_strip( if (sequencer_view3d_cb && BLI_thread_is_main() && doseq_gl && (scene == context.scene || have_seq == 0) && camera) { char err_out[256] = "unknown"; - /* for old scened this can be uninitialized, should probably be added to do_versions at some point if the functionality stays */ + /* for old scened this can be uninitialized, + * should probably be added to do_versions at some point if the functionality stays */ if (context.scene->r.seq_prev_type == 0) context.scene->r.seq_prev_type = 3 /* ==OB_SOLID */; @@ -2204,8 +2287,8 @@ static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra) int is_proxy_image = FALSE; float nr = give_stripelem_index(seq, cfra); /* all effects are handled similarly with the exception of speed effect */ - int type = (seq->type & SEQ_EFFECT && seq->type != SEQ_SPEED) ? SEQ_EFFECT : seq->type; - int is_preprocessed = !ELEM3(type, SEQ_IMAGE, SEQ_MOVIE, SEQ_SCENE); + int type = (seq->type & SEQ_TYPE_EFFECT && seq->type != SEQ_TYPE_SPEED) ? SEQ_TYPE_EFFECT : seq->type; + int is_preprocessed = !ELEM3(type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SCENE); ibuf = seq_stripelem_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF); @@ -2218,13 +2301,13 @@ static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra) ibuf = copy_from_ibuf_still(context, seq, nr); /* MOVIECLIPs have their own proxy management */ - if (ibuf == NULL && seq->type != SEQ_MOVIECLIP) { + if (ibuf == NULL && seq->type != SEQ_TYPE_MOVIECLIP) { ibuf = seq_proxy_fetch(context, seq, cfra); is_proxy_image = (ibuf != NULL); } if (ibuf == NULL) switch (type) { - case SEQ_META: + case SEQ_TYPE_META: { ImBuf *meta_ibuf = NULL; @@ -2246,7 +2329,7 @@ static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra) break; } - case SEQ_SPEED: + case SEQ_TYPE_SPEED: { ImBuf *child_ibuf = NULL; @@ -2272,13 +2355,13 @@ static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra) } break; } - case SEQ_EFFECT: + case SEQ_TYPE_EFFECT: { ibuf = seq_render_effect_strip_impl( context, seq, seq->start + nr); break; } - case SEQ_IMAGE: + case SEQ_TYPE_IMAGE: { StripElem *s_elem = give_stripelem(seq, cfra); @@ -2303,7 +2386,7 @@ static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra) } break; } - case SEQ_MOVIE: + case SEQ_TYPE_MOVIE: { seq_open_anim_file(seq); @@ -2330,7 +2413,7 @@ static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra) copy_to_ibuf_still(context, seq, nr, ibuf); break; } - case SEQ_SCENE: + case SEQ_TYPE_SCENE: { // scene can be NULL after deletions ibuf = seq_render_scene_strip(context, seq, nr); @@ -2340,7 +2423,7 @@ static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra) copy_to_ibuf_still(context, seq, nr, ibuf); break; } - case SEQ_MOVIECLIP: + case SEQ_TYPE_MOVIECLIP: { ibuf = seq_render_movieclip_strip(context, seq, nr); @@ -2355,10 +2438,18 @@ static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra) copy_to_ibuf_still(context, seq, nr, ibuf); break; } + case SEQ_TYPE_MASK: + { + /* ibuf is alwats new */ + ibuf = seq_render_mask_strip(context, seq, nr); + + copy_to_ibuf_still(context, seq, nr, ibuf); + break; + } } if (ibuf == NULL) - ibuf = IMB_allocImBuf((short)context.rectx, (short)context.recty, 32, IB_rect); + ibuf = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rect); if (ibuf->x != context.rectx || ibuf->y != context.recty) use_preprocess = TRUE; @@ -2383,7 +2474,7 @@ static int seq_must_swap_input_in_blend_mode(Sequence *seq) /* bad hack, to fix crazy input ordering of * those two effects */ - if (ELEM3(seq->blend_mode, SEQ_ALPHAOVER, SEQ_ALPHAUNDER, SEQ_OVERDROP)) { + if (ELEM3(seq->blend_mode, SEQ_TYPE_ALPHAOVER, SEQ_TYPE_ALPHAUNDER, SEQ_TYPE_OVERDROP)) { swap_input = TRUE; } @@ -2473,7 +2564,7 @@ static ImBuf *seq_render_strip_stack( break; case EARLY_USE_INPUT_1: if (i == 0) { - out = IMB_allocImBuf((short)context.rectx, (short)context.recty, 32, IB_rect); + out = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rect); } break; case EARLY_DO_EFFECT: @@ -2567,7 +2658,7 @@ ImBuf *give_ibuf_seq_direct(SeqRenderData context, float cfra, Sequence *seq) /* check used when we need to change seq->blend_mode but not to effect or audio strips */ static int seq_can_blend(Sequence *seq) { - if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) { + if (ELEM4(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_META, SEQ_TYPE_SCENE, SEQ_TYPE_MOVIE)) { return 1; } else { @@ -2949,16 +3040,16 @@ void free_imbuf_seq(Scene *scene, ListBase *seqbase, int check_mem_usage, for (seq = seqbase->first; seq; seq = seq->next) { if (seq->strip) { - if (seq->type == SEQ_MOVIE && !keep_file_handles) + if (seq->type == SEQ_TYPE_MOVIE && !keep_file_handles) free_anim_seq(seq); - if (seq->type == SEQ_SPEED) { + if (seq->type == SEQ_TYPE_SPEED) { sequence_effect_speed_rebuild_map(scene, seq, 1); } } - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { free_imbuf_seq(scene, &seq->seqbase, FALSE, keep_file_handles); } - if (seq->type == SEQ_SCENE) { + if (seq->type == SEQ_TYPE_SCENE) { /* FIXME: recurs downwards, * but do recurs protection somehow! */ } @@ -2995,9 +3086,9 @@ static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *chan if (free_imbuf) { if (ibuf_change) { - if (seq->type == SEQ_MOVIE) + if (seq->type == SEQ_TYPE_MOVIE) free_anim_seq(seq); - if (seq->type == SEQ_SPEED) { + if (seq->type == SEQ_TYPE_SPEED) { sequence_effect_speed_rebuild_map(scene, seq, 1); } } @@ -3086,8 +3177,8 @@ void seq_tx_set_final_right(Sequence *seq, int val) int seq_single_check(Sequence *seq) { return ((seq->len == 1) && - (seq->type == SEQ_IMAGE || - ((seq->type & SEQ_EFFECT) && + (seq->type == SEQ_TYPE_IMAGE || + ((seq->type & SEQ_TYPE_EFFECT) && get_sequence_effect_num_inputs(seq->type) == 0))); } @@ -3110,7 +3201,7 @@ int seqbase_isolated_sel_check(ListBase *seqbase) /* test relationships */ for (seq = seqbase->first; seq; seq = seq->next) { - if ((seq->type & SEQ_EFFECT) == 0) + if ((seq->type & SEQ_TYPE_EFFECT) == 0) continue; if (seq->flag & SELECT) { @@ -3173,7 +3264,7 @@ void seq_tx_handle_xlimits(Sequence *seq, int leftflag, int rightflag) } /* sounds cannot be extended past their endpoints */ - if (seq->type == SEQ_SOUND) { + if (seq->type == SEQ_TYPE_SOUND_RAM) { seq->startstill = 0; seq->endstill = 0; } @@ -3199,7 +3290,7 @@ void seq_single_fix(Sequence *seq) int seq_tx_test(Sequence *seq) { - return (seq->type < SEQ_EFFECT) || (get_sequence_effect_num_inputs(seq->type) == 0); + return (seq->type < SEQ_TYPE_EFFECT) || (get_sequence_effect_num_inputs(seq->type) == 0); } static int seq_overlap(Sequence *seq1, Sequence *seq2) @@ -3228,7 +3319,7 @@ void seq_translate(Scene *evil_scene, Sequence *seq, int delta) seq_offset_animdata(evil_scene, seq, delta); seq->start += delta; - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { Sequence *seq_child; for (seq_child = seq->seqbase.first; seq_child; seq_child = seq_child->next) { seq_translate(evil_scene, seq_child, delta); @@ -3240,7 +3331,7 @@ void seq_translate(Scene *evil_scene, Sequence *seq, int delta) void seq_sound_init(Scene *scene, Sequence *seq) { - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { Sequence *seq_child; for (seq_child = seq->seqbase.first; seq_child; seq_child = seq_child->next) { seq_sound_init(scene, seq_child); @@ -3268,7 +3359,7 @@ Sequence *seq_foreground_frame_get(Scene *scene, int frame) if (seq->flag & SEQ_MUTE || seq->startdisp > frame || seq->enddisp <= frame) continue; /* only use elements you can see - not */ - if (ELEM5(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE, SEQ_COLOR)) { + if (ELEM5(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_META, SEQ_TYPE_SCENE, SEQ_TYPE_MOVIE, SEQ_TYPE_COLOR)) { if (seq->machine > best_machine) { best_seq = seq; best_machine = seq->machine; @@ -3394,10 +3485,10 @@ void seq_update_sound_bounds_all(Scene *scene) Sequence *seq; for (seq = ed->seqbase.first; seq; seq = seq->next) { - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { seq_update_sound_bounds_recursive(scene, seq); } - else if (ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) { + else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) { seq_update_sound_bounds(scene, seq); } } @@ -3420,7 +3511,7 @@ static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, i for (seq = seqbasep->first; seq; seq = seq->next) { seqmute = (mute || (seq->flag & SEQ_MUTE)); - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { /* if this is the current meta sequence, unmute because * all sequences above this were set to mute */ if (seq == metaseq) @@ -3428,7 +3519,7 @@ static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, i seq_update_muting_recursive(&seq->seqbase, metaseq, seqmute); } - else if (ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) { + else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) { if (seq->scene_sound) { sound_mute_scene_sound(seq->scene_sound, seqmute); } @@ -3454,10 +3545,10 @@ static void seq_update_sound_recursive(Scene *scene, ListBase *seqbasep, bSound Sequence *seq; for (seq = seqbasep->first; seq; seq = seq->next) { - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { seq_update_sound_recursive(scene, &seq->seqbase, sound); } - else if (seq->type == SEQ_SOUND) { + else if (seq->type == SEQ_TYPE_SOUND_RAM) { if (seq->scene_sound && sound == seq->sound) { sound_update_scene_sound(seq->scene_sound, sound); } @@ -3521,18 +3612,18 @@ int seq_swap(Sequence *seq_a, Sequence *seq_b, const char **error_str) /* type checking, could be more advanced but disalow sound vs non-sound copy */ if (seq_a->type != seq_b->type) { - if (seq_a->type == SEQ_SOUND || seq_b->type == SEQ_SOUND) { + if (seq_a->type == SEQ_TYPE_SOUND_RAM || seq_b->type == SEQ_TYPE_SOUND_RAM) { *error_str = "Strips were not compatible"; return 0; } /* disallow effects to swap with non-effects strips */ - if ((seq_a->type & SEQ_EFFECT) != (seq_b->type & SEQ_EFFECT)) { + if ((seq_a->type & SEQ_TYPE_EFFECT) != (seq_b->type & SEQ_TYPE_EFFECT)) { *error_str = "Strips were not compatible"; return 0; } - if ((seq_a->type & SEQ_EFFECT) && (seq_b->type & SEQ_EFFECT)) { + if ((seq_a->type & SEQ_TYPE_EFFECT) && (seq_b->type & SEQ_TYPE_EFFECT)) { if (get_sequence_effect_num_inputs(seq_a->type) != get_sequence_effect_num_inputs(seq_b->type)) { *error_str = "Strips must have the same number of inputs"; return 0; @@ -3769,8 +3860,8 @@ Sequence *sequencer_add_image_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo Strip *strip; seq = alloc_sequence(seqbasep, seq_load->start_frame, seq_load->channel); - seq->type = SEQ_IMAGE; - seq->blend_mode = SEQ_CROSS; /* so alpha adjustment fade to the strip below */ + seq->type = SEQ_TYPE_IMAGE; + seq->blend_mode = SEQ_TYPE_CROSS; /* so alpha adjustment fade to the strip below */ /* basic defaults */ seq->strip = strip = MEM_callocN(sizeof(Strip), "strip"); @@ -3818,7 +3909,7 @@ Sequence *sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo seq = alloc_sequence(seqbasep, seq_load->start_frame, seq_load->channel); - seq->type = SEQ_SOUND; + seq->type = SEQ_TYPE_SOUND_RAM; seq->sound = sound; BLI_strncpy(seq->name + 2, "Sound", SEQ_NAME_MAXSTR - 2); seqbase_unique_name_recursive(&scene->ed->seqbase, seq); @@ -3874,8 +3965,8 @@ Sequence *sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo return NULL; seq = alloc_sequence(seqbasep, seq_load->start_frame, seq_load->channel); - seq->type = SEQ_MOVIE; - seq->blend_mode = SEQ_CROSS; /* so alpha adjustment fade to the strip below */ + seq->type = SEQ_TYPE_MOVIE; + seq->blend_mode = SEQ_TYPE_CROSS; /* so alpha adjustment fade to the strip below */ seq->anim = an; seq->anim_preseek = IMB_anim_get_preseek(an); @@ -3942,24 +4033,24 @@ static Sequence *seq_dupli(struct Scene *scene, struct Scene *scene_to, Sequence seqn->strip->color_balance = MEM_dupallocN(seq->strip->color_balance); } - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { seqn->strip->stripdata = NULL; seqn->seqbase.first = seqn->seqbase.last = NULL; /* WATCH OUT!!! - This metastrip is not recursively duplicated here - do this after!!! */ /* - seq_dupli_recursive(&seq->seqbase,&seqn->seqbase);*/ } - else if (seq->type == SEQ_SCENE) { + else if (seq->type == SEQ_TYPE_SCENE) { seqn->strip->stripdata = NULL; if (seq->scene_sound) seqn->scene_sound = sound_scene_add_scene_sound_defaults(sce_audio, seqn); } - else if (seq->type == SEQ_MOVIE) { + else if (seq->type == SEQ_TYPE_MOVIE) { seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata); seqn->anim = NULL; } - else if (seq->type == SEQ_SOUND) { + else if (seq->type == SEQ_TYPE_SOUND_RAM) { seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata); if (seq->scene_sound) @@ -3967,16 +4058,16 @@ static Sequence *seq_dupli(struct Scene *scene, struct Scene *scene_to, Sequence seqn->sound->id.us++; } - else if (seq->type == SEQ_IMAGE) { + else if (seq->type == SEQ_TYPE_IMAGE) { seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata); } - else if (seq->type >= SEQ_EFFECT) { + else if (seq->type >= SEQ_TYPE_EFFECT) { if (seq->seq1 && seq->seq1->tmp) seqn->seq1 = seq->seq1->tmp; if (seq->seq2 && seq->seq2->tmp) seqn->seq2 = seq->seq2->tmp; if (seq->seq3 && seq->seq3->tmp) seqn->seq3 = seq->seq3->tmp; - if (seq->type & SEQ_EFFECT) { + if (seq->type & SEQ_TYPE_EFFECT) { struct SeqEffectHandle sh; sh = get_sequence_effect(seq); if (sh.copy) @@ -4004,7 +4095,7 @@ static Sequence *seq_dupli(struct Scene *scene, struct Scene *scene_to, Sequence Sequence *seq_dupli_recursive(struct Scene *scene, struct Scene *scene_to, Sequence *seq, int dupe_flag) { Sequence *seqn = seq_dupli(scene, scene_to, seq, dupe_flag); - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { Sequence *s; for (s = seq->seqbase.first; s; s = s->next) { Sequence *n = seq_dupli_recursive(scene, scene_to, s, dupe_flag); @@ -4033,7 +4124,7 @@ void seqbase_dupli_recursive(Scene *scene, Scene *scene_to, ListBase *nseqbase, } BLI_addtail(nseqbase, seqn); - if (seq->type == SEQ_META) + if (seq->type == SEQ_TYPE_META) seqbase_dupli_recursive(scene, scene_to, &seqn->seqbase, &seq->seqbase, dupe_flag); if (dupe_flag & SEQ_DUPE_CONTEXT) { diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 7a5465edf02..ebc31517524 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -150,6 +150,7 @@ static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs) struct WTURBULENCE *smoke_turbulence_init(int *UNUSED(res), int UNUSED(amplify), int UNUSED(noisetype)) { return NULL; } struct FLUID_3D *smoke_init(int *UNUSED(res), float *UNUSED(p0)) { return NULL; } void smoke_free(struct FLUID_3D *UNUSED(fluid)) {} +float *smoke_get_density(struct FLUID_3D *UNUSED(fluid)) { return NULL; } void smoke_turbulence_free(struct WTURBULENCE *UNUSED(wt)) {} void smoke_initWaveletBlenderRNA(struct WTURBULENCE *UNUSED(wt), float *UNUSED(strength)) {} void smoke_initBlenderRNA(struct FLUID_3D *UNUSED(fluid), float *UNUSED(alpha), float *UNUSED(beta), float *UNUSED(dt_factor), float *UNUSED(vorticity), int *UNUSED(border_colli)) {} diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index b0745ebf1c8..bbb70bb77ff 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -20,6 +20,7 @@ * * Contributor(s): Blender Foundation, * Sergey Sharybin + * Keir Mierle * * ***** END GPL LICENSE BLOCK ***** */ @@ -59,6 +60,8 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" +#include "raskter.h" + #ifdef WITH_LIBMV # include "libmv-capi.h" #else @@ -73,6 +76,141 @@ static struct { ListBase tracks; } tracking_clipboard; +/*********************** space transformation functions *************************/ + +/* Three coordinate frames: Frame, Search, and Marker + * Two units: Pixels, Unified + * Notation: {coordinate frame}_{unit}; for example, "search_pixel" are search + * window relative coordinates in pixels, and "frame_unified" are unified 0..1 + * coordinates relative to the entire frame. + */ +static void unified_to_pixel(int frame_width, int frame_height, + const float unified_coords[2], float pixel_coords[2]) +{ + pixel_coords[0] = unified_coords[0] * frame_width; + pixel_coords[1] = unified_coords[1] * frame_height; +} + +static void marker_to_frame_unified(const MovieTrackingMarker *marker, const float marker_unified_coords[2], + float frame_unified_coords[2]) +{ + frame_unified_coords[0] = marker_unified_coords[0] + marker->pos[0]; + frame_unified_coords[1] = marker_unified_coords[1] + marker->pos[1]; +} + +static void marker_unified_to_frame_pixel_coordinates(int frame_width, int frame_height, + const MovieTrackingMarker *marker, + const float marker_unified_coords[2], float frame_pixel_coords[2]) +{ + marker_to_frame_unified(marker, marker_unified_coords, frame_pixel_coords); + unified_to_pixel(frame_width, frame_height, frame_pixel_coords, frame_pixel_coords); +} + +static void get_search_origin_frame_pixel(int frame_width, int frame_height, + const MovieTrackingMarker *marker, float frame_pixel[2]) +{ + /* Get the lower left coordinate of the search window and snap to pixel coordinates */ + marker_unified_to_frame_pixel_coordinates(frame_width, frame_height, marker, marker->search_min, frame_pixel); + frame_pixel[0] = (int)frame_pixel[0]; + frame_pixel[1] = (int)frame_pixel[1]; +} + +#ifdef WITH_LIBMV +static void pixel_to_unified(int frame_width, int frame_height, const float pixel_coords[2], float unified_coords[2]) +{ + unified_coords[0] = pixel_coords[0] / frame_width; + unified_coords[1] = pixel_coords[1] / frame_height; +} + +static void marker_unified_to_search_pixel(int frame_width, int frame_height, + const MovieTrackingMarker *marker, + const float marker_unified[2], float search_pixel[2]) +{ + float frame_pixel[2]; + float search_origin_frame_pixel[2]; + + marker_unified_to_frame_pixel_coordinates(frame_width, frame_height, marker, marker_unified, frame_pixel); + get_search_origin_frame_pixel(frame_width, frame_height, marker, search_origin_frame_pixel); + sub_v2_v2v2(search_pixel, frame_pixel, search_origin_frame_pixel); +} + +static void search_pixel_to_marker_unified(int frame_width, int frame_height, + const MovieTrackingMarker *marker, + const float search_pixel[2], float marker_unified[2]) +{ + float frame_unified[2]; + float search_origin_frame_pixel[2]; + + get_search_origin_frame_pixel(frame_width, frame_height, marker, search_origin_frame_pixel); + add_v2_v2v2(frame_unified, search_pixel, search_origin_frame_pixel); + pixel_to_unified(frame_width, frame_height, frame_unified, frame_unified); + + /* marker pos is in frame unified */ + sub_v2_v2v2(marker_unified, frame_unified, marker->pos); +} + +/* Each marker has 5 coordinates associated with it that get warped with + * tracking: the four corners ("pattern_corners"), and the cernter ("pos"). + * This function puts those 5 points into the appropriate frame for tracking + * (the "search" coordinate frame). + */ +static void get_marker_coords_for_tracking(int frame_width, int frame_height, + const MovieTrackingMarker *marker, + double search_pixel_x[5], double search_pixel_y[5]) +{ + int i; + float unified_coords[2]; + float pixel_coords[2]; + + /* Convert the corners into search space coordinates. */ + for (i = 0; i < 4; i++) { + marker_unified_to_search_pixel(frame_width, frame_height, marker, marker->pattern_corners[i], pixel_coords); + search_pixel_x[i] = pixel_coords[0]; + search_pixel_y[i] = pixel_coords[1]; + } + /* Convert the center position (aka "pos"); this is the origin */ + unified_coords[0] = 0.0; + unified_coords[1] = 0.0; + marker_unified_to_search_pixel(frame_width, frame_height, marker, unified_coords, pixel_coords); + + search_pixel_x[4] = pixel_coords[0]; + search_pixel_y[4] = pixel_coords[1]; +} + +/* Inverse of above. */ +static void set_marker_coords_from_tracking(int frame_width, int frame_height, MovieTrackingMarker *marker, + const double search_pixel_x[5], const double search_pixel_y[5]) +{ + int i; + float marker_unified[2]; + float search_pixel[2]; + + /* Convert the corners into search space coordinates. */ + for (i = 0; i < 4; i++) { + search_pixel[0] = search_pixel_x[i]; + search_pixel[1] = search_pixel_y[i]; + search_pixel_to_marker_unified(frame_width, frame_height, marker, search_pixel, marker->pattern_corners[i]); + } + + /* Convert the center position (aka "pos"); this is the origin */ + search_pixel[0] = search_pixel_x[4]; + search_pixel[1] = search_pixel_y[4]; + search_pixel_to_marker_unified(frame_width, frame_height, marker, search_pixel, marker_unified); + + /* If the tracker tracked nothing, then "marker_unified" would be zero. + * Otherwise, the entire patch shifted, and that delta should be applied to + * all the coordinates. + */ + for (i = 0; i < 4; i++) { + marker->pattern_corners[i][0] -= marker_unified[0]; + marker->pattern_corners[i][1] -= marker_unified[1]; + } + + marker->pos[0] += marker_unified[0]; + marker->pos[1] += marker_unified[1]; +} +#endif + /*********************** common functions *************************/ void BKE_tracking_init_settings(MovieTracking *tracking) @@ -81,11 +219,10 @@ void BKE_tracking_init_settings(MovieTracking *tracking) tracking->camera.pixel_aspect = 1.0f; tracking->camera.units = CAMERA_UNITS_MM; - tracking->settings.default_tracker = TRACKER_HYBRID; + tracking->settings.default_motion_model = TRACK_MOTION_MODEL_TRANSLATION; tracking->settings.default_minimum_correlation = 0.75; tracking->settings.default_pattern_size = 11; tracking->settings.default_search_size = 61; - tracking->settings.default_pyramid_levels = 2; tracking->settings.keyframe1 = 1; tracking->settings.keyframe2 = 30; tracking->settings.dist = 1; @@ -99,105 +236,68 @@ void BKE_tracking_init_settings(MovieTracking *tracking) BKE_tracking_new_object(tracking, "Camera"); } -void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event) +void BKE_tracking_clamp_marker(MovieTrackingMarker *marker, int event) { int a; - float pat_min[2]; - float pat_max[2]; - float max_pyramid_level_factor = 1.0; - - if (track->tracker == TRACKER_KLT) { - max_pyramid_level_factor = 1 << (track->pyramid_levels - 1); - } - - /* sort */ - for (a = 0; a < 2; a++) { - if (track->pat_min[a] > track->pat_max[a]) - SWAP(float, track->pat_min[a], track->pat_max[a]); + float pat_min[2], pat_max[2]; - if (track->search_min[a] > track->search_max[a]) - SWAP(float, track->search_min[a], track->search_max[a]); - } - - /* compute the effective pattern size, which differs from the fine resolution - * pattern size for the pyramid KLT tracker */ - for (a = 0; a < 2; a++) { - pat_min[a] = max_pyramid_level_factor * track->pat_min[a]; - pat_max[a] = max_pyramid_level_factor * track->pat_max[a]; - } + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); if (event == CLAMP_PAT_DIM) { for (a = 0; a < 2; a++) { /* search shouldn't be resized smaller than pattern */ - track->search_min[a] = MIN2(pat_min[a], track->search_min[a]); - track->search_max[a] = MAX2(pat_max[a], track->search_max[a]); + marker->search_min[a] = MIN2(pat_min[a], marker->search_min[a]); + marker->search_max[a] = MAX2(pat_max[a], marker->search_max[a]); } } else if (event == CLAMP_PAT_POS) { float dim[2]; - sub_v2_v2v2(dim, track->pat_max, track->pat_min); + sub_v2_v2v2(dim, pat_max, pat_min); for (a = 0; a < 2; a++) { + int b; /* pattern shouldn't be moved outside of search */ - if (pat_min[a] < track->search_min[a]) { - track->pat_min[a] = track->search_min[a] - (pat_min[a] - track->pat_min[a]); - track->pat_max[a] = track->pat_min[a] + dim[a]; + if (pat_min[a] < marker->search_min[a]) { + for (b = 0; b < 4; b++) + marker->pattern_corners[b][a] += marker->search_min[a] - pat_min[a]; } - if (track->pat_max[a] > track->search_max[a]) { - track->pat_max[a] = track->search_max[a] - (pat_max[a] - track->pat_max[a]); - track->pat_min[a] = track->pat_max[a] - dim[a]; + if (pat_max[a] > marker->search_max[a]) { + for (b = 0; b < 4; b++) + marker->pattern_corners[b][a] -= pat_max[a] - marker->search_max[a]; } } } else if (event == CLAMP_SEARCH_DIM) { for (a = 0; a < 2; a++) { /* search shouldn't be resized smaller than pattern */ - track->search_min[a] = MIN2(pat_min[a], track->search_min[a]); - track->search_max[a] = MAX2(pat_max[a], track->search_max[a]); + marker->search_min[a] = MIN2(pat_min[a], marker->search_min[a]); + marker->search_max[a] = MAX2(pat_max[a], marker->search_max[a]); } } else if (event == CLAMP_SEARCH_POS) { float dim[2]; - sub_v2_v2v2(dim, track->search_max, track->search_min); + sub_v2_v2v2(dim, marker->search_max, marker->search_min); for (a = 0; a < 2; a++) { /* search shouldn't be moved inside pattern */ - if (track->search_min[a] > pat_min[a]) { - track->search_min[a] = pat_min[a]; - track->search_max[a] = track->search_min[a] + dim[a]; + if (marker->search_min[a] > pat_min[a]) { + marker->search_min[a] = pat_min[a]; + marker->search_max[a] = marker->search_min[a] + dim[a]; } - if (track->search_max[a] < pat_max[a]) { - track->search_max[a] = pat_max[a]; - track->search_min[a] = track->search_max[a] - dim[a]; + if (marker->search_max[a] < pat_max[a]) { + marker->search_max[a] = pat_max[a]; + marker->search_min[a] = marker->search_max[a] - dim[a]; } } } - else if (event == CLAMP_PYRAMID_LEVELS || (event == CLAMP_SEARCH_DIM && track->tracker == TRACKER_KLT)) { - float dim[2]; - sub_v2_v2v2(dim, track->pat_max, track->pat_min); - { - float search_ratio = 2.3f * max_pyramid_level_factor; - - /* resize the search area to something sensible based - * on the number of pyramid levels */ - for (a = 0; a < 2; a++) { - track->search_min[a] = search_ratio * track->pat_min[a]; - track->search_max[a] = search_ratio * track->pat_max[a]; - } - } - } - - /* marker's center should be in center of pattern */ - if (event == CLAMP_PAT_DIM || event == CLAMP_PAT_POS) { + else if (event == CLAMP_SEARCH_DIM) { float dim[2]; - - sub_v2_v2v2(dim, track->pat_max, track->pat_min); - + sub_v2_v2v2(dim, pat_max, pat_min); for (a = 0; a < 2; a++) { - track->pat_min[a] = -dim[a] / 2.0f; - track->pat_max[a] = dim[a] / 2.0f; + marker->search_min[a] = pat_min[a]; + marker->search_max[a] = pat_max[a]; } } } @@ -245,29 +345,32 @@ MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tr track = MEM_callocN(sizeof(MovieTrackingTrack), "add_marker_exec track"); strcpy(track->name, "Track"); - track->tracker = settings->default_tracker; - track->pyramid_levels = settings->default_pyramid_levels; + track->motion_model = settings->default_motion_model; track->minimum_correlation = settings->default_minimum_correlation; track->margin = settings->default_margin; track->pattern_match = settings->default_pattern_match; track->frames_limit = settings->default_frames_limit; track->flag = settings->default_flag; + track->algorithm_flag = settings->default_algorithm_flag; memset(&marker, 0, sizeof(marker)); marker.pos[0] = x; marker.pos[1] = y; marker.framenr = framenr; - copy_v2_v2(track->pat_max, pat); - negate_v2_v2(track->pat_min, pat); + marker.pattern_corners[0][0] = -pat[0]; + marker.pattern_corners[0][1] = -pat[1]; - copy_v2_v2(track->search_max, search); - negate_v2_v2(track->search_min, search); + marker.pattern_corners[1][0] = pat[0]; + marker.pattern_corners[1][1] = -pat[1]; - BKE_tracking_insert_marker(track, &marker); + negate_v2_v2(marker.pattern_corners[2], marker.pattern_corners[0]); + negate_v2_v2(marker.pattern_corners[3], marker.pattern_corners[1]); - if (track->tracker == TRACKER_KLT) - BKE_tracking_clamp_track(track, CLAMP_PYRAMID_LEVELS); + copy_v2_v2(marker.search_max, search); + negate_v2_v2(marker.search_min, search); + + BKE_tracking_insert_marker(track, &marker); BLI_addtail(tracksbase, track); BKE_track_unique_name(tracksbase, track); @@ -337,6 +440,16 @@ void BKE_tracking_delete_marker(MovieTrackingTrack *track, int framenr) } } +void BKE_tracking_marker_pattern_minmax(MovieTrackingMarker *marker, float min[2], float max[2]) +{ + INIT_MINMAX2(min, max); + + DO_MINMAX2(marker->pattern_corners[0], min, max); + DO_MINMAX2(marker->pattern_corners[1], min, max); + DO_MINMAX2(marker->pattern_corners[2], min, max); + DO_MINMAX2(marker->pattern_corners[3], min, max); +} + MovieTrackingMarker *BKE_tracking_get_marker(MovieTrackingTrack *track, int framenr) { int a = track->markersnr - 1; @@ -527,7 +640,8 @@ void BKE_tracking_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack if ((dst_track->markers[b].flag & MARKER_DISABLED) == 0) { /* both tracks are enabled on this frame, so find the whole segment * on which tracks are intersecting and blend tracks using linear - * interpolation to prevent jumps */ + * interpolation to prevent jumps + */ MovieTrackingMarker *marker_a, *marker_b; int start_a = a, start_b = b, len = 0, frame = src_track->markers[a].framenr; @@ -827,7 +941,8 @@ static void tracks_map_merge(TracksMap *map, MovieTracking *tracking) /* duplicate currently operating tracks to temporary list. * this is needed to keep names in unique state and it's faster to change names - * of currently operating tracks (if needed) */ + * of currently operating tracks (if needed) + */ for (a = 0; a < map->num_tracks; a++) { int replace_sel = 0, replace_rot = 0; MovieTrackingTrack *new_track, *old; @@ -929,10 +1044,14 @@ static void tracks_map_free(TracksMap *map, void (*customdata_free) (void *custo typedef struct TrackContext { #ifdef WITH_LIBMV - float keyframed_pos[2]; + /* the reference marker and cutout search area */ + MovieTrackingMarker marker; - struct libmv_RegionTracker *region_tracker; - float *patch; /* keyframed patch */ + /* keyframed patch. This is the search area */ + float *search_area; + int search_area_height; + int search_area_width; + int framenr; #else int pad; #endif @@ -972,7 +1091,8 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u track = tracksbase->first; while (track) { if (TRACK_SELECTED(track) && (track->flag & (TRACK_LOCKED | TRACK_HIDDEN)) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, user->framenr); + int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr); + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); if ((marker->flag & MARKER_DISABLED) == 0) num_tracks++; @@ -993,53 +1113,12 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u track = tracksbase->first; while (track) { if (TRACK_SELECTED(track) && (track->flag & (TRACK_HIDDEN | TRACK_LOCKED)) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, user->framenr); + int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr); + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); if ((marker->flag & MARKER_DISABLED) == 0) { TrackContext track_context; - memset(&track_context, 0, sizeof(TrackContext)); - -#ifdef WITH_LIBMV - { - float patx = (int)((track->pat_max[0] - track->pat_min[0]) * width), - paty = (int)((track->pat_max[1] - track->pat_min[1]) * height); - - float search_size_x = (track->search_max[0] - track->search_min[0]) * width; - float search_size_y = (track->search_max[1] - track->search_min[1]) * height; - float pattern_size_x = (track->pat_max[0] - track->pat_min[0]) * width; - float pattern_size_y = (track->pat_max[1] - track->pat_min[1]) * height; - int wndx = (int)patx / 2, wndy = (int)paty / 2; - int half_wnd = MAX2(wndx, wndy); - - /* compute the maximum pyramid size */ - float search_to_pattern_ratio = MIN2(search_size_x, search_size_y) - / MAX2(pattern_size_x, pattern_size_y); - float log2_search_to_pattern_ratio = log(floor(search_to_pattern_ratio)) / M_LN2; - int max_pyramid_levels = floor(log2_search_to_pattern_ratio + 1); - - /* try to accommodate the user's choice of pyramid level in a way - * that doesn't cause the coarsest pyramid pattern to be larger - * than the search size */ - int level = MIN2(track->pyramid_levels, max_pyramid_levels); - - struct libmv_RegionTracker *region_tracker; - - if (track->tracker == TRACKER_KLT) { - region_tracker = libmv_pyramidRegionTrackerNew(100, level, half_wnd, - track->minimum_correlation); - } - else if (track->tracker == TRACKER_HYBRID) { - region_tracker = libmv_hybridRegionTrackerNew(100, half_wnd, track->minimum_correlation); - } - else if (track->tracker == TRACKER_SAD) { - region_tracker = libmv_bruteRegionTrackerNew(MAX2(wndx, wndy), track->minimum_correlation); - } - - track_context.region_tracker = region_tracker; - } -#endif - tracks_map_insert(context->tracks_map, track, &track_context); } } @@ -1057,7 +1136,8 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u * would be used for images * - MCLIP_USE_PROXY_CUSTOM_DIR is needed because proxy/timecode files might * be stored in a different location - * ignore all the rest possible flags for now */ + * ignore all the rest possible flags for now + */ context->clip_flag = clip->flag & MCLIP_TIMECODE_FLAGS; context->user = *user; @@ -1075,11 +1155,8 @@ static void track_context_free(void *customdata) TrackContext *track_context = (TrackContext *)customdata; #if WITH_LIBMV - if (track_context->region_tracker) - libmv_regionTrackerDestroy(track_context->region_tracker); - - if (track_context->patch) - MEM_freeN(track_context->patch); + if (track_context->search_area) + MEM_freeN(track_context->search_area); #else (void) track_context; @@ -1098,7 +1175,8 @@ void BKE_tracking_context_free(MovieTrackingContext *context) /* zap channels from the imbuf that are disabled by the user. this can lead to * better tracks sometimes. however, instead of simply zeroing the channels - * out, do a partial grayscale conversion so the display is better. */ + * out, do a partial grayscale conversion so the display is better. + */ void BKE_tracking_disable_imbuf_channels(ImBuf *ibuf, int disable_red, int disable_green, int disable_blue, int grayscale) { @@ -1109,7 +1187,8 @@ void BKE_tracking_disable_imbuf_channels(ImBuf *ibuf, int disable_red, int disab return; /* If only some components are selected, it's important to rescale the result - * appropriately so that e.g. if only blue is selected, it's not zeroed out. */ + * appropriately so that e.g. if only blue is selected, it's not zeroed out. + */ scale = (disable_red ? 0.0f : 0.2126f) + (disable_green ? 0.0f : 0.7152f) + (disable_blue ? 0.0f : 0.0722f); @@ -1165,116 +1244,271 @@ static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int g track->flag & TRACK_DISABLE_GREEN, track->flag & TRACK_DISABLE_BLUE, grayscale); } -static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, - float min[2], float max[2], int margin, int anchored, float pos[2], int origin[2]) +ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, + ImBuf *search_ibuf, MovieTrackingMarker *marker, + int num_samples_x, int num_samples_y, float pos[2]) { - ImBuf *tmpibuf; - int x, y; - int x1, y1, w, h; - float mpos[2]; +#ifdef WITH_LIBMV + ImBuf *pattern_ibuf; + double src_pixel_x[5], src_pixel_y[5]; + double warped_position_x, warped_position_y; - copy_v2_v2(mpos, marker->pos); - if (anchored) - add_v2_v2(mpos, track->offset); + pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat); + pattern_ibuf->profile = IB_PROFILE_LINEAR_RGB; - if (pos) - zero_v2(pos); + if (!search_ibuf->rect_float) { + IMB_float_from_rect(search_ibuf); + } - x = mpos[0]*ibuf->x; - y = mpos[1]*ibuf->y; + get_marker_coords_for_tracking(frame_width, frame_height, marker, src_pixel_x, src_pixel_y); - w = (max[0] - min[0]) * ibuf->x; - h = (max[1] - min[1]) * ibuf->y; + libmv_samplePlanarPatch(search_ibuf->rect_float, search_ibuf->x, search_ibuf->y, 4, + src_pixel_x, src_pixel_y, num_samples_x, + num_samples_y, pattern_ibuf->rect_float, + &warped_position_x, &warped_position_y); - /* dimensions should be odd */ - w = w | 1; - h = h | 1; + if (pos) { + pos[0] = warped_position_x; + pos[1] = warped_position_y; + } - x1 = x - (int)(w * (-min[0] / (max[0] - min[0]))); - y1 = y - (int)(h * (-min[1] / (max[1] - min[1]))); + return pattern_ibuf; +#else + ImBuf *pattern_ibuf; - if (ibuf->rect_float) - tmpibuf = IMB_allocImBuf(w + margin * 2, h + margin * 2, 32, IB_rectfloat); - else - tmpibuf = IMB_allocImBuf(w + margin * 2, h + margin * 2, 32, IB_rect); + /* real sampling requires libmv, but areas are supposing pattern would be + * sampled if search area does exists, so we'll need to create empty + * pattern area here to prevent adding NULL-checks all over just to deal + * with situation when lubmv is disabled + */ + + (void) frame_width; + (void) frame_height; + (void) search_ibuf; + (void) marker; + + pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat); + + pos[0] = num_samples_x / 2.0f; + pos[1] = num_samples_y / 2.0f; + + return pattern_ibuf; +#endif +} + +ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, + int anchored, int disable_channels) +{ + ImBuf *pattern_ibuf, *search_ibuf; + float pat_min[2], pat_max[2]; + int num_samples_x, num_samples_y; - tmpibuf->profile = ibuf->profile; + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); - IMB_rectcpy(tmpibuf, ibuf, 0, 0, x1 - margin, y1 - margin, w + margin * 2, h + margin * 2); + num_samples_x = (pat_max[0] - pat_min[0]) * ibuf->x; + num_samples_y = (pat_max[1] - pat_min[1]) * ibuf->y; - if (pos != NULL) { - pos[0] = mpos[0] * ibuf->x - x1 + margin; - pos[1] = mpos[1] * ibuf->y - y1 + margin; + search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, anchored, disable_channels); + + pattern_ibuf = BKE_tracking_sample_pattern_imbuf(ibuf->x, ibuf->y, search_ibuf, marker, + num_samples_x, num_samples_y, NULL); + + IMB_freeImBuf(search_ibuf); + + return pattern_ibuf; +} + +ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, + int anchored, int disable_channels) +{ + ImBuf *searchibuf; + int x, y, w, h; + float search_origin[2]; + + get_search_origin_frame_pixel(ibuf->x, ibuf->y, marker, search_origin); + + x = search_origin[0]; + y = search_origin[1]; + + if (anchored) { + x += track->offset[0] * ibuf->x; + y += track->offset[1] * ibuf->y; } - if (origin != NULL) { - origin[0] = x1 - margin; - origin[1] = y1 - margin; + w = (marker->search_max[0] - marker->search_min[0]) * ibuf->x; + h = (marker->search_max[1] - marker->search_min[1]) * ibuf->y; + + searchibuf = IMB_allocImBuf(w, h, 32, ibuf->rect_float ? IB_rectfloat : IB_rect); + searchibuf->profile = ibuf->profile; + + IMB_rectcpy(searchibuf, ibuf, 0, 0, x, y, w, h); + + if (disable_channels) { + if ((track->flag & TRACK_PREVIEW_GRAYSCALE) || + (track->flag & TRACK_DISABLE_RED) || + (track->flag & TRACK_DISABLE_GREEN) || + (track->flag & TRACK_DISABLE_BLUE)) + { + disable_imbuf_channels(searchibuf, track, TRUE); + } } - if ((track->flag & TRACK_PREVIEW_GRAYSCALE) || - (track->flag & TRACK_DISABLE_RED) || - (track->flag & TRACK_DISABLE_GREEN) || - (track->flag & TRACK_DISABLE_BLUE)) - { - disable_imbuf_channels(tmpibuf, track, TRUE /* grayscale */); + return searchibuf; +} + +static bGPDlayer *track_mask_gpencil_layer_get(MovieTrackingTrack *track) +{ + bGPDlayer *layer; + + if (!track->gpd) + return NULL; + + layer = track->gpd->layers.first; + + while (layer) { + if (layer->flag & GP_LAYER_ACTIVE) + return layer; + + layer = layer->next; } - return tmpibuf; + return NULL; } -ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, - int margin, int anchored, float pos[2], int origin[2]) +static void track_mask_gpencil_layer_rasterize(MovieTracking *tracking, MovieTrackingMarker *marker, + bGPDlayer *layer, ImBuf *ibuf, int width, int height) { - return get_area_imbuf(ibuf, track, marker, track->pat_min, track->pat_max, margin, anchored, pos, origin); + bGPDframe *frame = layer->frames.first; + float *mask; + int x, y; + float aspy = 1.0f / tracking->camera.pixel_aspect; + + mask = MEM_callocN(ibuf->x * ibuf->y * sizeof(float), "track mask"); + + while (frame) { + bGPDstroke *stroke = frame->strokes.first; + + while (stroke) { + bGPDspoint *stroke_points = stroke->points; + float *mask_points, *fp; + int i; + + if (stroke->flag & GP_STROKE_2DSPACE) { + fp = mask_points = MEM_callocN(2 * stroke->totpoints * sizeof(float), + "track mask rasterization points"); + + for (i = 0; i < stroke->totpoints; i++, fp += 2) { + fp[0] = stroke_points[i].x * width / ibuf->x - marker->search_min[0]; + fp[1] = stroke_points[i].y * height * aspy / ibuf->x - marker->search_min[1]; + } + + PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, ibuf->x, ibuf->y); + + MEM_freeN(mask_points); + } + + stroke = stroke->next; + } + + frame = frame->next; + } + + for (y = 0; y < ibuf->y; y++) { + for (x = 0; x < ibuf->x; x++) { + float *pixel = &ibuf->rect_float[4 * (y * ibuf->x + x)]; + float val = mask[y * ibuf->x + x]; + + pixel[0] = val; + pixel[1] = val; + pixel[2] = val; + pixel[3] = 1.0f; + } + } + + MEM_freeN(mask); + + IMB_rect_from_float(ibuf); } -ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, - int margin, int anchored, float pos[2], int origin[2]) +ImBuf *BKE_tracking_track_mask_get(MovieTracking *tracking, MovieTrackingTrack *track, MovieTrackingMarker *marker, + int width, int height) { - return get_area_imbuf(ibuf, track, marker, track->search_min, track->search_max, margin, anchored, pos, origin); + ImBuf *ibuf; + bGPDlayer *layer = track_mask_gpencil_layer_get(track); + int mask_width, mask_height; + + mask_width = (marker->search_max[0] - marker->search_min[0]) * width; + mask_height = (marker->search_max[1] - marker->search_min[1]) * height; + + ibuf = IMB_allocImBuf(mask_width, mask_height, 32, IB_rect | IB_rectfloat); + + if (layer) { + track_mask_gpencil_layer_rasterize(tracking, marker, layer, ibuf, width, height); + } + else { + float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + IMB_rectfill(ibuf, white); + } + + return ibuf; } #ifdef WITH_LIBMV -static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, - int *width_r, int *height_r, float pos[2], int origin[2]) + +/* Convert from float and byte RGBA to grayscale. Supports different coefficients for RGB. */ +static void float_rgba_to_gray(const float *rgba, float *gray, int num_pixels, + float weight_red, float weight_green, float weight_blue) { - ImBuf *tmpibuf; - float *pixels, *fp; - int x, y, width, height; + int i; + + for (i = 0; i < num_pixels; i++) { + const float *pixel = rgba + 4 * i; + + gray[i] = weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2]; + } +} - width = (track->search_max[0] - track->search_min[0]) * ibuf->x; - height = (track->search_max[1] - track->search_min[1]) * ibuf->y; +static void uint8_rgba_to_float_gray(const unsigned char *rgba, float *gray, int num_pixels, + float weight_red, float weight_green, float weight_blue) +{ + int i; - tmpibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, 0, 0, pos, origin); - disable_imbuf_channels(tmpibuf, track, FALSE /* don't grayscale */); + for (i = 0; i < num_pixels; i++) { + const unsigned char *pixel = rgba + i * 4; - *width_r = width; - *height_r = height; + *gray++ = (weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2]) / 255.0f; + } +} - fp = pixels = MEM_callocN(width * height * sizeof(float), "tracking floatBuf"); - for (y = 0; y < (int)height; y++) { - for (x = 0; x < (int)width; x++) { - int pixel = tmpibuf->x * y + x; +static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, + int *width_r, int *height_r) +{ + ImBuf *searchibuf; + float *gray_pixels; + int width, height; - if (tmpibuf->rect_float) { - float *rrgbf = tmpibuf->rect_float + pixel * 4; + searchibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, FALSE, TRUE); - *fp = 0.2126 * rrgbf[0] + 0.7152 * rrgbf[1] + 0.0722 * rrgbf[2]; - } - else { - unsigned char *rrgb = (unsigned char*)tmpibuf->rect + pixel * 4; + width = searchibuf->x; + height = searchibuf->y; - *fp = (0.2126 * rrgb[0] + 0.7152 * rrgb[1] + 0.0722 * rrgb[2]) / 255.0f; - } + *width_r = searchibuf->x; + *height_r = searchibuf->y; - fp++; - } + gray_pixels = MEM_callocN(width * height * sizeof(float), "tracking floatBuf"); + + if (searchibuf->rect_float) { + float_rgba_to_gray(searchibuf->rect_float, gray_pixels, width * height, + 0.2126f, 0.7152f, 0.0722f); + } + else { + uint8_rgba_to_float_gray((unsigned char *)searchibuf->rect, gray_pixels, width * height, + 0.2126f, 0.7152f, 0.0722f); } - IMB_freeImBuf(tmpibuf); + IMB_freeImBuf(searchibuf); - return pixels; + return gray_pixels; } static unsigned char *get_ucharbuf(ImBuf *ibuf) @@ -1311,7 +1545,7 @@ static ImBuf *get_frame_ibuf(MovieTrackingContext *context, int framenr) ImBuf *ibuf; MovieClipUser user = context->user; - user.framenr = framenr; + user.framenr = BKE_movieclip_remap_clip_to_scene_frame(context->clip, framenr); ibuf = BKE_movieclip_get_ibuf_flag(context->clip, &user, context->clip_flag, MOVIECLIP_CACHE_SKIP); @@ -1398,10 +1632,12 @@ void BKE_tracking_sync_user(MovieClipUser *user, MovieTrackingContext *context) int BKE_tracking_next(MovieTrackingContext *context) { - ImBuf *ibuf_new; - int curfra = context->user.framenr; + ImBuf *destination_ibuf; + int curfra = BKE_movieclip_remap_scene_to_clip_frame(context->clip, context->user.framenr); int a, ok = FALSE, map_size; + int frame_width, frame_height; + map_size = tracks_map_size(context->tracks_map); /* nothing to track, avoid unneeded frames reading to save time and memory */ @@ -1413,28 +1649,31 @@ int BKE_tracking_next(MovieTrackingContext *context) else context->user.framenr++; - ibuf_new = BKE_movieclip_get_ibuf_flag(context->clip, &context->user, context->clip_flag, MOVIECLIP_CACHE_SKIP); - if (!ibuf_new) + destination_ibuf = BKE_movieclip_get_ibuf_flag(context->clip, &context->user, + context->clip_flag, MOVIECLIP_CACHE_SKIP); + if (!destination_ibuf) return FALSE; - #pragma omp parallel for private(a) shared(ibuf_new, ok) if (map_size>1) + frame_width = destination_ibuf->x; + frame_height = destination_ibuf->y; + + #pragma omp parallel for private(a) shared(destination_ibuf, ok) if (map_size>1) for (a = 0; a < map_size; a++) { TrackContext *track_context = NULL; MovieTrackingTrack *track; MovieTrackingMarker *marker; - tracks_map_get(context->tracks_map, a, &track, (void**)&track_context); + tracks_map_get(context->tracks_map, a, &track, (void **)&track_context); marker = BKE_tracking_exact_marker(track, curfra); if (marker && (marker->flag & MARKER_DISABLED) == 0) { #ifdef WITH_LIBMV - int width, height, origin[2], tracked = 0, need_readjust = 0; - float pos[2], margin[2], dim[2]; - double x1, y1, x2, y2; - ImBuf *ibuf = NULL; + int width, height, tracked = 0, need_readjust = 0; + float margin[2], dim[2], pat_min[2], pat_max[2]; MovieTrackingMarker marker_new, *marker_keyed; int onbound = FALSE, nextfra; + double dst_pixel_x[5], dst_pixel_y[5]; if (track->pattern_match == TRACK_MATCH_KEYFRAME) need_readjust = context->first_time; @@ -1447,11 +1686,12 @@ int BKE_tracking_next(MovieTrackingContext *context) nextfra = curfra + 1; /* margin from frame boundaries */ - sub_v2_v2v2(dim, track->pat_max, track->pat_min); + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + sub_v2_v2v2(dim, pat_max, pat_min); margin[0] = margin[1] = MAX2(dim[0], dim[1]) / 2.0f; - margin[0] = MAX2(margin[0], (float)track->margin / ibuf_new->x); - margin[1] = MAX2(margin[1], (float)track->margin / ibuf_new->y); + margin[0] = MAX2(margin[0], (float)track->margin / destination_ibuf->x); + margin[1] = MAX2(margin[1], (float)track->margin / destination_ibuf->y); /* do not track markers which are too close to boundary */ if (marker->pos[0] < margin[0] || marker->pos[0] > 1.0f - margin[0] || @@ -1460,58 +1700,83 @@ int BKE_tracking_next(MovieTrackingContext *context) onbound = TRUE; } else { + /* to convert to the x/y split array format for libmv. */ + double src_pixel_x[5]; + double src_pixel_y[5]; + + /* settings for the tracker */ + struct libmv_trackRegionOptions options; + struct libmv_trackRegionResult result; + float *patch_new; if (need_readjust) { + ImBuf *reference_ibuf = NULL; /* calculate patch for keyframed position */ - ibuf = get_adjust_ibuf(context, track, marker, curfra, &marker_keyed); + reference_ibuf = get_adjust_ibuf(context, track, marker, curfra, &marker_keyed); + track_context->marker = *marker_keyed; - if (track_context->patch) - MEM_freeN(track_context->patch); + if (track_context->search_area) + MEM_freeN(track_context->search_area); - track_context->patch = get_search_floatbuf(ibuf, track, marker_keyed, &width, &height, - track_context->keyframed_pos, origin); + track_context->search_area = get_search_floatbuf(reference_ibuf, track, + marker_keyed, &width, &height); + track_context->search_area_height = height; + track_context->search_area_width = width; - IMB_freeImBuf(ibuf); + IMB_freeImBuf(reference_ibuf); } - patch_new = get_search_floatbuf(ibuf_new, track, marker, &width, &height, pos, origin); + /* for now track to the same search area dimension as marker has got for current frame + * will make all tracked markers in currently tracked segment have the same search area + * size, but it's quite close to what is actually needed + */ + patch_new = get_search_floatbuf(destination_ibuf, track, marker, &width, &height); + + /* Configure the tracker */ + options.motion_model = track->motion_model; + + options.use_brute = + ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_BRUTE) != 0); - x1 = track_context->keyframed_pos[0]; - y1 = track_context->keyframed_pos[1]; + options.use_normalization = + ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_NORMALIZATION) != 0); - x2 = pos[0]; - y2 = pos[1]; + options.num_iterations = 50; + options.minimum_correlation = track->minimum_correlation; + options.sigma = 0.9; - tracked = libmv_regionTrackerTrack(track_context->region_tracker, track_context->patch, patch_new, - width, height, x1, y1, &x2, &y2); + /* Convert the marker corners and center into pixel coordinates in the search/destination images. */ + get_marker_coords_for_tracking(frame_width, frame_height, &track_context->marker, src_pixel_x, src_pixel_y); + get_marker_coords_for_tracking(frame_width, frame_height, marker, dst_pixel_x, dst_pixel_y); + /* Run the tracker! */ + tracked = libmv_trackRegion(&options, + track_context->search_area, patch_new, + width, height, + src_pixel_x, src_pixel_y, + &result, + dst_pixel_x, dst_pixel_y); MEM_freeN(patch_new); } - if (tracked && !onbound && finite(x2) && finite(y2)) { + if (tracked && !onbound) { + memset(&marker_new, 0, sizeof(marker_new)); + marker_new = *marker; + set_marker_coords_from_tracking(frame_width, frame_height, &marker_new, dst_pixel_x, dst_pixel_y); + marker_new.flag |= MARKER_TRACKED; + marker_new.framenr = nextfra; + if (context->first_time) { #pragma omp critical { /* check if there's no keyframe/tracked markers before tracking marker. - * if so -- create disabled marker before currently tracking "segment" */ - put_disabled_marker(track, marker, !context->backwards, 0); + * if so -- create disabled marker before currently tracking "segment" + */ + put_disabled_marker(track, &marker_new, !context->backwards, 0); } } - memset(&marker_new, 0, sizeof(marker_new)); - - if (!onbound) { - marker_new.pos[0] = (origin[0] + x2) / ibuf_new->x; - marker_new.pos[1] = (origin[1] + y2) / ibuf_new->y; - } - else { - copy_v2_v2(marker_new.pos, marker->pos); - } - - marker_new.flag |= MARKER_TRACKED; - marker_new.framenr = nextfra; - #pragma omp critical { BKE_tracking_insert_marker(track, &marker_new); @@ -1529,7 +1794,7 @@ int BKE_tracking_next(MovieTrackingContext *context) marker_new.framenr = nextfra; marker_new.flag |= MARKER_DISABLED; - #pragma omp critical + //#pragma omp critical { BKE_tracking_insert_marker(track, &marker_new); } @@ -1540,7 +1805,7 @@ int BKE_tracking_next(MovieTrackingContext *context) } } - IMB_freeImBuf(ibuf_new); + IMB_freeImBuf(destination_ibuf); context->first_time = FALSE; context->frames++; @@ -2763,7 +3028,8 @@ ImBuf *BKE_tracking_stabilize(MovieTracking *tracking, int framenr, ImBuf *ibuf, if (tangle == 0.0f) { /* if angle is zero, then it's much faster to use rect copy - * but could be issues with subpixel precisions */ + * but could be issues with subpixel precisions + */ IMB_rectcpy(tmpibuf, ibuf, tloc[0] - (tscale - 1.0f) * width / 2.0f, tloc[1] - (tscale - 1.0f) * height / 2.0f, @@ -3113,6 +3379,17 @@ static int channels_longest_segment_sort(void *a, void *b) return 0; } +static int channels_average_error_sort(void *a, void *b) +{ + MovieTrackingDopesheetChannel *channel_a = a; + MovieTrackingDopesheetChannel *channel_b = b; + + if (channel_a->track->error > channel_b->track->error) + return 1; + else + return 0; +} + static int channels_alpha_inverse_sort(void *a, void *b) { if (channels_alpha_sort(a, b)) @@ -3137,6 +3414,17 @@ static int channels_longest_segment_inverse_sort(void *a, void *b) return 1; } +static int channels_average_error_inverse_sort(void *a, void *b) +{ + MovieTrackingDopesheetChannel *channel_a = a; + MovieTrackingDopesheetChannel *channel_b = b; + + if (channel_a->track->error < channel_b->track->error) + return 1; + else + return 0; +} + static void channels_segments_calc(MovieTrackingDopesheetChannel *channel) { MovieTrackingTrack *track = channel->track; @@ -3232,6 +3520,9 @@ static void tracking_dopesheet_sort(MovieTracking *tracking, int sort_method, i else if (sort_method == TRACK_SORT_TOTAL) { BLI_sortlist(&dopesheet->channels, channels_total_track_inverse_sort); } + else if (sort_method == TRACK_SORT_AVERAGE_ERROR) { + BLI_sortlist(&dopesheet->channels, channels_average_error_inverse_sort); + } } else { if (sort_method == TRACK_SORT_NAME) { @@ -3243,6 +3534,9 @@ static void tracking_dopesheet_sort(MovieTracking *tracking, int sort_method, i else if (sort_method == TRACK_SORT_TOTAL) { BLI_sortlist(&dopesheet->channels, channels_total_track_sort); } + else if (sort_method == TRACK_SORT_AVERAGE_ERROR) { + BLI_sortlist(&dopesheet->channels, channels_average_error_sort); + } } dopesheet->sort_method = sort_method; diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index 91e93bbd05d..40471514b48 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -1003,9 +1003,11 @@ void BKE_ffmpeg_end(void) fprintf(stderr, "Closing ffmpeg...\n"); -/* if (audio_stream) { SEE UPPER - write_audio_frames(); - }*/ +#if 0 + if (audio_stream) { /* SEE UPPER */ + write_audio_frames(); + } +#endif #ifdef WITH_AUDASPACE if (audio_mixdown_device) { diff --git a/source/blender/blenlib/BLI_boxpack2d.h b/source/blender/blenlib/BLI_boxpack2d.h index 77e937d7b6f..3bc486054f5 100644 --- a/source/blender/blenlib/BLI_boxpack2d.h +++ b/source/blender/blenlib/BLI_boxpack2d.h @@ -43,7 +43,7 @@ typedef struct BoxPack { /* Verts this box uses * (BL,TR,TL,BR) / 0,1,2,3 */ - struct boxVert *v[4]; + struct BoxVert *v[4]; } BoxPack; void BLI_box_pack_2D(BoxPack *boxarray, const int len, float *tot_width, float *tot_height); diff --git a/source/blender/blenlib/BLI_pbvh.h b/source/blender/blenlib/BLI_pbvh.h index 8806721c044..dbfa08219bd 100644 --- a/source/blender/blenlib/BLI_pbvh.h +++ b/source/blender/blenlib/BLI_pbvh.h @@ -83,9 +83,12 @@ void BLI_pbvh_search_gather(PBVH *bvh, * hit first */ void BLI_pbvh_raycast(PBVH * bvh, BLI_pbvh_HitOccludedCallback cb, void *data, - float ray_start[3], float ray_normal[3], int original); + const float ray_start[3], const float ray_normal[3], + int original); + int BLI_pbvh_node_raycast(PBVH * bvh, PBVHNode * node, float (*origco)[3], - float ray_start[3], float ray_normal[3], float *dist); + const float ray_start[3], const float ray_normal[3], + float *dist); /* Drawing */ diff --git a/source/blender/blenlib/BLI_string_cursor_utf8.h b/source/blender/blenlib/BLI_string_cursor_utf8.h index 11c91aac6ac..3c38c0380e0 100644 --- a/source/blender/blenlib/BLI_string_cursor_utf8.h +++ b/source/blender/blenlib/BLI_string_cursor_utf8.h @@ -26,7 +26,7 @@ #ifndef __BLI_STRING_CURSOR_UTF8_H__ #define __BLI_STRING_CURSOR_UTF8_H__ -/** \file BLI_string_utf8.h +/** \file BLI_string_cursor_utf8.h * \ingroup bli */ diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h index b13da9f0dd4..fb8771722c1 100644 --- a/source/blender/blenlib/BLI_threads.h +++ b/source/blender/blenlib/BLI_threads.h @@ -136,6 +136,7 @@ void *BLI_thread_queue_pop(ThreadQueue *queue); void *BLI_thread_queue_pop_timeout(ThreadQueue *queue, int ms); int BLI_thread_queue_size(ThreadQueue *queue); +void BLI_thread_queue_wait_finish(ThreadQueue *queue); void BLI_thread_queue_nowait(ThreadQueue *queue); #endif diff --git a/source/blender/blenlib/intern/boxpack2d.c b/source/blender/blenlib/intern/boxpack2d.c index bf63517a4c2..feaa60b40b2 100644 --- a/source/blender/blenlib/intern/boxpack2d.c +++ b/source/blender/blenlib/intern/boxpack2d.c @@ -33,7 +33,7 @@ * * The defined Below are for internal use only */ -typedef struct boxVert { +typedef struct BoxVert { float x; float y; short free; @@ -48,7 +48,7 @@ typedef struct boxVert { struct BoxPack *isect_cache[4]; int index; -} boxVert; +} BoxVert; /* free vert flags */ #define EPSILON 0.0000001f @@ -121,11 +121,11 @@ static int box_areasort(const void *p1, const void *p2) * */ static float box_width; static float box_height; -static boxVert *vertarray; +static BoxVert *vertarray; static int vertex_sort(const void *p1, const void *p2) { - boxVert *v1, *v2; + BoxVert *v1, *v2; float a1, a2; v1 = vertarray + ((int *)p1)[0]; @@ -154,7 +154,7 @@ static int vertex_sort(const void *p1, const void *p2) * */ void BLI_box_pack_2D(BoxPack *boxarray, const int len, float *tot_width, float *tot_height) { - boxVert *vert; /* the current vert */ + BoxVert *vert; /* the current vert */ int box_index, verts_pack_len, i, j, k, isect; int quad_flags[4] = {BLF, TRF, TLF, BRF}; /* use for looping */ BoxPack *box, *box_test; /*current box and another for intersection tests*/ @@ -170,38 +170,38 @@ void BLI_box_pack_2D(BoxPack *boxarray, const int len, float *tot_width, float * qsort(boxarray, len, sizeof(BoxPack), box_areasort); /* add verts to the boxes, these are only used internally */ - vert = vertarray = MEM_mallocN(len * 4 * sizeof(boxVert), "BoxPack Verts"); + vert = vertarray = MEM_mallocN(len * 4 * sizeof(BoxVert), "BoxPack Verts"); vertex_pack_indices = MEM_mallocN(len * 3 * sizeof(int), "BoxPack Indices"); for (box = boxarray, box_index = 0, i = 0; box_index < len; box_index++, box++) { vert->blb = vert->brb = vert->tlb = - vert->isect_cache[0] = vert->isect_cache[1] = - vert->isect_cache[2] = vert->isect_cache[3] = NULL; + vert->isect_cache[0] = vert->isect_cache[1] = + vert->isect_cache[2] = vert->isect_cache[3] = NULL; vert->free = CORNERFLAGS & ~TRF; vert->trb = box; vert->index = i; i++; box->v[BL] = vert; vert++; vert->trb = vert->brb = vert->tlb = - vert->isect_cache[0] = vert->isect_cache[1] = - vert->isect_cache[2] = vert->isect_cache[3] = NULL; + vert->isect_cache[0] = vert->isect_cache[1] = + vert->isect_cache[2] = vert->isect_cache[3] = NULL; vert->free = CORNERFLAGS & ~BLF; vert->blb = box; vert->index = i; i++; box->v[TR] = vert; vert++; vert->trb = vert->blb = vert->tlb = - vert->isect_cache[0] = vert->isect_cache[1] = - vert->isect_cache[2] = vert->isect_cache[3] = NULL; + vert->isect_cache[0] = vert->isect_cache[1] = + vert->isect_cache[2] = vert->isect_cache[3] = NULL; vert->free = CORNERFLAGS & ~BRF; vert->brb = box; vert->index = i; i++; box->v[TL] = vert; vert++; vert->trb = vert->blb = vert->brb = - vert->isect_cache[0] = vert->isect_cache[1] = - vert->isect_cache[2] = vert->isect_cache[3] = NULL; + vert->isect_cache[0] = vert->isect_cache[1] = + vert->isect_cache[2] = vert->isect_cache[3] = NULL; vert->free = CORNERFLAGS & ~TLF; vert->tlb = box; vert->index = i; i++; diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c index 131ea59d3e5..85391336c86 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenlib/intern/bpath.c @@ -510,11 +510,11 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int SEQ_BEGIN(scene->ed, seq) { if (SEQ_HAS_PATH(seq)) { - if (ELEM(seq->type, SEQ_MOVIE, SEQ_SOUND)) { + if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM)) { rewrite_path_fixed_dirfile(seq->strip->dir, seq->strip->stripdata->name, visit_cb, absbase, bpath_user_data); } - else if (seq->type == SEQ_IMAGE) { + else if (seq->type == SEQ_TYPE_IMAGE) { /* might want an option not to loop over all strips */ StripElem *se = seq->strip->stripdata; int len = MEM_allocN_len(se) / sizeof(*se); diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index e6d06484e74..ec7b59702bd 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -385,16 +385,16 @@ int BLI_rename(const char *from, const char *to) enum { /* operation succeeded succeeded */ - recursiveOp_Callback_OK = 0, + RecursiveOp_Callback_OK = 0, /* operation requested not to perform recursive digging for current path */ - recursiveOp_Callback_StopRecurs = 1, + RecursiveOp_Callback_StopRecurs = 1, /* error occured in callback and recursive walking should stop immediately */ - recursiveOp_Callback_Error = 2 + RecursiveOp_Callback_Error = 2 } recuresiveOp_Callback_Result; -typedef int (*recursiveOp_Callback)(const char *from, const char *to); +typedef int (*RecursiveOp_Callback)(const char *from, const char *to); /* appending of filename to dir (ensures for buffer size before appending) */ static void join_dirfile_alloc(char **dst, size_t *alloc_len, const char *dir, const char *file) @@ -419,8 +419,8 @@ static char *strip_last_slash(const char *dir) return result; } -static int recursive_operation(const char *startfrom, const char *startto, recursiveOp_Callback callback_dir_pre, - recursiveOp_Callback callback_file, recursiveOp_Callback callback_dir_post) +static int recursive_operation(const char *startfrom, const char *startto, RecursiveOp_Callback callback_dir_pre, + RecursiveOp_Callback callback_file, RecursiveOp_Callback callback_dir_post) { struct dirent **dirlist; struct stat st; @@ -446,7 +446,7 @@ static int recursive_operation(const char *startfrom, const char *startto, recur if (callback_file) { ret = callback_file(from, to); - if (ret != recursiveOp_Callback_OK) + if (ret != RecursiveOp_Callback_OK) ret = -1; } @@ -472,11 +472,11 @@ static int recursive_operation(const char *startfrom, const char *startto, recur /* call pre-recursive walking directory callback */ ret = callback_dir_pre(from, to); - if (ret != recursiveOp_Callback_OK) { + if (ret != RecursiveOp_Callback_OK) { MEM_freeN(from); if (to) free(to); - if (ret == recursiveOp_Callback_StopRecurs) { + if (ret == RecursiveOp_Callback_StopRecurs) { /* callback requested not to perform recursive walking, not an error */ return 0; } @@ -505,7 +505,7 @@ static int recursive_operation(const char *startfrom, const char *startto, recur else if (callback_file) { /* call file callback for current path */ ret = callback_file(from_path, to_path); - if (ret != recursiveOp_Callback_OK) + if (ret != RecursiveOp_Callback_OK) ret = -1; } @@ -522,7 +522,7 @@ static int recursive_operation(const char *startfrom, const char *startto, recur if (callback_dir_post) { /* call post-recursive directory callback */ ret = callback_dir_post(from, to); - if (ret != recursiveOp_Callback_OK) + if (ret != RecursiveOp_Callback_OK) ret = -1; } } @@ -541,10 +541,10 @@ static int delete_callback_post(const char *from, const char *UNUSED(to)) if (rmdir(from)) { perror("rmdir"); - return recursiveOp_Callback_Error; + return RecursiveOp_Callback_Error; } - return recursiveOp_Callback_OK; + return RecursiveOp_Callback_OK; } static int delete_single_file(const char *from, const char *UNUSED(to)) @@ -552,10 +552,10 @@ static int delete_single_file(const char *from, const char *UNUSED(to)) if (unlink(from)) { perror("unlink"); - return recursiveOp_Callback_Error; + return RecursiveOp_Callback_Error; } - return recursiveOp_Callback_OK; + return RecursiveOp_Callback_OK; } FILE *BLI_fopen(const char *filename, const char *mode) @@ -628,27 +628,27 @@ static int copy_callback_pre(const char *from, const char *to) if (check_the_same(from, to)) { fprintf(stderr, "%s: '%s' is the same as '%s'\n", __func__, from, to); - return recursiveOp_Callback_Error; + return RecursiveOp_Callback_Error; } if (lstat(from, &st)) { perror("stat"); - return recursiveOp_Callback_Error; + return RecursiveOp_Callback_Error; } /* create a directory */ if (mkdir(to, st.st_mode)) { perror("mkdir"); - return recursiveOp_Callback_Error; + return RecursiveOp_Callback_Error; } /* set proper owner and group on new directory */ if (chown(to, st.st_uid, st.st_gid)) { perror("chown"); - return recursiveOp_Callback_Error; + return RecursiveOp_Callback_Error; } - return recursiveOp_Callback_OK; + return RecursiveOp_Callback_OK; } static int copy_single_file(const char *from, const char *to) @@ -660,12 +660,12 @@ static int copy_single_file(const char *from, const char *to) if (check_the_same(from, to)) { fprintf(stderr, "%s: '%s' is the same as '%s'\n", __func__, from, to); - return recursiveOp_Callback_Error; + return RecursiveOp_Callback_Error; } if (lstat(from, &st)) { perror("lstat"); - return recursiveOp_Callback_Error; + return RecursiveOp_Callback_Error; } if (S_ISLNK(st.st_mode)) { @@ -690,7 +690,7 @@ static int copy_single_file(const char *from, const char *to) if (need_free) MEM_freeN(link_buffer); - return recursiveOp_Callback_Error; + return RecursiveOp_Callback_Error; } link_buffer[link_len] = 0; @@ -698,13 +698,13 @@ static int copy_single_file(const char *from, const char *to) if (symlink(link_buffer, to)) { perror("symlink"); if (need_free) MEM_freeN(link_buffer); - return recursiveOp_Callback_Error; + return RecursiveOp_Callback_Error; } if (need_free) MEM_freeN(link_buffer); - return recursiveOp_Callback_OK; + return RecursiveOp_Callback_OK; } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) || @@ -714,30 +714,30 @@ static int copy_single_file(const char *from, const char *to) /* copy special type of file */ if (mknod(to, st.st_mode, st.st_rdev)) { perror("mknod"); - return recursiveOp_Callback_Error; + return RecursiveOp_Callback_Error; } if (set_permissions(to, &st)) - return recursiveOp_Callback_Error; + return RecursiveOp_Callback_Error; - return recursiveOp_Callback_OK; + return RecursiveOp_Callback_OK; } else if (!S_ISREG(st.st_mode)) { fprintf(stderr, "Copying of this kind of files isn't supported yet\n"); - return recursiveOp_Callback_Error; + return RecursiveOp_Callback_Error; } from_stream = fopen(from, "rb"); if (!from_stream) { perror("fopen"); - return recursiveOp_Callback_Error; + return RecursiveOp_Callback_Error; } to_stream = fopen(to, "wb"); if (!to_stream) { perror("fopen"); fclose(from_stream); - return recursiveOp_Callback_Error; + return RecursiveOp_Callback_Error; } while ((len = fread(buf, 1, sizeof(buf), from_stream)) > 0) { @@ -748,9 +748,9 @@ static int copy_single_file(const char *from, const char *to) fclose(from_stream); if (set_permissions(to, &st)) - return recursiveOp_Callback_Error; + return RecursiveOp_Callback_Error; - return recursiveOp_Callback_OK; + return RecursiveOp_Callback_OK; } static int move_callback_pre(const char *from, const char *to) @@ -760,7 +760,7 @@ static int move_callback_pre(const char *from, const char *to) if (ret) return copy_callback_pre(from, to); - return recursiveOp_Callback_StopRecurs; + return RecursiveOp_Callback_StopRecurs; } static int move_single_file(const char *from, const char *to) @@ -770,7 +770,7 @@ static int move_single_file(const char *from, const char *to) if (ret) return copy_single_file(from, to); - return recursiveOp_Callback_OK; + return RecursiveOp_Callback_OK; } int BLI_move(const char *file, const char *to) diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index da07bb156d7..ef2eb25a891 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -614,7 +614,7 @@ font driver produces such outlines. # \ # - Two "on" points + Two "on" points and two "cubic" point between them diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c index 9433cfd31df..5b034bd2872 100644 --- a/source/blender/blenlib/intern/math_color.c +++ b/source/blender/blenlib/intern/math_color.c @@ -285,8 +285,8 @@ void rgb_to_hsl(float r, float g, float b, float *lh, float *ls, float *ll) else { h = (r - g) / d + 4.0f; } - } - h /= 6.0f; + } + h /= 6.0f; *lh = h; *ls = s; @@ -634,23 +634,23 @@ void BLI_init_srgb_conversion(void) } static float inverse_srgb_companding(float v) { - if (v > 0.04045f) { - return powf((v + 0.055f) / 1.055f, 2.4); - } - else { - return v / 12.92f; - } + if (v > 0.04045f) { + return powf((v + 0.055f) / 1.055f, 2.4); + } + else { + return v / 12.92f; + } } void rgb_to_xyz(float r, float g, float b, float *x, float *y, float *z) { - r = inverse_srgb_companding(r) * 100.0f; - g = inverse_srgb_companding(g) * 100.0f; - b = inverse_srgb_companding(b) * 100.0f; + r = inverse_srgb_companding(r) * 100.0f; + g = inverse_srgb_companding(g) * 100.0f; + b = inverse_srgb_companding(b) * 100.0f; - *x = r * 0.4124 + g * 0.3576 + b * 0.1805; - *y = r * 0.2126 + g * 0.7152 + b * 0.0722; - *z = r * 0.0193 + g * 0.1192 + b * 0.9505; + *x = r * 0.4124 + g * 0.3576 + b * 0.1805; + *y = r * 0.2126 + g * 0.7152 + b * 0.0722; + *z = r * 0.0193 + g * 0.1192 + b * 0.9505; } static float xyz_to_lab_component(float v) diff --git a/source/blender/blenlib/intern/math_color_inline.c b/source/blender/blenlib/intern/math_color_inline.c index 243e9fc8a57..b2a87a91433 100644 --- a/source/blender/blenlib/intern/math_color_inline.c +++ b/source/blender/blenlib/intern/math_color_inline.c @@ -215,4 +215,11 @@ MINLINE void rgba_char_args_test_set(char col[4], const char r, const char g, co } } +MINLINE void cpack_cpy_3ub(unsigned char r_col[3], const unsigned int pack) +{ + r_col[0] = ((pack) >> 0) & 0xFF; + r_col[1] = ((pack) >> 8) & 0xFF; + r_col[2] = ((pack) >> 16) & 0xFF; +} + #endif /* __MATH_COLOR_INLINE_C__ */ diff --git a/source/blender/blenlib/intern/pbvh.c b/source/blender/blenlib/intern/pbvh.c index f4b57857173..5361682caa4 100644 --- a/source/blender/blenlib/intern/pbvh.c +++ b/source/blender/blenlib/intern/pbvh.c @@ -1137,17 +1137,21 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode) if (node->flag & PBVH_RebuildDrawBuffers) { GPU_free_buffers(node->draw_buffers); - if (bvh->grids) { - node->draw_buffers = - GPU_build_grid_buffers(node->prim_indices, - node->totprim, bvh->grid_hidden, bvh->gridkey.grid_size); - } - else { - node->draw_buffers = - GPU_build_mesh_buffers(node->face_vert_indices, - bvh->faces, bvh->verts, - node->prim_indices, - node->totprim); + switch (bvh->type) { + case PBVH_GRIDS: + node->draw_buffers = + GPU_build_grid_buffers(node->prim_indices, + node->totprim, + bvh->grid_hidden, + bvh->gridkey.grid_size); + break; + case PBVH_FACES: + node->draw_buffers = + GPU_build_mesh_buffers(node->face_vert_indices, + bvh->faces, bvh->verts, + node->prim_indices, + node->totprim); + break; } node->flag &= ~PBVH_RebuildDrawBuffers; @@ -1473,7 +1477,8 @@ static int ray_aabb_intersect(PBVHNode *node, void *data_v) } void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data, - float ray_start[3], float ray_normal[3], int original) + const float ray_start[3], const float ray_normal[3], + int original) { RaycastData rcd; @@ -1489,8 +1494,10 @@ void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data, BLI_pbvh_search_callback_occluded(bvh, ray_aabb_intersect, &rcd, cb, data); } -static int ray_face_intersection(float ray_start[3], float ray_normal[3], - float *t0, float *t1, float *t2, float *t3, +static int ray_face_intersection(const float ray_start[3], + const float ray_normal[3], + const float *t0, const float *t1, + const float *t2, const float *t3, float *fdist) { float dist; @@ -1506,91 +1513,114 @@ static int ray_face_intersection(float ray_start[3], float ray_normal[3], } } -int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], - float ray_start[3], float ray_normal[3], float *dist) +static int pbvh_faces_node_raycast(PBVH *bvh, const PBVHNode *node, + float (*origco)[3], + const float ray_start[3], + const float ray_normal[3], float *dist) { - MVert *vert; - BLI_bitmap gh; - int *faces, totface, gridsize, totgrid; + const MVert *vert = bvh->verts; + const int *faces = node->prim_indices; + int i, hit = 0, totface = node->totprim; + + for (i = 0; i < totface; ++i) { + const MFace *f = bvh->faces + faces[i]; + const int *face_verts = node->face_vert_indices[i]; + + if (paint_is_face_hidden(f, vert)) + continue; + + if (origco) { + /* intersect with backuped original coordinates */ + hit |= ray_face_intersection(ray_start, ray_normal, + origco[face_verts[0]], + origco[face_verts[1]], + origco[face_verts[2]], + f->v4 ? origco[face_verts[3]] : NULL, + dist); + } + else { + /* intersect with current coordinates */ + hit |= ray_face_intersection(ray_start, ray_normal, + vert[f->v1].co, + vert[f->v2].co, + vert[f->v3].co, + f->v4 ? vert[f->v4].co : NULL, + dist); + } + } + + return hit; +} + +static int pbvh_grids_node_raycast(PBVH *bvh, PBVHNode *node, + float (*origco)[3], + const float ray_start[3], + const float ray_normal[3], float *dist) +{ + int totgrid = node->totprim; + int gridsize = bvh->gridkey.grid_size; int i, x, y, hit = 0; - if (node->flag & PBVH_FullyHidden) - return 0; + for (i = 0; i < totgrid; ++i) { + CCGElem *grid = bvh->grids[node->prim_indices[i]]; + BLI_bitmap gh; - switch (bvh->type) { - case PBVH_FACES: - vert = bvh->verts; - faces = node->prim_indices; - totface = node->totprim; + if (!grid) + continue; - for (i = 0; i < totface; ++i) { - const MFace *f = bvh->faces + faces[i]; - int *face_verts = node->face_vert_indices[i]; + gh = bvh->grid_hidden[node->prim_indices[i]]; - if (paint_is_face_hidden(f, vert)) - continue; + for (y = 0; y < gridsize - 1; ++y) { + for (x = 0; x < gridsize - 1; ++x) { + /* check if grid face is hidden */ + if (gh) { + if (paint_is_grid_face_hidden(gh, gridsize, x, y)) + continue; + } if (origco) { - /* intersect with backuped original coordinates */ hit |= ray_face_intersection(ray_start, ray_normal, - origco[face_verts[0]], - origco[face_verts[1]], - origco[face_verts[2]], - f->v4 ? origco[face_verts[3]] : NULL, - dist); + origco[y * gridsize + x], + origco[y * gridsize + x + 1], + origco[(y + 1) * gridsize + x + 1], + origco[(y + 1) * gridsize + x], + dist); } else { - /* intersect with current coordinates */ hit |= ray_face_intersection(ray_start, ray_normal, - vert[f->v1].co, - vert[f->v2].co, - vert[f->v3].co, - f->v4 ? vert[f->v4].co : NULL, - dist); + CCG_grid_elem_co(&bvh->gridkey, grid, x, y), + CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y), + CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y + 1), + CCG_grid_elem_co(&bvh->gridkey, grid, x, y + 1), + dist); } } + } + + if (origco) + origco += gridsize * gridsize; + } + + return hit; +} + +int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], + const float ray_start[3], const float ray_normal[3], + float *dist) +{ + int hit = 0; + + if (node->flag & PBVH_FullyHidden) + return 0; + + switch (bvh->type) { + case PBVH_FACES: + hit |= pbvh_faces_node_raycast(bvh, node, origco, + ray_start, ray_normal, dist); break; case PBVH_GRIDS: - totgrid = node->totprim; - gridsize = bvh->gridkey.grid_size; - - for (i = 0; i < totgrid; ++i) { - CCGElem *grid = bvh->grids[node->prim_indices[i]]; - if (!grid) - continue; - - gh = bvh->grid_hidden[node->prim_indices[i]]; - - for (y = 0; y < gridsize - 1; ++y) { - for (x = 0; x < gridsize - 1; ++x) { - /* check if grid face is hidden */ - if (gh) { - if (paint_is_grid_face_hidden(gh, gridsize, x, y)) - continue; - } - - if (origco) { - hit |= ray_face_intersection(ray_start, ray_normal, - origco[y * gridsize + x], - origco[y * gridsize + x + 1], - origco[(y + 1) * gridsize + x + 1], - origco[(y + 1) * gridsize + x], - dist); - } - else { - hit |= ray_face_intersection(ray_start, ray_normal, - CCG_grid_elem_co(&bvh->gridkey, grid, x, y), - CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y), - CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y + 1), - CCG_grid_elem_co(&bvh->gridkey, grid, x, y + 1), - dist); - } - } - } - - if (origco) - origco += gridsize * gridsize; - } + hit |= pbvh_grids_node_raycast(bvh, node, origco, + ray_start, ray_normal, dist); break; } @@ -1787,11 +1817,7 @@ PBVHProxyNode *BLI_pbvh_node_add_proxy(PBVH *bvh, PBVHNode *node) else node->proxies = MEM_mallocN(sizeof(PBVHProxyNode), "PBVHNodeProxy"); - if (bvh->grids) - totverts = node->totprim * bvh->gridkey.grid_area; - else - totverts = node->uniq_verts; - + BLI_pbvh_node_num_verts(bvh, node, &totverts, NULL); node->proxies[index].co = MEM_callocN(sizeof(float[3]) * totverts, "PBVHNodeProxy.co"); } diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c index e9bccd4244b..9795d4dea2d 100644 --- a/source/blender/blenlib/intern/string_utf8.c +++ b/source/blender/blenlib/intern/string_utf8.c @@ -335,9 +335,9 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *dst_w, const char *src_c, const size int BLI_str_utf8_size(const char *p) { int mask = 0, len; - unsigned char c = (unsigned char) *p; + unsigned char c = (unsigned char) *p; - UTF8_COMPUTE (c, mask, len); + UTF8_COMPUTE (c, mask, len); (void)mask; /* quiet warning */ diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c index f9f677d7c22..dc4c15a82fc 100644 --- a/source/blender/blenlib/intern/threads.c +++ b/source/blender/blenlib/intern/threads.c @@ -520,8 +520,10 @@ void BLI_insert_work(ThreadedWorker *worker, void *param) struct ThreadQueue { GSQueue *queue; pthread_mutex_t mutex; - pthread_cond_t cond; - int nowait; + pthread_cond_t push_cond; + pthread_cond_t finish_cond; + volatile int nowait; + volatile int cancelled; }; ThreadQueue *BLI_thread_queue_init(void) @@ -532,14 +534,17 @@ ThreadQueue *BLI_thread_queue_init(void) queue->queue = BLI_gsqueue_new(sizeof(void *)); pthread_mutex_init(&queue->mutex, NULL); - pthread_cond_init(&queue->cond, NULL); + pthread_cond_init(&queue->push_cond, NULL); + pthread_cond_init(&queue->finish_cond, NULL); return queue; } void BLI_thread_queue_free(ThreadQueue *queue) { - pthread_cond_destroy(&queue->cond); + /* destroy everything, assumes no one is using queue anymore */ + pthread_cond_destroy(&queue->finish_cond); + pthread_cond_destroy(&queue->push_cond); pthread_mutex_destroy(&queue->mutex); BLI_gsqueue_free(queue->queue); @@ -554,7 +559,7 @@ void BLI_thread_queue_push(ThreadQueue *queue, void *work) BLI_gsqueue_push(queue->queue, &work); /* signal threads waiting to pop */ - pthread_cond_signal(&queue->cond); + pthread_cond_signal(&queue->push_cond); pthread_mutex_unlock(&queue->mutex); } @@ -565,11 +570,15 @@ void *BLI_thread_queue_pop(ThreadQueue *queue) /* wait until there is work */ pthread_mutex_lock(&queue->mutex); while (BLI_gsqueue_is_empty(queue->queue) && !queue->nowait) - pthread_cond_wait(&queue->cond, &queue->mutex); - + pthread_cond_wait(&queue->push_cond, &queue->mutex); + /* if we have something, pop it */ - if (!BLI_gsqueue_is_empty(queue->queue)) + if (!BLI_gsqueue_is_empty(queue->queue)) { BLI_gsqueue_pop(queue->queue, &work); + + if(BLI_gsqueue_is_empty(queue->queue)) + pthread_cond_broadcast(&queue->finish_cond); + } pthread_mutex_unlock(&queue->mutex); @@ -623,16 +632,20 @@ void *BLI_thread_queue_pop_timeout(ThreadQueue *queue, int ms) /* wait until there is work */ pthread_mutex_lock(&queue->mutex); while (BLI_gsqueue_is_empty(queue->queue) && !queue->nowait) { - if (pthread_cond_timedwait(&queue->cond, &queue->mutex, &timeout) == ETIMEDOUT) + if (pthread_cond_timedwait(&queue->push_cond, &queue->mutex, &timeout) == ETIMEDOUT) break; else if (PIL_check_seconds_timer() - t >= ms * 0.001) break; } /* if we have something, pop it */ - if (!BLI_gsqueue_is_empty(queue->queue)) + if (!BLI_gsqueue_is_empty(queue->queue)) { BLI_gsqueue_pop(queue->queue, &work); - + + if(BLI_gsqueue_is_empty(queue->queue)) + pthread_cond_broadcast(&queue->finish_cond); + } + pthread_mutex_unlock(&queue->mutex); return work; @@ -656,10 +669,23 @@ void BLI_thread_queue_nowait(ThreadQueue *queue) queue->nowait = 1; /* signal threads waiting to pop */ - pthread_cond_signal(&queue->cond); + pthread_cond_broadcast(&queue->push_cond); + pthread_mutex_unlock(&queue->mutex); +} + +void BLI_thread_queue_wait_finish(ThreadQueue *queue) +{ + /* wait for finish condition */ + pthread_mutex_lock(&queue->mutex); + + while(!BLI_gsqueue_is_empty(queue->queue)) + pthread_cond_wait(&queue->finish_cond, &queue->mutex); + pthread_mutex_unlock(&queue->mutex); } +/* ************************************************ */ + void BLI_begin_threaded_malloc(void) { if (thread_levels == 0) { @@ -674,3 +700,4 @@ void BLI_end_threaded_malloc(void) if (thread_levels == 0) MEM_set_lock_callback(NULL, NULL); } + diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 6cad85aa273..95ac030a440 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -96,6 +96,7 @@ #include "DNA_vfont_types.h" #include "DNA_world_types.h" #include "DNA_movieclip_types.h" +#include "DNA_mask_types.h" #include "MEM_guardedalloc.h" @@ -1210,7 +1211,6 @@ static void change_idid_adr_fd(FileData *fd, void *old, void *new) if (old==entry->newp && entry->nr==ID_ID) { entry->newp = new; if (new) entry->nr = GS( ((ID *)new)->name ); - break; } } } @@ -3685,7 +3685,7 @@ static void lib_link_mesh(FileData *fd, Main *main) Main *gmain = G.main; G.main = main; - BKE_mesh_convert_mfaces_to_mpolys(me); + BKE_mesh_do_versions_convert_mfaces_to_mpolys(me); G.main = gmain; } @@ -3979,7 +3979,7 @@ static void direct_link_latt(FileData *fd, Lattice *lt) /* ************ READ OBJECT ***************** */ static void lib_link_modifiers__linkModifiers(void *userData, Object *ob, - ID **idpoin) + ID **idpoin) { FileData *fd = userData; @@ -4830,11 +4830,15 @@ static void lib_link_scene(FileData *fd, Main *main) seq->clip = newlibadr(fd, sce->id.lib, seq->clip); seq->clip->id.us++; } + if (seq->mask) { + seq->mask = newlibadr(fd, sce->id.lib, seq->mask); + seq->mask->id.us++; + } if (seq->scene_camera) seq->scene_camera = newlibadr(fd, sce->id.lib, seq->scene_camera); if (seq->sound) { seq->scene_sound = NULL; - if (seq->type == SEQ_HD_SOUND) - seq->type = SEQ_SOUND; + if (seq->type == SEQ_TYPE_SOUND_HD) + seq->type = SEQ_TYPE_SOUND_RAM; else seq->sound = newlibadr(fd, sce->id.lib, seq->sound); if (seq->sound) { @@ -4964,10 +4968,10 @@ static void direct_link_scene(FileData *fd, Scene *sce) seq->effectdata = newdataadr(fd, seq->effectdata); - if (seq->type & SEQ_EFFECT) + if (seq->type & SEQ_TYPE_EFFECT) seq->flag |= SEQ_EFFECT_NOT_LOADED; - if (seq->type == SEQ_SPEED) { + if (seq->type == SEQ_TYPE_SPEED) { SpeedControlVars *s = seq->effectdata; s->frameMap = NULL; } @@ -4976,7 +4980,7 @@ static void direct_link_scene(FileData *fd, Scene *sce) if (seq->strip && seq->strip->done==0) { seq->strip->done = TRUE; - if (ELEM4(seq->type, SEQ_IMAGE, SEQ_MOVIE, SEQ_RAM_SOUND, SEQ_HD_SOUND)) { + if (ELEM4(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) { seq->strip->stripdata = newdataadr(fd, seq->strip->stripdata); } else { @@ -5368,9 +5372,11 @@ static void lib_link_screen(FileData *fd, Main *main) } else if (sl->spacetype == SPACE_CLIP) { SpaceClip *sclip = (SpaceClip *)sl; - + sclip->clip = newlibadr_us(fd, sc->id.lib, sclip->clip); - + sclip->mask = newlibadr_us(fd, sc->id.lib, sclip->mask); + + sclip->scopes.track_search = NULL; sclip->scopes.track_preview = NULL; sclip->draw_context = NULL; sclip->scopes.ok = 0; @@ -5631,9 +5637,10 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) } else if (sl->spacetype == SPACE_CLIP) { SpaceClip *sclip = (SpaceClip *)sl; - + sclip->clip = restore_pointer_by_name(newmain, (ID *)sclip->clip, 1); - + sclip->mask = restore_pointer_by_name(newmain, (ID *)sclip->mask, 1); + sclip->scopes.ok = 0; } } @@ -6172,22 +6179,122 @@ static void direct_link_movieclip(FileData *fd, MovieClip *clip) } } +static void lib_link_movieTracks(FileData *fd, MovieClip *clip, ListBase *tracksbase) +{ + MovieTrackingTrack *track; + + for (track = tracksbase->first; track; track = track->next) { + track->gpd = newlibadr_us(fd, clip->id.lib, track->gpd); + } +} + static void lib_link_movieclip(FileData *fd, Main *main) { MovieClip *clip; for (clip = main->movieclip.first; clip; clip = clip->id.next) { if (clip->id.flag & LIB_NEEDLINK) { + MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *object; + if (clip->adt) lib_link_animdata(fd, &clip->id, clip->adt); clip->gpd = newlibadr_us(fd, clip->id.lib, clip->gpd); + lib_link_movieTracks(fd, clip, &tracking->tracks); + + for (object = tracking->objects.first; object; object = object->next) { + lib_link_movieTracks(fd, clip, &object->tracks); + } + clip->id.flag -= LIB_NEEDLINK; } } } +/* ***************** READ MOVIECLIP *************** */ + +static void direct_link_mask(FileData *fd, Mask *mask) +{ + MaskLayer *masklay; + + mask->adt = newdataadr(fd, mask->adt); + + link_list(fd, &mask->masklayers); + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + MaskLayerShape *masklay_shape; + + link_list(fd, &masklay->splines); + + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + + spline->points = newdataadr(fd, spline->points); + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (point->tot_uw) + point->uw = newdataadr(fd, point->uw); + } + } + + link_list(fd, &masklay->splines_shapes); + + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { + masklay_shape->data = newdataadr(fd, masklay_shape->data); + } + + masklay->act_spline = newdataadr(fd, masklay->act_spline); + masklay->act_point = newdataadr(fd, masklay->act_point); + } +} + +static void lib_link_mask_parent(FileData *fd, Mask *mask, MaskParent *parent) +{ + parent->id = newlibadr_us(fd, mask->id.lib, parent->id); +} + +static void lib_link_mask(FileData *fd, Main *main) +{ + Mask *mask; + + mask = main->mask.first; + while (mask) { + if (mask->id.flag & LIB_NEEDLINK) { + MaskLayer *masklay; + + if (mask->adt) + lib_link_animdata(fd, &mask->id, mask->adt); + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + spline = masklay->splines.first; + while (spline) { + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + lib_link_mask_parent(fd, mask, &point->parent); + } + + lib_link_mask_parent(fd, mask, &spline->parent); + + spline = spline->next; + } + } + + mask->id.flag -= LIB_NEEDLINK; + } + mask = mask->id.next; + } +} + /* ************ READ LINE STYLE ***************** */ static void lib_link_linestyle(FileData *fd, Main *main) @@ -6565,6 +6672,9 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID case ID_MC: direct_link_movieclip(fd, (MovieClip *)id); break; + case ID_MSK: + direct_link_mask(fd, (Mask *)id); + break; case ID_LS: direct_link_linestyle(fd, (FreestyleLineStyle *)id); break; @@ -6826,6 +6936,11 @@ static void do_versions_nodetree_multi_file_output_format_2_62_1(Scene *sce, bNo char basepath[FILE_MAXDIR]; char filename[FILE_MAXFILE]; + /* ugly, need to remove the old inputs list to avoid bad pointer checks when adding new sockets. + * sock->storage is expected to contain path info in ntreeCompositOutputFileAddSocket. + */ + node->inputs.first = node->inputs.last = NULL; + node->storage = nimf; /* split off filename from the old path, to be used as socket sub-path */ @@ -6999,6 +7114,22 @@ static void do_versions_nodetree_frame_2_64_6(bNodeTree *ntree) } } +static void do_version_ntree_image_user_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) +{ + bNode *node; + + for (node = ntree->nodes.first; node; node = node->next) { + if (ELEM(node->type, SH_NODE_TEX_IMAGE, SH_NODE_TEX_ENVIRONMENT)) { + NodeTexImage *tex = node->storage; + + tex->iuser.frames= 1; + tex->iuser.sfra= 1; + tex->iuser.fie_ima= 2; + tex->iuser.ok= 1; + } + } +} + static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -7143,12 +7274,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main) track = clip->tracking.tracks.first; while (track) { - if (track->pyramid_levels == 0) - track->pyramid_levels = 2; - if (track->minimum_correlation == 0.0f) track->minimum_correlation = 0.75f; - + track = track->next; } } @@ -7166,10 +7294,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main) for (clip= main->movieclip.first; clip; clip= clip->id.next) { MovieTrackingSettings *settings= &clip->tracking.settings; - - if (settings->default_pyramid_levels == 0) { - settings->default_tracker= TRACKER_KLT; - settings->default_pyramid_levels = 2; + + if (settings->default_pattern_size == 0.0f) { + settings->default_motion_model = TRACK_MOTION_MODEL_TRANSLATION; settings->default_minimum_correlation = 0.75; settings->default_pattern_size = 11; settings->default_search_size = 51; @@ -7696,7 +7823,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } } - + + if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 8)) { /* set new deactivation values for game settings */ @@ -7710,6 +7838,97 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 9)) { + bNodeTreeType *ntreetype = ntreeGetType(NTREE_SHADER); + + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, do_version_ntree_image_user_264); + } + + if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 10)) { + { + Scene *scene; + // composite redesign + for (scene=main->scene.first; scene; scene=scene->id.next) { + if (scene->nodetree) { + if (scene->nodetree->chunksize == 0) { + scene->nodetree->chunksize = 256; + } + } + } + } + + { + bScreen *sc; + + for (sc = main->screen.first; sc; sc = sc->id.next) { + ScrArea *sa; + + for (sa = sc->areabase.first; sa; sa = sa->next) { + SpaceLink *sl; + + for (sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_CLIP) { + SpaceClip *sclip = (SpaceClip *)sl; + + if (sclip->around == 0) { + sclip->around = V3D_CENTROID; + } + } + } + } + } + } + + { + MovieClip *clip; + + for (clip = main->movieclip.first; clip; clip = clip->id.next) { + clip->start_frame = 1; + } + } + } + + if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 11)) { + MovieClip *clip; + + for (clip = main->movieclip.first; clip; clip = clip->id.next) { + MovieTrackingTrack *track; + + track = clip->tracking.tracks.first; + while (track) { + int i; + + for (i = 0; i < track->markersnr; i++) { + MovieTrackingMarker *marker = &track->markers[i]; + + if (is_zero_v2(marker->pattern_corners[0]) && is_zero_v2(marker->pattern_corners[1]) && + is_zero_v2(marker->pattern_corners[3]) && is_zero_v2(marker->pattern_corners[3])) + { + marker->pattern_corners[0][0] = track->pat_min[0]; + marker->pattern_corners[0][1] = track->pat_min[1]; + + marker->pattern_corners[1][0] = track->pat_max[0]; + marker->pattern_corners[1][1] = track->pat_min[1]; + + marker->pattern_corners[2][0] = track->pat_max[0]; + marker->pattern_corners[2][1] = track->pat_max[1]; + + marker->pattern_corners[3][0] = track->pat_min[0]; + marker->pattern_corners[3][1] = track->pat_max[1]; + } + + if (is_zero_v2(marker->search_min) && is_zero_v2(marker->search_max)) { + copy_v2_v2(marker->search_min, track->search_min); + copy_v2_v2(marker->search_max, track->search_max); + } + } + + track = track->next; + } + } + } + /* default values in Freestyle settings */ { Scene *sce; @@ -7739,21 +7958,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main) linestyle->rounds= 3; } } - + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ - { - Scene *scene; - // composite redesign - for (scene=main->scene.first; scene; scene=scene->id.next) { - if (scene->nodetree) { - if (scene->nodetree->chunksize == 0) { - scene->nodetree->chunksize = 256; - } - } - } - } - + /* don't forget to set version number in blender.c! */ } @@ -7796,8 +8004,9 @@ static void lib_link_all(FileData *fd, Main *main) lib_link_brush(fd, main); lib_link_particlesettings(fd, main); lib_link_movieclip(fd, main); + lib_link_mask(fd, main); lib_link_linestyle(fd, main); - + lib_link_mesh(fd, main); /* as last: tpage images with users at zero */ lib_link_library(fd, main); /* only init users */ @@ -8079,10 +8288,17 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old) /* Update: the issue is that in file reading, the oldnewmap is OK, but for existing data, it has to be * inserted in the map to be found! */ - if (id->flag & LIB_PRE_EXISTING) - oldnewmap_insert(fd->libmap, bhead->old, id, 1); - + + /* Update: previously it was checking for id->flag & LIB_PRE_EXISTING, however that does not affect file + * reading. For file reading we may need to insert it into the libmap as well, because you might have + * two files indirectly linking the same datablock, and in that case we need this in the libmap for the + * fd of both those files. + * + * The crash that this check avoided earlier was because bhead->code wasn't properly passed in, making + * change_idid_adr not detect the mapping was for an ID_ID datablock. */ + oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code); change_idid_adr_fd(fd, bhead->old, id); + // commented because this can print way too much // if (G.debug & G_DEBUG) printf("expand_doit: already linked: %s lib: %s\n", id->name, lib->name); } @@ -8098,7 +8314,7 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old) else { /* this is actually only needed on UI call? when ID was already read before, and another append * happens which invokes same ID... in that case the lookup table needs this entry */ - oldnewmap_insert(fd->libmap, bhead->old, id, 1); + oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code); // commented because this can print way too much // if (G.debug & G_DEBUG) printf("expand: already read %s\n", id->name); } @@ -8516,7 +8732,7 @@ static void expand_armature(FileData *fd, Main *mainvar, bArmature *arm) } static void expand_object_expandModifiers(void *userData, Object *UNUSED(ob), - ID **idpoin) + ID **idpoin) { struct { FileData *fd; Main *mainvar; } *data= userData; @@ -9012,7 +9228,7 @@ static ID *append_named_part(Main *mainl, FileData *fd, const char *idname, cons else { /* already linked */ printf("append: already linked\n"); - oldnewmap_insert(fd->libmap, bhead->old, id, 1); + oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code); if (id->flag & LIB_INDIRECT) { id->flag -= LIB_INDIRECT; id->flag |= LIB_EXTERN; diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index 620d15993a1..5ed39ad5307 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -744,7 +744,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) if (scene->ed && scene->ed->seqbasep) { SEQ_BEGIN (scene->ed, seq) { - if (seq->type == SEQ_HD_SOUND) { + if (seq->type == SEQ_TYPE_SOUND_HD) { char str[FILE_MAX]; BLI_join_dirfile(str, sizeof(str), seq->strip->dir, seq->strip->stripdata->name); BLI_path_abs(str, main->name); diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c index 7b314c31488..46ef2716ade 100644 --- a/source/blender/blenloader/intern/versioning_legacy.c +++ b/source/blender/blenloader/intern/versioning_legacy.c @@ -1842,7 +1842,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) if (ed) { SEQ_BEGIN (sce->ed, seq) { - if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) + if (seq->type == SEQ_TYPE_IMAGE || seq->type == SEQ_TYPE_MOVIE) seq->flag |= SEQ_MAKE_PREMUL; } SEQ_END diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index beaf36421c5..332a00f9440 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -134,6 +134,7 @@ Any case: direct data is ALWAYS after the lib block #include "DNA_world_types.h" #include "DNA_windowmanager_types.h" #include "DNA_movieclip_types.h" +#include "DNA_mask_types.h" #include "MEM_guardedalloc.h" // MEM_freeN #include "BLI_bitmap.h" @@ -2155,19 +2156,19 @@ static void write_scenes(WriteData *wd, ListBase *scebase) if (seq->effectdata) { switch (seq->type) { - case SEQ_COLOR: + case SEQ_TYPE_COLOR: writestruct(wd, DATA, "SolidColorVars", 1, seq->effectdata); break; - case SEQ_SPEED: + case SEQ_TYPE_SPEED: writestruct(wd, DATA, "SpeedControlVars", 1, seq->effectdata); break; - case SEQ_WIPE: + case SEQ_TYPE_WIPE: writestruct(wd, DATA, "WipeVars", 1, seq->effectdata); break; - case SEQ_GLOW: + case SEQ_TYPE_GLOW: writestruct(wd, DATA, "GlowVars", 1, seq->effectdata); break; - case SEQ_TRANSFORM: + case SEQ_TYPE_TRANSFORM: writestruct(wd, DATA, "TransformVars", 1, seq->effectdata); break; } @@ -2187,9 +2188,9 @@ static void write_scenes(WriteData *wd, ListBase *scebase) if (seq->flag & SEQ_USE_COLOR_BALANCE && strip->color_balance) { writestruct(wd, DATA, "StripColorBalance", 1, strip->color_balance); } - if (seq->type==SEQ_IMAGE) + if (seq->type==SEQ_TYPE_IMAGE) writestruct(wd, DATA, "StripElem", MEM_allocN_len(strip->stripdata) / sizeof(struct StripElem), strip->stripdata); - else if (seq->type==SEQ_MOVIE || seq->type==SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) + else if (seq->type==SEQ_TYPE_MOVIE || seq->type==SEQ_TYPE_SOUND_RAM || seq->type == SEQ_TYPE_SOUND_HD) writestruct(wd, DATA, "StripElem", 1, strip->stripdata); strip->done = TRUE; @@ -2765,6 +2766,59 @@ static void write_movieclips(WriteData *wd, ListBase *idbase) mywrite(wd, MYWRITE_FLUSH, 0); } +static void write_masks(WriteData *wd, ListBase *idbase) +{ + Mask *mask; + + mask = idbase->first; + while (mask) { + if (mask->id.us > 0 || wd->current) { + MaskLayer *masklay; + + writestruct(wd, ID_MSK, "Mask", 1, mask); + + if (mask->adt) + write_animdata(wd, mask->adt); + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + MaskLayerShape *masklay_shape; + + writestruct(wd, DATA, "MaskLayer", 1, masklay); + + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + + void *points_deform = spline->points_deform; + spline->points_deform = NULL; + + writestruct(wd, DATA, "MaskSpline", 1, spline); + writestruct(wd, DATA, "MaskSplinePoint", spline->tot_point, spline->points); + + spline->points_deform = points_deform; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (point->tot_uw) + writestruct(wd, DATA, "MaskSplinePointUW", point->tot_uw, point->uw); + } + } + + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { + writestruct(wd, DATA, "MaskLayerShape", 1, masklay_shape); + writedata(wd, DATA, masklay_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, masklay_shape->data); + } + } + } + + mask = mask->id.next; + } + + /* flush helps the compression for undo-save */ + mywrite(wd, MYWRITE_FLUSH, 0); +} + static void write_linestyle_color_modifiers(WriteData *wd, ListBase *modifiers) { LineStyleModifier *m; @@ -3048,6 +3102,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil write_screens (wd, &mainvar->screen); } write_movieclips (wd, &mainvar->movieclip); + write_masks (wd, &mainvar->mask); write_scenes (wd, &mainvar->scene); write_curves (wd, &mainvar->curve); write_mballs (wd, &mainvar->mball); diff --git a/source/blender/bmesh/intern/bmesh_marking.h b/source/blender/bmesh/intern/bmesh_marking.h index 12ebaedac60..406971652dc 100644 --- a/source/blender/bmesh/intern/bmesh_marking.h +++ b/source/blender/bmesh/intern/bmesh_marking.h @@ -27,8 +27,7 @@ * \ingroup bmesh */ -typedef struct BMEditSelection -{ +typedef struct BMEditSelection { struct BMEditSelection *next, *prev; BMElem *ele; char htype; @@ -82,7 +81,7 @@ void BM_editselection_plane(BMEditSelection *ese, float r_plane[3]); #define BM_select_history_store_notest(bm, ele) _bm_select_history_store_notest(bm, &(ele)->head) #define BM_select_history_store(bm, ele) _bm_select_history_store(bm, &(ele)->head) -int _bm_select_history_check(BMesh *bm, const BMHeader *ele); +int _bm_select_history_check(BMesh *bm, const BMHeader *ele); int _bm_select_history_remove(BMesh *bm, BMHeader *ele); void _bm_select_history_store_notest(BMesh *bm, BMHeader *ele); void _bm_select_history_store(BMesh *bm, BMHeader *ele); diff --git a/source/blender/bmesh/operators/bmo_mesh_conv.c b/source/blender/bmesh/operators/bmo_mesh_conv.c index 4578270d571..c550a17e696 100644 --- a/source/blender/bmesh/operators/bmo_mesh_conv.c +++ b/source/blender/bmesh/operators/bmo_mesh_conv.c @@ -20,7 +20,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/bmesh/operators/bmesh_mesh_conv.c +/** \file blender/bmesh/operators/bmo_mesh_conv.c * \ingroup bmesh * * This file contains functions diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c index e53144bd597..0903620f9a0 100644 --- a/source/blender/bmesh/operators/bmo_triangulate.c +++ b/source/blender/bmesh/operators/bmo_triangulate.c @@ -20,7 +20,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/bmesh/operators/bmo_subdivide.c +/** \file blender/bmesh/operators/bmo_triangulate.c * \ingroup bmesh */ diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index 13f24863aa3..1ec4d4ab6d4 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -20,7 +20,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/bmesh/operators/bmo_subdivide.c +/** \file blender/bmesh/operators/bmo_utils.c * \ingroup bmesh * * utility bmesh operators, e.g. transform, diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp index 195057817dd..45d7d4a7684 100644 --- a/source/blender/collada/AnimationImporter.cpp +++ b/source/blender/collada/AnimationImporter.cpp @@ -804,7 +804,7 @@ void AnimationImporter::translate_Animations ( COLLADAFW::Node * node, bool is_joint = node->getType() == COLLADAFW::Node::JOINT; COLLADAFW::Node *root = root_map.find(node->getUniqueId()) == root_map.end() ? node : root_map[node->getUniqueId()]; - Object *ob = is_joint ? armature_importer->get_armature_for_joint(root) : object_map.find(node->getUniqueId())->second; + Object *ob = is_joint ? armature_importer->get_armature_for_joint(root) : object_map.find(node->getUniqueId())->second; if (!ob) { fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str()); return; diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp index 9d59be39f33..107a3fc5796 100644 --- a/source/blender/collada/ArmatureExporter.cpp +++ b/source/blender/collada/ArmatureExporter.cpp @@ -37,6 +37,14 @@ #include "BKE_action.h" #include "BKE_armature.h" + +extern "C" { +#include "BKE_main.h" +#include "BKE_mesh.h" +#include "BKE_global.h" +#include "BKE_library.h" +} + #include "ED_armature.h" #include "BLI_listbase.h" @@ -45,6 +53,8 @@ #include "ArmatureExporter.h" #include "SceneExporter.h" +#include "collada_utils.h" + // XXX exporter writes wrong data for shared armatures. A separate // controller should be written for each armature-mesh binding how do // we make controller ids then? @@ -66,12 +76,12 @@ void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene* sce, bool ArmatureExporter::is_skinned_mesh(Object *ob) { - return get_assigned_armature(ob) != NULL; + return bc_get_assigned_armature(ob) != NULL; } -void ArmatureExporter::add_instance_controller(Object *ob) +bool ArmatureExporter::add_instance_controller(Object *ob) { - Object *ob_arm = get_assigned_armature(ob); + Object *ob_arm = bc_get_assigned_armature(ob); bArmature *arm = (bArmature*)ob_arm->data; const std::string& controller_id = get_controller_id(ob_arm, ob); @@ -79,6 +89,9 @@ void ArmatureExporter::add_instance_controller(Object *ob) COLLADASW::InstanceController ins(mSW); ins.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, controller_id)); + Mesh *me = (Mesh *)ob->data; + if (!me->dvert) return false; + // write root bone URLs Bone *bone; for (bone = (Bone*)arm->bonebase.first; bone; bone = bone->next) { @@ -89,6 +102,7 @@ void ArmatureExporter::add_instance_controller(Object *ob) InstanceWriter::add_material_bindings(ins.getBindMaterial(), ob); ins.add(); + return true; } void ArmatureExporter::export_controllers(Scene *sce) @@ -105,7 +119,7 @@ void ArmatureExporter::export_controllers(Scene *sce) void ArmatureExporter::operator()(Object *ob) { - Object *ob_arm = get_assigned_armature(ob); + Object *ob_arm = bc_get_assigned_armature(ob); if (ob_arm /*&& !already_written(ob_arm)*/) export_controller(ob, ob_arm); @@ -139,27 +153,6 @@ void ArmatureExporter::find_objects_using_armature(Object *ob_arm, std::vector<O } #endif -Object *ArmatureExporter::get_assigned_armature(Object *ob) -{ - Object *ob_arm = NULL; - - if (ob->parent && ob->partype == PARSKEL && ob->parent->type == OB_ARMATURE) { - ob_arm = ob->parent; - } - else { - ModifierData *mod = (ModifierData*)ob->modifiers.first; - while (mod) { - if (mod->type == eModifierType_Armature) { - ob_arm = ((ArmatureModifierData*)mod)->object; - } - - mod = mod->next; - } - } - - return ob_arm; -} - std::string ArmatureExporter::get_joint_sid(Bone *bone, Object *ob_arm) { return get_joint_id(bone, ob_arm); @@ -325,7 +318,16 @@ void ArmatureExporter::export_controller(Object* ob, Object *ob_arm) */ bool use_instantiation = this->export_settings->use_object_instantiation; - Mesh *me = (Mesh*)ob->data; + Mesh *me; + + if ( this->export_settings->apply_modifiers ) { + me = bc_to_mesh_apply_modifiers(scene, ob); + } + else { + me = (Mesh*)ob->data; + } + BKE_mesh_tessface_ensure(me); + if (!me->dvert) return; std::string controller_name = id_name(ob_arm); @@ -393,6 +395,10 @@ void ArmatureExporter::export_controller(Object* ob, Object *ob_arm) add_joints_element(&ob->defbase, joints_source_id, inv_bind_mat_source_id); add_vertex_weights_element(weights_source_id, joints_source_id, vcounts, joints); + if (this->export_settings->apply_modifiers) + { + BKE_libblock_free_us(&(G.main->mesh), me); + } closeSkin(); closeController(); } diff --git a/source/blender/collada/ArmatureExporter.h b/source/blender/collada/ArmatureExporter.h index e9ee38d36cf..beef77af767 100644 --- a/source/blender/collada/ArmatureExporter.h +++ b/source/blender/collada/ArmatureExporter.h @@ -64,7 +64,7 @@ public: bool is_skinned_mesh(Object *ob); - void add_instance_controller(Object *ob); + bool add_instance_controller(Object *ob); void export_controllers(Scene *sce); @@ -85,8 +85,6 @@ private: void find_objects_using_armature(Object *ob_arm, std::vector<Object *>& objects, Scene *sce); #endif - Object *get_assigned_armature(Object *ob); - std::string get_joint_sid(Bone *bone, Object *ob_arm); // Scene, SceneExporter and the list of child_objects diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index 19fc30a2790..69f302eaec7 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -262,8 +262,10 @@ void DocumentExporter::exportCurrentScene(Scene *sce) // <library_controllers> ArmatureExporter arm_exporter(&sw, this->export_settings); - if (has_object_type(sce, OB_ARMATURE)) { - arm_exporter.export_controllers(sce); + if (this->export_settings->include_armatures) { + if (has_object_type(sce, OB_ARMATURE)) { + arm_exporter.export_controllers(sce); + } } // <library_visual_scenes> diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h index f0d3f810831..a6ae29bf2b2 100644 --- a/source/blender/collada/ExportSettings.h +++ b/source/blender/collada/ExportSettings.h @@ -32,6 +32,7 @@ struct ExportSettings public: bool selected; bool apply_modifiers; + bool include_armatures; bool include_bone_children; bool use_object_instantiation; bool second_life; diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index 6df16165e4b..53d7f1e6449 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -49,6 +49,7 @@ extern "C" { #include "BKE_material.h" #include "BKE_mesh.h" #include "collada_internal.h" +#include "collada_utils.h" // TODO: optimize UV sets by making indexed list with duplicates removed GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryGeometries(sw), export_settings(export_settings) {} @@ -65,25 +66,6 @@ void GeometryExporter::exportGeom(Scene *sce) closeLibrary(); } -Mesh * GeometryExporter::get_mesh(Object *ob, int apply_modifiers) -{ - Mesh *tmpmesh; - if (!apply_modifiers) - { - tmpmesh = (Mesh*)ob->data; - } - else - { - CustomDataMask mask = CD_MASK_MESH; - DerivedMesh *dm = mesh_create_derived_view(mScene, ob, mask); - tmpmesh = BKE_mesh_add("ColladaMesh"); // name is not important here - DM_to_mesh(dm, tmpmesh, ob); - dm->release(dm); - } - BKE_mesh_tessface_ensure(tmpmesh); - return tmpmesh; -} - void GeometryExporter::operator()(Object *ob) { // XXX don't use DerivedMesh, Mesh instead? @@ -93,7 +75,14 @@ void GeometryExporter::operator()(Object *ob) #endif bool use_instantiation = this->export_settings->use_object_instantiation; - Mesh *me = get_mesh(ob, this->export_settings->apply_modifiers); + Mesh *me; + if ( this->export_settings->apply_modifiers ) { + me = bc_to_mesh_apply_modifiers(mScene, ob); + } + else { + me = (Mesh*)ob->data; + } + BKE_mesh_tessface_ensure(me); std::string geom_id = get_geometry_id(ob, use_instantiation); std::vector<Normal> nor; diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h index aae095e819e..23cdcc0a5ba 100644 --- a/source/blender/collada/GeometryExporter.h +++ b/source/blender/collada/GeometryExporter.h @@ -105,7 +105,7 @@ private: const ExportSettings *export_settings; - Mesh * get_mesh(Object *ob, int apply_modifiers); + Mesh * get_mesh(Scene *sce, Object *ob, int apply_modifiers); }; struct GeometryFunctor { diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp index d258f4ef5e1..510107272cd 100644 --- a/source/blender/collada/SceneExporter.cpp +++ b/source/blender/collada/SceneExporter.cpp @@ -25,6 +25,7 @@ */ #include "SceneExporter.h" +#include "collada_utils.h" SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings) : COLLADASW::LibraryVisualScenes(sw), arm_exporter(arm), export_settings(export_settings) @@ -40,19 +41,36 @@ void SceneExporter::exportScene(Scene *sce) closeLibrary(); } +// Returns true if the parent chain does not contain any selected object +// Otherwise return false (ob has selected predecessor) +bool is_exported_base_node(Object *ob, bool selection_only) { + + if (selection_only && ob->flag & SELECT) { + // Move up towards root object, + // stop at first selected predecessor's child, + // or at root, if no parent was selected + while (ob->parent && (ob->parent->type==OB_ARMATURE || !(ob->parent->flag & SELECT))) + { + ob = ob->parent; + } + } + + return !ob->parent; +} + void SceneExporter::exportHierarchy(Scene *sce) { Base *base= (Base*) sce->base.first; while (base) { Object *ob = base->object; - if (!ob->parent) { + bool is_export_base_node = is_exported_base_node(ob, this->export_settings->selected); + if (is_export_base_node) { if (sce->lay & ob->lay) { switch (ob->type) { case OB_MESH: case OB_CAMERA: case OB_LAMP: - case OB_ARMATURE: case OB_EMPTY: if (this->export_settings->selected && !(ob->flag & SELECT)) { break; @@ -70,6 +88,14 @@ void SceneExporter::exportHierarchy(Scene *sce) void SceneExporter::writeNodes(Object *ob, Scene *sce) { + + // Add associated armature first if available + if (this->export_settings->include_armatures) { + Object *ob_arm = bc_get_assigned_armature(ob); + if(ob_arm != NULL) + writeNodes(ob_arm, sce); + } + COLLADASW::Node node(mSW); node.setNodeId(translate_id(id_name(ob))); node.setNodeName(translate_id(id_name(ob))); @@ -80,8 +106,19 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) bool is_skinned_mesh = arm_exporter->is_skinned_mesh(ob); std::list<Object*> child_objects; + // XXX Not sure about this. + // For me this looks more like a very special case for a very special purpose. + // Wouldn't it be better to have only one option here ? + // + // - include children + // + // Instead of "include_bone_children" ? + // then we could just ask: + // if (this->export_settings->include_children) + // ... + if (this->export_settings->include_armatures + && this->export_settings->include_bone_children) { - if (this->export_settings->include_bone_children) { // list child objects Base *b = (Base*) sce->base.first; while (b) { @@ -105,7 +142,7 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) } - if (ob->type == OB_MESH && is_skinned_mesh) + if (ob->type == OB_MESH && this->export_settings->include_armatures && is_skinned_mesh) // for skinned mesh we write obmat in <bind_shape_matrix> TransformWriter::add_node_transform_identity(node); else @@ -113,10 +150,11 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) // <instance_geometry> if (ob->type == OB_MESH) { - if (is_skinned_mesh) { - arm_exporter->add_instance_controller(ob); + bool instance_controller_created = false; + if (this->export_settings->include_armatures && is_skinned_mesh) { + instance_controller_created = arm_exporter->add_instance_controller(ob); } - else { + if (!instance_controller_created){ COLLADASW::InstanceGeometry instGeom(mSW); instGeom.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, this->export_settings->use_object_instantiation))); diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp index 951fecec049..e880082c9ec 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -54,14 +54,18 @@ extern "C" const char *filepath, int selected, int apply_modifiers, + + int include_armatures, int include_bone_children, + int use_object_instantiation, - int second_life) + int second_life ) { ExportSettings export_settings; export_settings.selected = selected != 0; export_settings.apply_modifiers = apply_modifiers != 0; + export_settings.include_armatures = include_armatures != 0; export_settings.include_bone_children = include_bone_children != 0; export_settings.second_life = second_life != 0; export_settings.use_object_instantiation = use_object_instantiation != 0; diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h index 67aaf1ff6c7..646c8469e6b 100644 --- a/source/blender/collada/collada.h +++ b/source/blender/collada/collada.h @@ -38,13 +38,17 @@ extern "C" { */ int collada_import(bContext *C, const char *filepath); int collada_export( - Scene *sce, + Scene *sce, const char *filepath, int selected, int apply_modifiers, + + int include_armatures, int include_bone_children, + int use_object_instantiation, int second_life); + #ifdef __cplusplus } #endif diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index 8b7a28e5fbe..8693441d7c8 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -32,8 +32,10 @@ #include "COLLADAFWMeshPrimitive.h" #include "COLLADAFWMeshVertexData.h" +#include "DNA_modifier_types.h" #include "DNA_customdata_types.h" #include "DNA_object_types.h" +#include "DNA_mesh_types.h" #include "DNA_scene_types.h" #include "BLI_math.h" @@ -42,8 +44,13 @@ #include "BKE_customdata.h" #include "BKE_depsgraph.h" #include "BKE_object.h" +#include "BKE_mesh.h" #include "BKE_scene.h" +extern "C" { +#include "BKE_DerivedMesh.h" +} + #include "WM_api.h" // XXX hrm, see if we can do without this #include "WM_types.h" @@ -125,3 +132,35 @@ Object *bc_add_object(Scene *scene, int type, const char *name) return ob; } +Mesh *bc_to_mesh_apply_modifiers(Scene *scene, Object *ob) +{ + Mesh *tmpmesh; + CustomDataMask mask = CD_MASK_MESH; + DerivedMesh *dm = mesh_create_derived_view(scene, ob, mask); + tmpmesh = BKE_mesh_add("ColladaMesh"); // name is not important here + DM_to_mesh(dm, tmpmesh, ob); + dm->release(dm); + return tmpmesh; +} + +Object *bc_get_assigned_armature(Object *ob) +{ + Object *ob_arm = NULL; + + if (ob->parent && ob->partype == PARSKEL && ob->parent->type == OB_ARMATURE) { + ob_arm = ob->parent; + } + else { + ModifierData *mod = (ModifierData*)ob->modifiers.first; + while (mod) { + if (mod->type == eModifierType_Armature) { + ob_arm = ((ArmatureModifierData*)mod)->object; + } + + mod = mod->next; + } + } + + return ob_arm; +} + diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h index 1f5d2b1d8da..9882b44d94c 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -36,6 +36,7 @@ #include <map> #include "DNA_object_types.h" +#include "DNA_mesh_types.h" #include "DNA_customdata_types.h" #include "DNA_texture_types.h" #include "BKE_context.h" @@ -50,5 +51,7 @@ extern int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_sp extern char *bc_CustomData_get_layer_name(const CustomData *data, int type, int n); extern char *bc_CustomData_get_active_layer_name(const CustomData *data, int type); extern Object *bc_add_object(Scene *scene, int type, const char *name); +extern Mesh *bc_to_mesh_apply_modifiers(Scene *scene, Object *ob); +extern Object *bc_get_assigned_armature(Object *ob); #endif diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index dc28328e867..22f72270734 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -26,24 +26,24 @@ set(INC . + intern + nodes + operations ../blenkernel ../blenlib + ../blenlib + ../blenloader + ../imbuf ../makesdna - ../render/extern/include - ../render/intern/include ../makesrna - ../blenloader - ../blenlib + ../opencl ../windowmanager - ../imbuf - ../../../intern/guardedalloc - nodes - ../nodes/ + ../nodes ../nodes/composite ../nodes/intern - intern - operations - ../opencl + ../render/extern/include + ../render/intern/include + ../../../intern/guardedalloc ) set(SRC @@ -100,7 +100,7 @@ set(SRC operations/COM_QualityStepHelper.h operations/COM_QualityStepHelper.cpp -# Internal nodes + # Internal nodes nodes/COM_MuteNode.cpp nodes/COM_MuteNode.h nodes/COM_GroupNode.cpp @@ -108,7 +108,7 @@ set(SRC nodes/COM_SocketProxyNode.cpp nodes/COM_SocketProxyNode.h -# input nodes + # input nodes nodes/COM_RenderLayersNode.cpp nodes/COM_RenderLayersNode.h nodes/COM_ImageNode.cpp @@ -129,8 +129,10 @@ set(SRC nodes/COM_MovieClipNode.h nodes/COM_OutputFileNode.cpp nodes/COM_OutputFileNode.h + nodes/COM_MaskNode.cpp + nodes/COM_MaskNode.h -# output nodes + # output nodes nodes/COM_CompositorNode.cpp nodes/COM_CompositorNode.h nodes/COM_ViewerNode.cpp @@ -144,7 +146,7 @@ set(SRC operations/COM_CalculateMeanOperation.cpp operations/COM_CalculateMeanOperation.h -# distort nodes + # distort nodes nodes/COM_TranslateNode.cpp nodes/COM_TranslateNode.h nodes/COM_ScaleNode.cpp @@ -191,27 +193,27 @@ set(SRC nodes/COM_DefocusNode.cpp nodes/COM_DefocusNode.h -# color nodes - nodes/COM_VectorCurveNode.cpp - nodes/COM_VectorCurveNode.h - nodes/COM_ColorCurveNode.cpp - nodes/COM_ColorCurveNode.h - nodes/COM_ColorToBWNode.cpp - nodes/COM_ColorToBWNode.h - nodes/COM_ColorRampNode.cpp - nodes/COM_ColorRampNode.h - nodes/COM_MixNode.cpp - nodes/COM_MixNode.h - nodes/COM_AlphaOverNode.cpp - nodes/COM_AlphaOverNode.h - nodes/COM_ZCombineNode.cpp - nodes/COM_ZCombineNode.h - nodes/COM_BrightnessNode.cpp - nodes/COM_BrightnessNode.h - nodes/COM_ColorBalanceNode.cpp - nodes/COM_ColorBalanceNode.h - nodes/COM_InvertNode.cpp - nodes/COM_InvertNode.h + # color nodes + nodes/COM_VectorCurveNode.cpp + nodes/COM_VectorCurveNode.h + nodes/COM_ColorCurveNode.cpp + nodes/COM_ColorCurveNode.h + nodes/COM_ColorToBWNode.cpp + nodes/COM_ColorToBWNode.h + nodes/COM_ColorRampNode.cpp + nodes/COM_ColorRampNode.h + nodes/COM_MixNode.cpp + nodes/COM_MixNode.h + nodes/COM_AlphaOverNode.cpp + nodes/COM_AlphaOverNode.h + nodes/COM_ZCombineNode.cpp + nodes/COM_ZCombineNode.h + nodes/COM_BrightnessNode.cpp + nodes/COM_BrightnessNode.h + nodes/COM_ColorBalanceNode.cpp + nodes/COM_ColorBalanceNode.h + nodes/COM_InvertNode.cpp + nodes/COM_InvertNode.h nodes/COM_GammaNode.cpp nodes/COM_GammaNode.h nodes/COM_SetAlphaNode.cpp @@ -231,25 +233,25 @@ set(SRC operations/COM_TonemapOperation.cpp operations/COM_TonemapOperation.h -# converter nodes - nodes/COM_IDMaskNode.cpp - nodes/COM_IDMaskNode.h - nodes/COM_SeparateRGBANode.cpp - nodes/COM_SeparateRGBANode.h - nodes/COM_CombineRGBANode.cpp - nodes/COM_CombineRGBANode.h - nodes/COM_SeparateHSVANode.cpp - nodes/COM_SeparateHSVANode.h - nodes/COM_CombineHSVANode.cpp - nodes/COM_CombineHSVANode.h - nodes/COM_SeparateYUVANode.cpp - nodes/COM_SeparateYUVANode.h - nodes/COM_CombineYUVANode.cpp - nodes/COM_CombineYUVANode.h - nodes/COM_SeparateYCCANode.cpp - nodes/COM_SeparateYCCANode.h - nodes/COM_CombineYCCANode.cpp - nodes/COM_CombineYCCANode.h + # converter nodes + nodes/COM_IDMaskNode.cpp + nodes/COM_IDMaskNode.h + nodes/COM_SeparateRGBANode.cpp + nodes/COM_SeparateRGBANode.h + nodes/COM_CombineRGBANode.cpp + nodes/COM_CombineRGBANode.h + nodes/COM_SeparateHSVANode.cpp + nodes/COM_SeparateHSVANode.h + nodes/COM_CombineHSVANode.cpp + nodes/COM_CombineHSVANode.h + nodes/COM_SeparateYUVANode.cpp + nodes/COM_SeparateYUVANode.h + nodes/COM_CombineYUVANode.cpp + nodes/COM_CombineYUVANode.h + nodes/COM_SeparateYCCANode.cpp + nodes/COM_SeparateYCCANode.h + nodes/COM_CombineYCCANode.cpp + nodes/COM_CombineYCCANode.h nodes/COM_NormalNode.cpp nodes/COM_NormalNode.h @@ -263,7 +265,7 @@ set(SRC operations/COM_NormalizeOperation.cpp operations/COM_NormalizeOperation.h -# Filter nodes + # Filter nodes nodes/COM_BilateralBlurNode.cpp nodes/COM_BilateralBlurNode.h operations/COM_BilateralBlurOperation.cpp @@ -273,12 +275,10 @@ set(SRC operations/COM_VectorBlurOperation.cpp operations/COM_VectorBlurOperation.h - - - nodes/COM_FilterNode.cpp - nodes/COM_FilterNode.h - nodes/COM_DilateErodeNode.cpp - nodes/COM_DilateErodeNode.h + nodes/COM_FilterNode.cpp + nodes/COM_FilterNode.h + nodes/COM_DilateErodeNode.cpp + nodes/COM_DilateErodeNode.h nodes/COM_BlurNode.cpp nodes/COM_BlurNode.h nodes/COM_BokehBlurNode.cpp @@ -308,7 +308,7 @@ set(SRC operations/COM_GammaCorrectOperation.h operations/COM_GammaCorrectOperation.cpp -# Matte nodes + # Matte nodes nodes/COM_BoxMaskNode.cpp nodes/COM_BoxMaskNode.h nodes/COM_EllipseMaskNode.cpp @@ -320,50 +320,50 @@ set(SRC operations/COM_DoubleEdgeMaskOperation.cpp operations/COM_DoubleEdgeMaskOperation.h -operations/COM_ColorSpillOperation.cpp -operations/COM_ColorSpillOperation.h - operations/COM_RenderLayersBaseProg.cpp - operations/COM_RenderLayersBaseProg.h - operations/COM_RenderLayersImageProg.cpp - operations/COM_RenderLayersImageProg.h - operations/COM_RenderLayersAlphaProg.cpp - operations/COM_RenderLayersAlphaProg.h - operations/COM_RenderLayersDepthProg.cpp - operations/COM_RenderLayersDepthProg.h - operations/COM_RenderLayersNormalOperation.cpp - operations/COM_RenderLayersNormalOperation.h - operations/COM_RenderLayersSpeedOperation.cpp - operations/COM_RenderLayersSpeedOperation.h - operations/COM_RenderLayersColorOperation.cpp - operations/COM_RenderLayersColorOperation.h - operations/COM_RenderLayersUVOperation.cpp - operations/COM_RenderLayersUVOperation.h - operations/COM_RenderLayersMistOperation.cpp - operations/COM_RenderLayersMistOperation.h - operations/COM_RenderLayersObjectIndexOperation.cpp - operations/COM_RenderLayersObjectIndexOperation.h - operations/COM_RenderLayersMaterialIndexOperation.cpp - operations/COM_RenderLayersMaterialIndexOperation.h - operations/COM_RenderLayersDiffuseOperation.cpp - operations/COM_RenderLayersDiffuseOperation.h - operations/COM_RenderLayersSpecularOperation.cpp - operations/COM_RenderLayersSpecularOperation.h - operations/COM_RenderLayersShadowOperation.cpp - operations/COM_RenderLayersShadowOperation.h - operations/COM_RenderLayersAOOperation.cpp - operations/COM_RenderLayersAOOperation.h - operations/COM_RenderLayersEmitOperation.cpp - operations/COM_RenderLayersEmitOperation.h - operations/COM_RenderLayersReflectionOperation.cpp - operations/COM_RenderLayersReflectionOperation.h - operations/COM_RenderLayersRefractionOperation.cpp - operations/COM_RenderLayersRefractionOperation.h - operations/COM_RenderLayersEnvironmentOperation.cpp - operations/COM_RenderLayersEnvironmentOperation.h - operations/COM_RenderLayersIndirectOperation.cpp - operations/COM_RenderLayersIndirectOperation.h - operations/COM_RenderLayersCyclesOperation.cpp - operations/COM_RenderLayersCyclesOperation.h + operations/COM_ColorSpillOperation.cpp + operations/COM_ColorSpillOperation.h + operations/COM_RenderLayersBaseProg.cpp + operations/COM_RenderLayersBaseProg.h + operations/COM_RenderLayersImageProg.cpp + operations/COM_RenderLayersImageProg.h + operations/COM_RenderLayersAlphaProg.cpp + operations/COM_RenderLayersAlphaProg.h + operations/COM_RenderLayersDepthProg.cpp + operations/COM_RenderLayersDepthProg.h + operations/COM_RenderLayersNormalOperation.cpp + operations/COM_RenderLayersNormalOperation.h + operations/COM_RenderLayersSpeedOperation.cpp + operations/COM_RenderLayersSpeedOperation.h + operations/COM_RenderLayersColorOperation.cpp + operations/COM_RenderLayersColorOperation.h + operations/COM_RenderLayersUVOperation.cpp + operations/COM_RenderLayersUVOperation.h + operations/COM_RenderLayersMistOperation.cpp + operations/COM_RenderLayersMistOperation.h + operations/COM_RenderLayersObjectIndexOperation.cpp + operations/COM_RenderLayersObjectIndexOperation.h + operations/COM_RenderLayersMaterialIndexOperation.cpp + operations/COM_RenderLayersMaterialIndexOperation.h + operations/COM_RenderLayersDiffuseOperation.cpp + operations/COM_RenderLayersDiffuseOperation.h + operations/COM_RenderLayersSpecularOperation.cpp + operations/COM_RenderLayersSpecularOperation.h + operations/COM_RenderLayersShadowOperation.cpp + operations/COM_RenderLayersShadowOperation.h + operations/COM_RenderLayersAOOperation.cpp + operations/COM_RenderLayersAOOperation.h + operations/COM_RenderLayersEmitOperation.cpp + operations/COM_RenderLayersEmitOperation.h + operations/COM_RenderLayersReflectionOperation.cpp + operations/COM_RenderLayersReflectionOperation.h + operations/COM_RenderLayersRefractionOperation.cpp + operations/COM_RenderLayersRefractionOperation.h + operations/COM_RenderLayersEnvironmentOperation.cpp + operations/COM_RenderLayersEnvironmentOperation.h + operations/COM_RenderLayersIndirectOperation.cpp + operations/COM_RenderLayersIndirectOperation.h + operations/COM_RenderLayersCyclesOperation.cpp + operations/COM_RenderLayersCyclesOperation.h operations/COM_ImageOperation.cpp operations/COM_ImageOperation.h @@ -375,39 +375,39 @@ operations/COM_ColorSpillOperation.h operations/COM_BokehImageOperation.h - operations/COM_SocketProxyOperation.h - operations/COM_SocketProxyOperation.cpp + operations/COM_SocketProxyOperation.h + operations/COM_SocketProxyOperation.cpp - operations/COM_CompositorOperation.h - operations/COM_CompositorOperation.cpp + operations/COM_CompositorOperation.h + operations/COM_CompositorOperation.cpp operations/COM_OutputFileOperation.h operations/COM_OutputFileOperation.cpp - operations/COM_ViewerBaseOperation.h - operations/COM_ViewerBaseOperation.cpp - operations/COM_ViewerOperation.h - operations/COM_ViewerOperation.cpp - operations/COM_PreviewOperation.h - operations/COM_PreviewOperation.cpp - operations/COM_SplitViewerOperation.h - operations/COM_SplitViewerOperation.cpp - operations/COM_ConvertValueToColourProg.h - operations/COM_ConvertValueToColourProg.cpp - operations/COM_ConvertColourToValueProg.h - operations/COM_ConvertColourToValueProg.cpp - operations/COM_ConvertColorToBWOperation.h - operations/COM_ConvertColorToBWOperation.cpp - operations/COM_ConvertColorToVectorOperation.h - operations/COM_ConvertColorToVectorOperation.cpp - operations/COM_ConvertValueToVectorOperation.h - operations/COM_ConvertValueToVectorOperation.cpp - operations/COM_ConvertVectorToColorOperation.h - operations/COM_ConvertVectorToColorOperation.cpp - operations/COM_ConvertVectorToValueOperation.h - operations/COM_ConvertVectorToValueOperation.cpp -operations/COM_ConvertDepthToRadiusOperation.h -operations/COM_ConvertDepthToRadiusOperation.cpp - operations/COM_ZCombineOperation.cpp - operations/COM_ZCombineOperation.h + operations/COM_ViewerBaseOperation.h + operations/COM_ViewerBaseOperation.cpp + operations/COM_ViewerOperation.h + operations/COM_ViewerOperation.cpp + operations/COM_PreviewOperation.h + operations/COM_PreviewOperation.cpp + operations/COM_SplitViewerOperation.h + operations/COM_SplitViewerOperation.cpp + operations/COM_ConvertValueToColourProg.h + operations/COM_ConvertValueToColourProg.cpp + operations/COM_ConvertColourToValueProg.h + operations/COM_ConvertColourToValueProg.cpp + operations/COM_ConvertColorToBWOperation.h + operations/COM_ConvertColorToBWOperation.cpp + operations/COM_ConvertColorToVectorOperation.h + operations/COM_ConvertColorToVectorOperation.cpp + operations/COM_ConvertValueToVectorOperation.h + operations/COM_ConvertValueToVectorOperation.cpp + operations/COM_ConvertVectorToColorOperation.h + operations/COM_ConvertVectorToColorOperation.cpp + operations/COM_ConvertVectorToValueOperation.h + operations/COM_ConvertVectorToValueOperation.cpp + operations/COM_ConvertDepthToRadiusOperation.h + operations/COM_ConvertDepthToRadiusOperation.cpp + operations/COM_ZCombineOperation.cpp + operations/COM_ZCombineOperation.h operations/COM_ConvertRGBToYCCOperation.h operations/COM_ConvertRGBToYCCOperation.cpp @@ -468,86 +468,86 @@ operations/COM_ConvertDepthToRadiusOperation.cpp operations/COM_GammaOperation.h operations/COM_ColorCorrectionOperation.cpp operations/COM_ColorCorrectionOperation.h - operations/COM_SetValueOperation.h - operations/COM_SetValueOperation.cpp - operations/COM_SetColorOperation.h - operations/COM_SetColorOperation.cpp - operations/COM_SetVectorOperation.h - operations/COM_SetVectorOperation.cpp - - operations/COM_MixBurnOperation.h - operations/COM_MixBurnOperation.cpp - operations/COM_MixColorOperation.h - operations/COM_MixColorOperation.cpp - operations/COM_MixDarkenOperation.h - operations/COM_MixDarkenOperation.cpp - operations/COM_MixDodgeOperation.h - operations/COM_MixDodgeOperation.cpp - operations/COM_MixDifferenceOperation.h - operations/COM_MixDifferenceOperation.cpp - operations/COM_MixDivideOperation.h - operations/COM_MixDivideOperation.cpp - operations/COM_MixHueOperation.h - operations/COM_MixHueOperation.cpp - operations/COM_MixLightenOperation.h - operations/COM_MixLightenOperation.cpp - operations/COM_MixLinearLightOperation.h - operations/COM_MixLinearLightOperation.cpp - operations/COM_MixOverlayOperation.h - operations/COM_MixOverlayOperation.cpp - operations/COM_MixSaturationOperation.h - operations/COM_MixSaturationOperation.cpp - operations/COM_MixScreenOperation.h - operations/COM_MixScreenOperation.cpp - operations/COM_MixSoftLightOperation.h - operations/COM_MixSoftLightOperation.cpp - operations/COM_MixValueOperation.h - operations/COM_MixValueOperation.cpp - operations/COM_MixSubtractOperation.h - operations/COM_MixSubtractOperation.cpp + operations/COM_SetValueOperation.h + operations/COM_SetValueOperation.cpp + operations/COM_SetColorOperation.h + operations/COM_SetColorOperation.cpp + operations/COM_SetVectorOperation.h + operations/COM_SetVectorOperation.cpp + + operations/COM_MixBurnOperation.h + operations/COM_MixBurnOperation.cpp + operations/COM_MixColorOperation.h + operations/COM_MixColorOperation.cpp + operations/COM_MixDarkenOperation.h + operations/COM_MixDarkenOperation.cpp + operations/COM_MixDodgeOperation.h + operations/COM_MixDodgeOperation.cpp + operations/COM_MixDifferenceOperation.h + operations/COM_MixDifferenceOperation.cpp + operations/COM_MixDivideOperation.h + operations/COM_MixDivideOperation.cpp + operations/COM_MixHueOperation.h + operations/COM_MixHueOperation.cpp + operations/COM_MixLightenOperation.h + operations/COM_MixLightenOperation.cpp + operations/COM_MixLinearLightOperation.h + operations/COM_MixLinearLightOperation.cpp + operations/COM_MixOverlayOperation.h + operations/COM_MixOverlayOperation.cpp + operations/COM_MixSaturationOperation.h + operations/COM_MixSaturationOperation.cpp + operations/COM_MixScreenOperation.h + operations/COM_MixScreenOperation.cpp + operations/COM_MixSoftLightOperation.h + operations/COM_MixSoftLightOperation.cpp + operations/COM_MixValueOperation.h + operations/COM_MixValueOperation.cpp + operations/COM_MixSubtractOperation.h + operations/COM_MixSubtractOperation.cpp operations/COM_MathBaseOperation.h operations/COM_MathBaseOperation.cpp - operations/COM_AlphaOverMixedOperation.h - operations/COM_AlphaOverMixedOperation.cpp - operations/COM_AlphaOverPremultiplyOperation.h - operations/COM_AlphaOverPremultiplyOperation.cpp - operations/COM_AlphaOverKeyOperation.h - operations/COM_AlphaOverKeyOperation.cpp - - operations/COM_ColorBalanceLGGOperation.h - operations/COM_ColorBalanceLGGOperation.cpp - operations/COM_ColorBalanceASCCDLOperation.h - operations/COM_ColorBalanceASCCDLOperation.cpp - operations/COM_InvertOperation.cpp - operations/COM_InvertOperation.h + operations/COM_AlphaOverMixedOperation.h + operations/COM_AlphaOverMixedOperation.cpp + operations/COM_AlphaOverPremultiplyOperation.h + operations/COM_AlphaOverPremultiplyOperation.cpp + operations/COM_AlphaOverKeyOperation.h + operations/COM_AlphaOverKeyOperation.cpp + + operations/COM_ColorBalanceLGGOperation.h + operations/COM_ColorBalanceLGGOperation.cpp + operations/COM_ColorBalanceASCCDLOperation.h + operations/COM_ColorBalanceASCCDLOperation.cpp + operations/COM_InvertOperation.cpp + operations/COM_InvertOperation.h operations/COM_SetAlphaOperation.cpp operations/COM_SetAlphaOperation.h operations/COM_MapValueOperation.cpp operations/COM_MapValueOperation.h -# Distort operation - operations/COM_TranslateOperation.h - operations/COM_TranslateOperation.cpp - operations/COM_RotateOperation.h - operations/COM_RotateOperation.cpp - operations/COM_ScaleOperation.h - operations/COM_ScaleOperation.cpp - operations/COM_MapUVOperation.h - operations/COM_MapUVOperation.cpp - operations/COM_DisplaceOperation.h - operations/COM_DisplaceOperation.cpp - operations/COM_DisplaceSimpleOperation.h - operations/COM_DisplaceSimpleOperation.cpp - operations/COM_FlipOperation.h - operations/COM_FlipOperation.cpp - operations/COM_ProjectorLensDistortionOperation.cpp - operations/COM_ProjectorLensDistortionOperation.h - operations/COM_ScreenLensDistortionOperation.cpp - operations/COM_ScreenLensDistortionOperation.h - -#Filter operations + # Distort operation + operations/COM_TranslateOperation.h + operations/COM_TranslateOperation.cpp + operations/COM_RotateOperation.h + operations/COM_RotateOperation.cpp + operations/COM_ScaleOperation.h + operations/COM_ScaleOperation.cpp + operations/COM_MapUVOperation.h + operations/COM_MapUVOperation.cpp + operations/COM_DisplaceOperation.h + operations/COM_DisplaceOperation.cpp + operations/COM_DisplaceSimpleOperation.h + operations/COM_DisplaceSimpleOperation.cpp + operations/COM_FlipOperation.h + operations/COM_FlipOperation.cpp + operations/COM_ProjectorLensDistortionOperation.cpp + operations/COM_ProjectorLensDistortionOperation.h + operations/COM_ScreenLensDistortionOperation.cpp + operations/COM_ScreenLensDistortionOperation.h + + #Filter operations operations/COM_ConvolutionFilterOperation.h operations/COM_ConvolutionFilterOperation.cpp operations/COM_ConvolutionEdgeFilterOperation.h @@ -570,7 +570,7 @@ operations/COM_ConvertDepthToRadiusOperation.cpp operations/COM_SetSamplerOperation.h -#Convert operations + #Convert operations operations/COM_IDMaskOperation.cpp operations/COM_IDMaskOperation.h @@ -581,7 +581,8 @@ operations/COM_ConvertDepthToRadiusOperation.cpp operations/COM_DotproductOperation.cpp operations/COM_DotproductOperation.h -# Matte operation + + # Matte operation operations/COM_BoxMaskOperation.h operations/COM_BoxMaskOperation.cpp operations/COM_EllipseMaskOperation.h @@ -594,6 +595,9 @@ operations/COM_ConvertDepthToRadiusOperation.cpp operations/COM_AntiAliasOperation.cpp operations/COM_AntiAliasOperation.h + + operations/COM_MaskOperation.cpp + operations/COM_MaskOperation.h ) blender_add_lib(bf_compositor "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/compositor/COM_defines.h b/source/blender/compositor/COM_defines.h index df807091cb8..f87265c50f5 100644 --- a/source/blender/compositor/COM_defines.h +++ b/source/blender/compositor/COM_defines.h @@ -52,12 +52,25 @@ typedef enum CompositorQuality { COM_QUALITY_LOW = 2 } CompositorQuality; +/** + * @brief Possible priority settings + * @ingroup Execution + */ +typedef enum CompositorPriority { + /** @brief High quality setting */ + COM_PRIORITY_HIGH = 2 , + /** @brief Medium quality setting */ + COM_PRIORITY_MEDIUM = 1, + /** @brief Low quality setting */ + COM_PRIORITY_LOW = 0 +} CompositorPriority; + // configurable items // chunk size determination #define COM_PREVIEW_SIZE 140.0f -#define COM_OPENCL_ENABLED -#define COM_PREVIEW_ENABLED +//#define COM_OPENCL_ENABLED + // workscheduler threading models /** * COM_TM_QUEUE is a multithreaded model, which uses the BLI_thread_queue pattern. This is the default option. diff --git a/source/blender/compositor/intern/COM_ChunkOrderHotspot.cpp b/source/blender/compositor/intern/COM_ChunkOrderHotspot.cpp index 94110f0bcfe..0ab08ec5810 100644 --- a/source/blender/compositor/intern/COM_ChunkOrderHotspot.cpp +++ b/source/blender/compositor/intern/COM_ChunkOrderHotspot.cpp @@ -35,6 +35,6 @@ double ChunkOrderHotspot::determineDistance(int x, int y) int dx = x-this->x; int dy = y-this->y; double result = sqrt((double)(dx*dx+dy*dy)); - result += this->addition; + result += (double)this->addition; return result; } diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp index 3cb297801ca..dc6409e7b86 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -111,6 +111,7 @@ #include "COM_DefocusNode.h" #include "COM_DoubleEdgeMaskNode.h" #include "COM_CropNode.h" +#include "COM_MaskNode.h" Node *Converter::convert(bNode *bNode) { @@ -347,6 +348,9 @@ case CMP_NODE_OUTPUT_FILE: case CMP_NODE_CROP: node = new CropNode(bNode); break; + case CMP_NODE_MASK: + node = new MaskNode(bNode); + break; /* not inplemented yet */ default: node = new MuteNode(bNode); diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp index 0ebf9af207b..481b83c81a3 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp @@ -57,7 +57,7 @@ ExecutionGroup::ExecutionGroup() this->chunksFinished = 0; } -int ExecutionGroup::getRenderPriotrity() +CompositorPriority ExecutionGroup::getRenderPriotrity() { return this->getOutputNodeOperation()->getRenderPriority(); } @@ -351,7 +351,8 @@ void ExecutionGroup::execute(ExecutionSystem *graph) startIndex = index+1; } } - PIL_sleep_ms(10); + + WorkScheduler::finish(); if (bTree->test_break && bTree->test_break(bTree->tbh)) { breaked = true; @@ -401,47 +402,11 @@ MemoryBuffer** ExecutionGroup::getInputBuffersOpenCL(int chunkNumber) return memoryBuffers; } -// @todo: for opencl the memory buffers size needs to be same as the needed size -// currently this method is not called, but will be when opencl nodes are created MemoryBuffer *ExecutionGroup::constructConsolidatedMemoryBuffer(MemoryProxy *memoryProxy, rcti *rect) { - // find all chunks inside the rect - // determine minxchunk, minychunk, maxxchunk, maxychunk where x and y are chunknumbers - float chunkSizef = this->chunkSize; - - int indexx, indexy; - - const int minxchunk = floor(rect->xmin/chunkSizef); - const int maxxchunk = ceil((rect->xmax-1)/chunkSizef); - const int minychunk = floor(rect->ymin/chunkSizef); - const int maxychunk = ceil((rect->ymax-1)/chunkSizef); - - if (maxxchunk== minxchunk+1 && maxychunk == minychunk+1) { - MemoryBuffer *result =memoryProxy->getBuffer(); - return result; - } - - rcti chunkRect; - chunkRect.xmin = minxchunk*this->chunkSize; - chunkRect.xmax = maxxchunk*this->chunkSize; - chunkRect.ymin = minychunk*this->chunkSize; - chunkRect.ymax = maxychunk*this->chunkSize; - - CLAMP(chunkRect.xmin, 0, (int)this->width); - CLAMP(chunkRect.xmax, 0, (int)this->width); - CLAMP(chunkRect.ymin, 0, (int)this->height); - CLAMP(chunkRect.ymax, 0, (int)this->height); - - MemoryBuffer *result = new MemoryBuffer(memoryProxy, &chunkRect); - - for (indexx = max(minxchunk, 0); indexx<min((int)this->numberOfXChunks, maxxchunk) ; indexx++) { - for (indexy = max(minychunk, 0); indexy<min((int)this->numberOfYChunks, maxychunk) ; indexy++) { - /* int chunkNumber = indexx+indexy*this->numberOfXChunks; */ /* UNUSED */ - MemoryBuffer *chunkBuffer = memoryProxy->getBuffer(); - result->copyContentFrom(chunkBuffer); - } - } - + MemoryBuffer* imageBuffer = memoryProxy->getBuffer(); + MemoryBuffer* result = new MemoryBuffer(memoryProxy, rect); + result->copyContentFrom(imageBuffer); return result; } @@ -487,14 +452,14 @@ void ExecutionGroup::determineChunkRect(rcti *rect, const unsigned int chunkNumb MemoryBuffer *ExecutionGroup::allocateOutputBuffer(int chunkNumber, rcti *rect) { - MemoryBuffer *outputBuffer = NULL; - // output allocation is only valid when our outputoperation is a memorywriter + // we asume that this method is only called from complex execution groups. NodeOperation * operation = this->getOutputNodeOperation(); if (operation->isWriteBufferOperation()) { -/* WriteBufferOperation *writeOperation = (WriteBufferOperation*)operation; */ /* UNUSED */ -// @todo outputBuffer = MemoryManager::allocateMemoryBuffer(writeOperation->getMemoryProxy(), chunkNumber, rect); + WriteBufferOperation *writeOperation = (WriteBufferOperation*)operation; + MemoryBuffer *buffer = new MemoryBuffer(writeOperation->getMemoryProxy(), rect); + return buffer; } - return outputBuffer; + return NULL; } @@ -600,11 +565,6 @@ void ExecutionGroup::determineDependingMemoryProxies(vector<MemoryProxy*> *memor } } -bool ExecutionGroup::operator ==(const ExecutionGroup & executionGroup) const -{ - return this->getOutputNodeOperation() == executionGroup.getOutputNodeOperation(); -} - bool ExecutionGroup::isOpenCL() { return this->openCL; diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h index cbdc9bb1787..416a78eb8b8 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.h +++ b/source/blender/compositor/intern/COM_ExecutionGroup.h @@ -167,13 +167,7 @@ private: * @param operation the operation to be added */ bool canContainOperation(NodeOperation *operation); - - /** - * @brief get the Render priority of this ExecutionGroup - * @see ExecutionSystem.execute - */ - int getRenderPriotrity(); - + /** * @brief calculate the actual chunk size of this execution group. * @note A chunk size is an unsigned int that is both the height and width of a chunk. @@ -396,17 +390,21 @@ public: * @see determineChunkSize() */ void determineChunkRect(rcti *rect, const unsigned int chunkNumber) const; - - - bool operator ==(const ExecutionGroup &executionGroup) const; - - /** + + /** * @brief can this ExecutionGroup be scheduled on an OpenCLDevice * @see WorkScheduler.schedule */ bool isOpenCL(); - + void setChunksize(int chunksize) {this->chunkSize = chunksize;} + + /** + * @brief get the Render priority of this ExecutionGroup + * @see ExecutionSystem.execute + */ + CompositorPriority getRenderPriotrity(); + }; #endif diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp index 96d2a6f4434..8c0b37a0685 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp @@ -127,20 +127,9 @@ void ExecutionSystem::execute() WorkScheduler::start(this->context); - - vector<ExecutionGroup*> executionGroups; - this->findOutputExecutionGroup(&executionGroups); - - /* start execution of the ExecutionGroups based on priority of their output node */ - for (int priority = 9 ; priority>=0 ; priority--) { - for (index = 0 ; index < executionGroups.size(); index ++) { - ExecutionGroup *group = executionGroups[index]; - NodeOperation *output = group->getOutputNodeOperation(); - if (output->getRenderPriority() == priority) { - group->execute(this); - } - } - } + executeGroups(COM_PRIORITY_HIGH); + executeGroups(COM_PRIORITY_MEDIUM); + executeGroups(COM_PRIORITY_LOW); WorkScheduler::finish(); WorkScheduler::stop(); @@ -155,6 +144,18 @@ void ExecutionSystem::execute() } } +void ExecutionSystem::executeGroups(CompositorPriority priority) +{ + int index; + vector<ExecutionGroup*> executionGroups; + this->findOutputExecutionGroup(&executionGroups, priority); + + for (index = 0 ; index < executionGroups.size(); index ++) { + ExecutionGroup *group = executionGroups[index]; + group->execute(this); + } +} + void ExecutionSystem::addOperation(NodeOperation *operation) { ExecutionSystemHelper::addOperation(this->operations, operation); @@ -304,6 +305,17 @@ void ExecutionSystem::determineActualSocketDataTypes(vector<NodeBase*> &nodes) } } +void ExecutionSystem::findOutputExecutionGroup(vector<ExecutionGroup*> *result, CompositorPriority priority) const +{ + unsigned int index; + for (index = 0 ; index < this->groups.size() ; index ++) { + ExecutionGroup *group = this->groups[index]; + if (group->isOutputExecutionGroup() && group->getRenderPriotrity() == priority) { + result->push_back(group); + } + } +} + void ExecutionSystem::findOutputExecutionGroup(vector<ExecutionGroup*> *result) const { unsigned int index; diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.h b/source/blender/compositor/intern/COM_ExecutionSystem.h index 85fec8b6145..510e58ba1bb 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.h +++ b/source/blender/compositor/intern/COM_ExecutionSystem.h @@ -141,6 +141,11 @@ private: //methods /** * find all execution group with output nodes */ + void findOutputExecutionGroup(vector<ExecutionGroup*> *result, CompositorPriority priority) const; + + /** + * find all execution group with output nodes + */ void findOutputExecutionGroup(vector<ExecutionGroup*> *result) const; public: @@ -224,6 +229,8 @@ private: * @param nodes list of nodes or operations to do the data type determination */ void determineActualSocketDataTypes(vector<NodeBase*> &nodes); + + void executeGroups(CompositorPriority priority); }; #endif diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cpp b/source/blender/compositor/intern/COM_MemoryBuffer.cpp index 37d79607d12..3ebf8398c02 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.cpp +++ b/source/blender/compositor/intern/COM_MemoryBuffer.cpp @@ -150,8 +150,8 @@ void MemoryBuffer::readCubic(float result[4], float x, float y) float valuex = x - x1; float valuey = y - y1; - float mvaluex = 1.0 - valuex; - float mvaluey = 1.0 - valuey; + float mvaluex = 1.0f - valuex; + float mvaluey = 1.0f - valuey; float color1[4]; float color2[4]; diff --git a/source/blender/compositor/intern/COM_Node.cpp b/source/blender/compositor/intern/COM_Node.cpp index ba5e21d53ae..264725b4b2c 100644 --- a/source/blender/compositor/intern/COM_Node.cpp +++ b/source/blender/compositor/intern/COM_Node.cpp @@ -83,23 +83,20 @@ void Node::addSetValueOperation(ExecutionSystem *graph, InputSocket *inputsocket graph->addOperation(operation); } -void Node::addPreviewOperation(ExecutionSystem *system, OutputSocket *outputSocket, int priority) +void Node::addPreviewOperation(ExecutionSystem *system, OutputSocket *outputSocket) { -#ifdef COM_PREVIEW_ENABLED PreviewOperation *operation = new PreviewOperation(); system->addOperation(operation); operation->setbNode(this->getbNode()); operation->setbNodeTree(system->getContext().getbNodeTree()); - operation->setPriority(priority); this->addLink(system, outputSocket, operation->getInputSocket(0)); -#endif } -void Node::addPreviewOperation(ExecutionSystem *system, InputSocket *inputSocket, int priority) +void Node::addPreviewOperation(ExecutionSystem *system, InputSocket *inputSocket) { if (inputSocket->isConnected()) { OutputSocket *outputsocket = inputSocket->getConnection()->getFromSocket(); - this->addPreviewOperation(system, outputsocket, priority); + this->addPreviewOperation(system, outputsocket); } } diff --git a/source/blender/compositor/intern/COM_Node.h b/source/blender/compositor/intern/COM_Node.h index 2666d0a6980..23744adf642 100644 --- a/source/blender/compositor/intern/COM_Node.h +++ b/source/blender/compositor/intern/COM_Node.h @@ -120,8 +120,8 @@ protected: Node(); - void addPreviewOperation(ExecutionSystem *system, InputSocket *inputSocket, int priority); - void addPreviewOperation(ExecutionSystem *system, OutputSocket *inputSocket, int priority); + void addPreviewOperation(ExecutionSystem *system, InputSocket *inputSocket); + void addPreviewOperation(ExecutionSystem *system, OutputSocket *outputSocket); bNodeSocket *getEditorInputSocket(int editorNodeInputSocketIndex); bNodeSocket *getEditorOutputSocket(int editorNodeOutputSocketIndex); diff --git a/source/blender/compositor/intern/COM_NodeOperation.cpp b/source/blender/compositor/intern/COM_NodeOperation.cpp index fae652e39d7..650e4af5ae0 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.cpp +++ b/source/blender/compositor/intern/COM_NodeOperation.cpp @@ -124,3 +124,111 @@ bool NodeOperation::determineDependingAreaOfInterest(rcti * input, ReadBufferOpe return false; } } + +cl_mem NodeOperation::COM_clAttachMemoryBufferToKernelParameter(cl_context context, cl_kernel kernel, int parameterIndex, int offsetIndex, list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers, SocketReader* reader) +{ + cl_int error; + MemoryBuffer* result = (MemoryBuffer*)reader->initializeTileData(NULL, inputMemoryBuffers); + + const cl_image_format imageFormat = { + CL_RGBA, + CL_FLOAT + }; + + cl_mem clBuffer = clCreateImage2D(context, CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR, &imageFormat, result->getWidth(), + result->getHeight(), 0, result->getBuffer(), &error); + + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + if (error == CL_SUCCESS) cleanup->push_back(clBuffer); + + error = clSetKernelArg(kernel, parameterIndex, sizeof(cl_mem), &clBuffer); + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + + COM_clAttachMemoryBufferOffsetToKernelParameter(kernel, offsetIndex, result); + return clBuffer; +} + +void NodeOperation::COM_clAttachMemoryBufferOffsetToKernelParameter(cl_kernel kernel, int offsetIndex, MemoryBuffer *memoryBuffer) +{ + if (offsetIndex != -1) { + cl_int error; + rcti* rect = memoryBuffer->getRect(); + cl_int2 offset = {rect->xmin, rect->ymin}; + + error = clSetKernelArg(kernel, offsetIndex, sizeof(cl_int2), &offset); + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + } +} + +void NodeOperation::COM_clAttachSizeToKernelParameter(cl_kernel kernel, int offsetIndex) +{ + if (offsetIndex != -1) { + cl_int error; + cl_int2 offset = {this->getWidth(), this->getHeight()}; + + error = clSetKernelArg(kernel, offsetIndex, sizeof(cl_int2), &offset); + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + } +} + +void NodeOperation::COM_clAttachOutputMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, cl_mem clOutputMemoryBuffer) +{ + cl_int error; + error = clSetKernelArg(kernel, parameterIndex, sizeof(cl_mem), &clOutputMemoryBuffer); + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } +} + +void NodeOperation::COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, MemoryBuffer *outputMemoryBuffer) { + cl_int error; + const size_t size[] = {outputMemoryBuffer->getWidth(),outputMemoryBuffer->getHeight()}; + + error = clEnqueueNDRangeKernel(queue, kernel, 2, NULL, size, 0, 0, 0, NULL); + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } +} + +void NodeOperation::COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, MemoryBuffer *outputMemoryBuffer, int offsetIndex) { + cl_int error; + const int width = outputMemoryBuffer->getWidth(); + const int height = outputMemoryBuffer->getHeight(); + int offsetx; + int offsety; + const int localSize = 32; + size_t size[2]; + cl_int2 offset; + + for (offsety = 0 ; offsety < height; offsety+=localSize) { + offset[1] = offsety; + if (offsety+localSize < height) { + size[1] = localSize; + } else { + size[1] = height - offsety; + } + for (offsetx = 0 ; offsetx < width ; offsetx+=localSize) { + if (offsetx+localSize < width) { + size[0] = localSize; + } else { + size[0] = width - offsetx; + } + offset[0] = offsetx; + + error = clSetKernelArg(kernel, offsetIndex, sizeof(cl_int2), &offset); + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + error = clEnqueueNDRangeKernel(queue, kernel, 2, NULL, size, 0, 0, 0, NULL); + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + clFlush(queue); + } + } +} + +cl_kernel NodeOperation::COM_clCreateKernel(cl_program program, const char *kernelname, list<cl_kernel> *clKernelsToCleanUp) +{ + cl_int error; + cl_kernel kernel = clCreateKernel(program, kernelname, &error) ; + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); + } + else { + if (clKernelsToCleanUp) clKernelsToCleanUp->push_back(kernel); + } + return kernel; + +} diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h index 73ba5b472d7..2219907b0c8 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.h +++ b/source/blender/compositor/intern/COM_NodeOperation.h @@ -139,8 +139,10 @@ public: * @param rect the rectangle of the chunk (location and size) * @param chunkNumber the chunkNumber to be calculated * @param memoryBuffers all input MemoryBuffer's needed + * @param outputBuffer the outputbuffer to write to */ - virtual void executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, unsigned int chunkNumber, MemoryBuffer** memoryBuffers) {} + virtual void executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, + unsigned int chunkNumber, MemoryBuffer** memoryBuffers, MemoryBuffer* outputBuffer) {} /** * @brief custom handle to add new tasks to the OpenCL command queue in order to execute a chunk on an GPUDevice @@ -207,9 +209,9 @@ public: /** * @brief get the render priority of this node. * @note only applicable for output operations like ViewerOperation - * @return [0:9] 9 is highest priority + * @return CompositorPriority */ - virtual const int getRenderPriority() const {return 0;} + virtual const CompositorPriority getRenderPriority() const {return COM_PRIORITY_LOW;} /** * @brief can this NodeOperation be scheduled on an OpenCLDevice @@ -242,6 +244,13 @@ protected: */ void setOpenCL(bool openCL) {this->openCL = openCL;} + static cl_mem COM_clAttachMemoryBufferToKernelParameter(cl_context context, cl_kernel kernel, int parameterIndex, int offsetIndex, list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers, SocketReader* reader); + static void COM_clAttachMemoryBufferOffsetToKernelParameter(cl_kernel kernel, int offsetIndex, MemoryBuffer *memoryBuffers); + static void COM_clAttachOutputMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, cl_mem clOutputMemoryBuffer); + void COM_clAttachSizeToKernelParameter(cl_kernel kernel, int offsetIndex); + static void COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, MemoryBuffer* outputMemoryBuffer); + static void COM_clEnqueueRange(cl_command_queue queue, cl_kernel kernel, MemoryBuffer *outputMemoryBuffer, int offsetIndex); + cl_kernel COM_clCreateKernel(cl_program program, const char* kernelname, list<cl_kernel> *clKernelsToCleanUp); }; diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.cpp b/source/blender/compositor/intern/COM_OpenCLDevice.cpp index 692b96f40b3..e6d3789b06d 100644 --- a/source/blender/compositor/intern/COM_OpenCLDevice.cpp +++ b/source/blender/compositor/intern/COM_OpenCLDevice.cpp @@ -56,10 +56,10 @@ void OpenCLDevice::execute(WorkPackage *work) MemoryBuffer ** inputBuffers = executionGroup->getInputBuffersOpenCL(chunkNumber); MemoryBuffer * outputBuffer = executionGroup->allocateOutputBuffer(chunkNumber, &rect); - executionGroup->getOutputNodeOperation()->executeOpenCLRegion(this->context, this->program, this->queue, &rect, chunkNumber, inputBuffers); + executionGroup->getOutputNodeOperation()->executeOpenCLRegion(this->context, this->program, this->queue, &rect, + chunkNumber, inputBuffers, outputBuffer); + + delete outputBuffer; executionGroup->finalizeChunkExecution(chunkNumber, inputBuffers); - if (outputBuffer != NULL) { - outputBuffer->setCreatedState(); - } } diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp index 80b91b2364c..ba8bfe55310 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.cpp +++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp @@ -28,7 +28,7 @@ #include "COM_OpenCLDevice.h" #include "OCL_opencl.h" #include "stdio.h" -#include "COM_OpenCLKernels.cl.cpp" +#include "COM_OpenCLKernels.cl.h" #include "BKE_global.h" #if COM_CURRENT_THREADING_MODEL == COM_TM_NOTHREAD @@ -39,8 +39,6 @@ #endif -/// @brief global state of the WorkScheduler. -static WorkSchedulerState state; /// @brief list of all CPUDevices. for every hardware thread an instance of CPUDevice is created static vector<CPUDevice*> cpudevices; @@ -68,43 +66,29 @@ static bool openclActive = false; #if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE void *WorkScheduler::thread_execute_cpu(void *data) { - bool continueLoop = true; Device *device = (Device*)data; - while (continueLoop) { - WorkPackage *work = (WorkPackage*)BLI_thread_queue_pop(cpuqueue); - if (work) { - device->execute(work); - delete work; - } - PIL_sleep_ms(10); - - if (WorkScheduler::isStopping()) { - continueLoop = false; - } + WorkPackage *work; + + while ((work = (WorkPackage*)BLI_thread_queue_pop(cpuqueue))) { + device->execute(work); + delete work; } + return NULL; } void *WorkScheduler::thread_execute_gpu(void *data) { - bool continueLoop = true; Device *device = (Device*)data; - while (continueLoop) { - WorkPackage *work = (WorkPackage*)BLI_thread_queue_pop(gpuqueue); - if (work) { - device->execute(work); - delete work; - } - PIL_sleep_ms(10); - - if (WorkScheduler::isStopping()) { - continueLoop = false; - } + WorkPackage *work; + + while ((work = (WorkPackage*)BLI_thread_queue_pop(gpuqueue))) { + device->execute(work); + delete work; } + return NULL; } - -bool WorkScheduler::isStopping() {return state == COM_WSS_STOPPING;} #endif @@ -135,7 +119,6 @@ void WorkScheduler::start(CompositorContext &context) #if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE unsigned int index; cpuqueue = BLI_thread_queue_init(); - BLI_thread_queue_nowait(cpuqueue); BLI_init_threads(&cputhreads, thread_execute_cpu, cpudevices.size()); for (index = 0 ; index < cpudevices.size() ; index ++) { Device *device = cpudevices[index]; @@ -144,7 +127,6 @@ void WorkScheduler::start(CompositorContext &context) #ifdef COM_OPENCL_ENABLED if (context.getHasActiveOpenCLDevices()) { gpuqueue = BLI_thread_queue_init(); - BLI_thread_queue_nowait(gpuqueue); BLI_init_threads(&gputhreads, thread_execute_gpu, gpudevices.size()); for (index = 0 ; index < gpudevices.size() ; index ++) { Device *device = gpudevices[index]; @@ -157,45 +139,39 @@ void WorkScheduler::start(CompositorContext &context) } #endif #endif - state = COM_WSS_STARTED; } void WorkScheduler::finish() { #if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE #ifdef COM_OPENCL_ENABLED if (openclActive) { - while (BLI_thread_queue_size(gpuqueue) + BLI_thread_queue_size(cpuqueue) > 0) { - PIL_sleep_ms(10); - } + BLI_thread_queue_wait_finish(gpuqueue); + BLI_thread_queue_wait_finish(cpuqueue); } else { - while (BLI_thread_queue_size(cpuqueue) > 0) { - PIL_sleep_ms(10); - } + BLI_thread_queue_wait_finish(cpuqueue); } #else - while (BLI_thread_queue_size(cpuqueue) > 0) { - PIL_sleep_ms(10); - } + BLI_thread_queue_wait_finish(cpuqueue); #endif #endif } void WorkScheduler::stop() { - state = COM_WSS_STOPPING; #if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE + BLI_thread_queue_nowait(cpuqueue); BLI_end_threads(&cputhreads); BLI_thread_queue_free(cpuqueue); cpuqueue = NULL; #ifdef COM_OPENCL_ENABLED if (openclActive) { + BLI_thread_queue_nowait(gpuqueue); BLI_end_threads(&gputhreads); BLI_thread_queue_free(gpuqueue); gpuqueue = NULL; } #endif #endif - state = COM_WSS_STOPPED; } bool WorkScheduler::hasGPUDevices() @@ -218,8 +194,6 @@ extern void clContextError(const char *errinfo, const void *private_info, size_t void WorkScheduler::initialize() { - state = COM_WSS_UNKNOWN; - #if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE int numberOfCPUThreads = BLI_system_thread_count(); @@ -260,7 +234,7 @@ void WorkScheduler::initialize() if (totalNumberOfDevices > 0) { context = clCreateContext(NULL, totalNumberOfDevices, cldevices, clContextError, NULL, &error); if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } - program = clCreateProgramWithSource(context, 1, &sourcecode, 0, &error); + program = clCreateProgramWithSource(context, 1, &clkernelstoh_COM_OpenCLKernels_cl, 0, &error); error = clBuildProgram(program, totalNumberOfDevices, cldevices, 0, 0, 0); if (error != CL_SUCCESS) { cl_int error2; @@ -298,8 +272,6 @@ void WorkScheduler::initialize() } #endif #endif - - state = COM_WSS_INITIALIZED; } void WorkScheduler::deinitialize() @@ -329,5 +301,4 @@ void WorkScheduler::deinitialize() } #endif #endif - state = COM_WSS_DEINITIALIZED; } diff --git a/source/blender/compositor/intern/COM_WorkScheduler.h b/source/blender/compositor/intern/COM_WorkScheduler.h index 0de1763749e..b03b514d139 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.h +++ b/source/blender/compositor/intern/COM_WorkScheduler.h @@ -31,19 +31,6 @@ extern "C" { #include "COM_defines.h" #include "COM_Device.h" -// STATES -/** @brief states of the WorkScheduler - * @ingroup execution - */ -typedef enum WorkSchedulerState { - COM_WSS_UNKNOWN = -1, - COM_WSS_INITIALIZED = 0, - COM_WSS_STARTED = 1, - COM_WSS_STOPPING = 2, - COM_WSS_STOPPED = 3, - COM_WSS_DEINITIALIZED = 4 -} WorkSchedulerState; - /** @brief the workscheduler * @ingroup execution */ diff --git a/source/blender/compositor/nodes/COM_BlurNode.cpp b/source/blender/compositor/nodes/COM_BlurNode.cpp index b209e36dd48..d9cf2c2fef0 100644 --- a/source/blender/compositor/nodes/COM_BlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BlurNode.cpp @@ -55,7 +55,7 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext * c this->getInputSocket(1)->relinkConnections(operationfgb->getInputSocket(1), 1, graph); this->getOutputSocket(0)->relinkConnections(operationfgb->getOutputSocket(0)); graph->addOperation(operationfgb); - addPreviewOperation(graph, operationfgb->getOutputSocket(), 5); + addPreviewOperation(graph, operationfgb->getOutputSocket()); } else if (!data->bokeh) { GaussianXBlurOperation *operationx = new GaussianXBlurOperation(); @@ -71,7 +71,7 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext * c graph->addOperation(operationy); addLink(graph, operationx->getOutputSocket(), operationy->getInputSocket(0)); addLink(graph, operationx->getInputSocket(1)->getConnection()->getFromSocket(), operationy->getInputSocket(1)); - addPreviewOperation(graph, operationy->getOutputSocket(), 5); + addPreviewOperation(graph, operationy->getOutputSocket()); if (!connectedSizeSocket) { operationx->setSize(size); @@ -86,7 +86,7 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext * c operation->setQuality(quality); graph->addOperation(operation); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); - addPreviewOperation(graph, operation->getOutputSocket(), 5); + addPreviewOperation(graph, operation->getOutputSocket()); if (!connectedSizeSocket) { operation->setSize(size); diff --git a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp index d6f4f58fe70..abae1b88890 100644 --- a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp @@ -41,9 +41,9 @@ void BokehBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContex if (this->getInputSocket(2)->isConnected()) { VariableSizeBokehBlurOperation *operation = new VariableSizeBokehBlurOperation(); ConvertDepthToRadiusOperation *converter = new ConvertDepthToRadiusOperation(); - converter->setfStop(4.0f); + converter->setfStop(this->getbNode()->custom3); converter->setCameraObject(camob); - operation->setMaxBlur(16); + operation->setMaxBlur((int)this->getbNode()->custom4); operation->setQuality(context->getQuality()); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph); diff --git a/source/blender/compositor/nodes/COM_BokehImageNode.cpp b/source/blender/compositor/nodes/COM_BokehImageNode.cpp index 35511d213f5..f498fa11e30 100644 --- a/source/blender/compositor/nodes/COM_BokehImageNode.cpp +++ b/source/blender/compositor/nodes/COM_BokehImageNode.cpp @@ -35,5 +35,5 @@ void BokehImageNode::convertToOperations(ExecutionSystem *graph, CompositorConte this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); graph->addOperation(operation); operation->setData((NodeBokehImage*)this->getbNode()->storage); - addPreviewOperation(graph, operation->getOutputSocket(0), 9); + addPreviewOperation(graph, operation->getOutputSocket(0)); } diff --git a/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp b/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp index dbe5b9936dc..f1d5b8d39cc 100644 --- a/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp @@ -82,7 +82,7 @@ void ChannelMatteNode::convertToOperations(ExecutionSystem *graph, CompositorCon graph->addOperation(operationAlpha); addLink(graph, operation->getOutputSocket(), operationAlpha->getInputSocket(1)); - addPreviewOperation(graph, operationAlpha->getOutputSocket(), 9); + addPreviewOperation(graph, operationAlpha->getOutputSocket()); if (outputSocketImage->isConnected()) { outputSocketImage->relinkConnections(operationAlpha->getOutputSocket()); diff --git a/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp b/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp index dd3b3855e3f..82059ed8493 100644 --- a/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp @@ -63,7 +63,7 @@ void ChromaMatteNode::convertToOperations(ExecutionSystem *graph, CompositorCont addLink(graph, operation->getOutputSocket(), operationAlpha->getInputSocket(1)); graph->addOperation(operationAlpha); - addPreviewOperation(graph, operationAlpha->getOutputSocket(), 9); + addPreviewOperation(graph, operationAlpha->getOutputSocket()); if (outputSocketImage->isConnected()) { outputSocketImage->relinkConnections(operationAlpha->getOutputSocket()); diff --git a/source/blender/compositor/nodes/COM_ColorCurveNode.cpp b/source/blender/compositor/nodes/COM_ColorCurveNode.cpp index d7cde21a984..0d331ed9b05 100644 --- a/source/blender/compositor/nodes/COM_ColorCurveNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorCurveNode.cpp @@ -31,16 +31,32 @@ ColorCurveNode::ColorCurveNode(bNode *editorNode): Node(editorNode) void ColorCurveNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) { - ColorCurveOperation *operation = new ColorCurveOperation(); - - this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); - this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph); - this->getInputSocket(2)->relinkConnections(operation->getInputSocket(2), 2, graph); - this->getInputSocket(3)->relinkConnections(operation->getInputSocket(3), 3, graph); - - this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); - - operation->setCurveMapping((CurveMapping*)this->getbNode()->storage); - - graph->addOperation(operation); + if (this->getInputSocket(2)->isConnected() || this->getInputSocket(3)->isConnected()) { + ColorCurveOperation *operation = new ColorCurveOperation(); + + this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); + this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph); + this->getInputSocket(2)->relinkConnections(operation->getInputSocket(2), 2, graph); + this->getInputSocket(3)->relinkConnections(operation->getInputSocket(3), 3, graph); + + this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); + + operation->setCurveMapping((CurveMapping*)this->getbNode()->storage); + + graph->addOperation(operation); + } else { + ConstantLevelColorCurveOperation *operation = new ConstantLevelColorCurveOperation(); + + this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); + this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph); + bNodeSocketValueRGBA *val = (bNodeSocketValueRGBA*)this->getInputSocket(2)->getbNodeSocket()->default_value; + operation->setBlackLevel(val->value); + val = (bNodeSocketValueRGBA*)this->getInputSocket(3)->getbNodeSocket()->default_value; + operation->setWhiteLevel(val->value); + this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); + + operation->setCurveMapping((CurveMapping*)this->getbNode()->storage); + + graph->addOperation(operation); + } } diff --git a/source/blender/compositor/nodes/COM_ColorMatteNode.cpp b/source/blender/compositor/nodes/COM_ColorMatteNode.cpp index 860d1a01194..ad117e1ca2c 100644 --- a/source/blender/compositor/nodes/COM_ColorMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorMatteNode.cpp @@ -60,7 +60,7 @@ void ColorMatteNode::convertToOperations(ExecutionSystem *graph, CompositorConte addLink(graph, operationRGBToHSV_Image->getInputSocket(0)->getConnection()->getFromSocket(), operationAlpha->getInputSocket(0)); addLink(graph, operation->getOutputSocket(), operationAlpha->getInputSocket(1)); graph->addOperation(operationAlpha); - addPreviewOperation(graph, operationAlpha->getOutputSocket(), 9); + addPreviewOperation(graph, operationAlpha->getOutputSocket()); if (outputSocketImage->isConnected()) { outputSocketImage->relinkConnections(operationAlpha->getOutputSocket()); diff --git a/source/blender/compositor/nodes/COM_CompositorNode.cpp b/source/blender/compositor/nodes/COM_CompositorNode.cpp index 57821e7fe27..e2cc34bb6ce 100644 --- a/source/blender/compositor/nodes/COM_CompositorNode.cpp +++ b/source/blender/compositor/nodes/COM_CompositorNode.cpp @@ -39,6 +39,6 @@ void CompositorNode::convertToOperations(ExecutionSystem *graph, CompositorConte imageSocket->relinkConnections(colourAlphaProg->getInputSocket(0)); alphaSocket->relinkConnections(colourAlphaProg->getInputSocket(1)); graph->addOperation(colourAlphaProg); - addPreviewOperation(graph, colourAlphaProg->getInputSocket(0), 5); + addPreviewOperation(graph, colourAlphaProg->getInputSocket(0)); } } diff --git a/source/blender/compositor/nodes/COM_DifferenceMatteNode.cpp b/source/blender/compositor/nodes/COM_DifferenceMatteNode.cpp index c26fb4e5c5d..596fefff77c 100644 --- a/source/blender/compositor/nodes/COM_DifferenceMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_DifferenceMatteNode.cpp @@ -49,5 +49,5 @@ void DifferenceMatteNode::convertToOperations(ExecutionSystem *graph, Compositor addLink(graph, operationSet->getOutputSocket(), operation->getInputSocket(1)); outputSocketImage->relinkConnections(operation->getOutputSocket()); graph->addOperation(operation); - addPreviewOperation(graph, operation->getOutputSocket(), 5); + addPreviewOperation(graph, operation->getOutputSocket()); } diff --git a/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp b/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp index d7b4e481ec2..20a55ae195c 100644 --- a/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp @@ -52,7 +52,7 @@ void DistanceMatteNode::convertToOperations(ExecutionSystem *graph, CompositorCo addLink(graph, operation->getOutputSocket(), operationAlpha->getInputSocket(1)); graph->addOperation(operationAlpha); - addPreviewOperation(graph, operationAlpha->getOutputSocket(), 9); + addPreviewOperation(graph, operationAlpha->getOutputSocket()); if (outputSocketImage->isConnected()) { outputSocketImage->relinkConnections(operationAlpha->getOutputSocket()); diff --git a/source/blender/compositor/nodes/COM_FilterNode.cpp b/source/blender/compositor/nodes/COM_FilterNode.cpp index bdba69dc47d..7700bceb4ab 100644 --- a/source/blender/compositor/nodes/COM_FilterNode.cpp +++ b/source/blender/compositor/nodes/COM_FilterNode.cpp @@ -76,7 +76,7 @@ void FilterNode::convertToOperations(ExecutionSystem *graph, CompositorContext * inputImageSocket->relinkConnections(operation->getInputSocket(0), 1, graph); inputSocket->relinkConnections(operation->getInputSocket(1), 0, graph); outputSocket->relinkConnections(operation->getOutputSocket()); - addPreviewOperation(graph, operation->getOutputSocket(0), 5); + addPreviewOperation(graph, operation->getOutputSocket(0)); graph->addOperation(operation); } diff --git a/source/blender/compositor/nodes/COM_GroupNode.cpp b/source/blender/compositor/nodes/COM_GroupNode.cpp index 076d4f1501a..ec06a3acd7e 100644 --- a/source/blender/compositor/nodes/COM_GroupNode.cpp +++ b/source/blender/compositor/nodes/COM_GroupNode.cpp @@ -45,23 +45,16 @@ void GroupNode::ungroup(ExecutionSystem &system) InputSocket * inputSocket = inputsockets[index]; bNodeSocket *editorInput = inputSocket->getbNodeSocket(); if (editorInput->groupsock) { - if (inputSocket->isConnected()) { - SocketProxyNode * proxy = new SocketProxyNode(this->getbNode(), editorInput, editorInput->groupsock); - inputSocket->relinkConnections(proxy->getInputSocket(0), index, &system); - ExecutionSystemHelper::addNode(system.getNodes(), proxy); - } - else { - OutputSocketProxyNode * proxy = new OutputSocketProxyNode(this->getbNode(), editorInput, editorInput->groupsock); - inputSocket->relinkConnections(proxy->getInputSocket(0), index, &system); - ExecutionSystemHelper::addNode(system.getNodes(), proxy); - } + SocketProxyNode * proxy = new SocketProxyNode(this->getbNode(), editorInput, editorInput->groupsock); + inputSocket->relinkConnections(proxy->getInputSocket(0), index, &system); + ExecutionSystemHelper::addNode(system.getNodes(), proxy); } } for (index = 0 ; index < outputsockets.size();index ++) { OutputSocket * outputSocket = outputsockets[index]; bNodeSocket *editorOutput = outputSocket->getbNodeSocket(); - if (outputSocket->isConnected() && editorOutput->groupsock) { + if (editorOutput->groupsock) { SocketProxyNode * proxy = new SocketProxyNode(this->getbNode(), editorOutput->groupsock, editorOutput); outputSocket->relinkConnections(proxy->getOutputSocket(0)); ExecutionSystemHelper::addNode(system.getNodes(), proxy); diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp index 7f14b068136..cfd530173a9 100644 --- a/source/blender/compositor/nodes/COM_ImageNode.cpp +++ b/source/blender/compositor/nodes/COM_ImageNode.cpp @@ -105,7 +105,7 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext * break; } if (index == 0 && operation) { - addPreviewOperation(graph, operation->getOutputSocket(), 9); + addPreviewOperation(graph, operation->getOutputSocket()); } } } @@ -123,7 +123,7 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext * operation->setImageUser(imageuser); operation->setFramenumber(framenumber); graph->addOperation(operation); - addPreviewOperation(graph, operation->getOutputSocket(), 9); + addPreviewOperation(graph, operation->getOutputSocket()); } if (numberOfOutputs > 1) { diff --git a/source/blender/compositor/nodes/COM_LuminanceMatteNode.cpp b/source/blender/compositor/nodes/COM_LuminanceMatteNode.cpp index eb78657f3c4..37976216106 100644 --- a/source/blender/compositor/nodes/COM_LuminanceMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_LuminanceMatteNode.cpp @@ -53,7 +53,7 @@ void LuminanceMatteNode::convertToOperations(ExecutionSystem *graph, CompositorC addLink(graph, rgbToYUV->getInputSocket(0)->getConnection()->getFromSocket(), operation->getInputSocket(0)); addLink(graph, operationSet->getOutputSocket(), operation->getInputSocket(1)); graph->addOperation(operation); - addPreviewOperation(graph, operation->getOutputSocket(), 9); + addPreviewOperation(graph, operation->getOutputSocket()); if (outputSocketImage->isConnected()) { outputSocketImage->relinkConnections(operation->getOutputSocket()); diff --git a/source/blender/compositor/nodes/COM_MaskNode.cpp b/source/blender/compositor/nodes/COM_MaskNode.cpp new file mode 100644 index 00000000000..991c3f75e05 --- /dev/null +++ b/source/blender/compositor/nodes/COM_MaskNode.cpp @@ -0,0 +1,65 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#include "COM_MaskNode.h" +#include "COM_ExecutionSystem.h" +#include "COM_MaskOperation.h" + +extern "C" { + #include "DNA_mask_types.h" +} + +MaskNode::MaskNode(bNode *editorNode): Node(editorNode) +{ +} + +void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) +{ + const RenderData *data = &context->getScene()->r; + + InputSocket *inputImage = this->getInputSocket(0); + OutputSocket *outputMask = this->getOutputSocket(0); + + bNode *editorNode = this->getbNode(); + Mask *mask = (Mask *)editorNode->id; + + // always connect the output image + MaskOperation *operation = new MaskOperation(); + + if (inputImage->isConnected()) { + inputImage->relinkConnections(operation->getInputSocket(0), 0, graph); + } + else { + operation->setMaskWidth(data->xsch * data->size / 100.0f); + operation->setMaskHeight(data->ysch * data->size / 100.0f); + } + + if (outputMask->isConnected()) { + outputMask->relinkConnections(operation->getOutputSocket()); + } + + operation->setMask(mask); + operation->setFramenumber(context->getFramenumber()); + + graph->addOperation(operation); +} diff --git a/source/blender/compositor/nodes/COM_MaskNode.h b/source/blender/compositor/nodes/COM_MaskNode.h new file mode 100644 index 00000000000..9d2ea1889d9 --- /dev/null +++ b/source/blender/compositor/nodes/COM_MaskNode.h @@ -0,0 +1,38 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#include "COM_Node.h" +#include "DNA_node_types.h" + +/** + * @brief MaskNode + * @ingroup Node + */ +class MaskNode : public Node { + + +public: + MaskNode(bNode *editorNode); + void convertToOperations(ExecutionSystem *graph, CompositorContext *context); + +}; diff --git a/source/blender/compositor/nodes/COM_MixNode.cpp b/source/blender/compositor/nodes/COM_MixNode.cpp index 86ca5ebc237..42e32a4e55e 100644 --- a/source/blender/compositor/nodes/COM_MixNode.cpp +++ b/source/blender/compositor/nodes/COM_MixNode.cpp @@ -125,7 +125,7 @@ void MixNode::convertToOperations(ExecutionSystem *graph, CompositorContext * co color1Socket->relinkConnections(convertProg->getInputSocket(1), 1, graph); color2Socket->relinkConnections(convertProg->getInputSocket(2), 2, graph); outputSocket->relinkConnections(convertProg->getOutputSocket(0)); - addPreviewOperation(graph, convertProg->getOutputSocket(0), 5); + addPreviewOperation(graph, convertProg->getOutputSocket(0)); convertProg->getInputSocket(2)->setResizeMode(color2Socket->getResizeMode()); diff --git a/source/blender/compositor/nodes/COM_MovieClipNode.cpp b/source/blender/compositor/nodes/COM_MovieClipNode.cpp index 75831130936..eac581dc903 100644 --- a/source/blender/compositor/nodes/COM_MovieClipNode.cpp +++ b/source/blender/compositor/nodes/COM_MovieClipNode.cpp @@ -62,7 +62,7 @@ void MovieClipNode::convertToOperations(ExecutionSystem *graph, CompositorContex converter->setFromColorProfile(IB_PROFILE_LINEAR_RGB); converter->setToColorProfile(IB_PROFILE_SRGB); addLink(graph, operation->getOutputSocket(), converter->getInputSocket(0)); - addPreviewOperation(graph, converter->getOutputSocket(), 9); + addPreviewOperation(graph, converter->getOutputSocket()); if (outputMovieClip->isConnected()) { outputMovieClip->relinkConnections(converter->getOutputSocket()); } @@ -72,7 +72,7 @@ void MovieClipNode::convertToOperations(ExecutionSystem *graph, CompositorContex } } else { - addPreviewOperation(graph, operation->getOutputSocket(), 9); + addPreviewOperation(graph, operation->getOutputSocket()); if (outputMovieClip->isConnected()) { outputMovieClip->relinkConnections(operation->getOutputSocket()); } diff --git a/source/blender/compositor/nodes/COM_OutputFileNode.cpp b/source/blender/compositor/nodes/COM_OutputFileNode.cpp index cc060e9f7cd..ca18ea5fbf7 100644 --- a/source/blender/compositor/nodes/COM_OutputFileNode.cpp +++ b/source/blender/compositor/nodes/COM_OutputFileNode.cpp @@ -59,7 +59,7 @@ void OutputFileNode::convertToOperations(ExecutionSystem *graph, CompositorConte input->relinkConnections(outputOperation->getInputSocket(i)); } } - if (hasConnections) addPreviewOperation(graph, outputOperation->getInputSocket(0), 5); + if (hasConnections) addPreviewOperation(graph, outputOperation->getInputSocket(0)); graph->addOperation(outputOperation); } @@ -81,7 +81,7 @@ void OutputFileNode::convertToOperations(ExecutionSystem *graph, CompositorConte input->relinkConnections(outputOperation->getInputSocket(0)); graph->addOperation(outputOperation); if (!previewAdded) { - addPreviewOperation(graph, outputOperation->getInputSocket(0), 5); + addPreviewOperation(graph, outputOperation->getInputSocket(0)); previewAdded = true; } } diff --git a/source/blender/compositor/nodes/COM_RenderLayersNode.cpp b/source/blender/compositor/nodes/COM_RenderLayersNode.cpp index 4e99db090e1..8216205b925 100644 --- a/source/blender/compositor/nodes/COM_RenderLayersNode.cpp +++ b/source/blender/compositor/nodes/COM_RenderLayersNode.cpp @@ -63,7 +63,7 @@ void RenderLayersNode::testSocketConnection(ExecutionSystem *system, int outputS outputSocket->relinkConnections(operation->getOutputSocket()); system->addOperation(operation); if (outputSocketNumber == 0) { // only do for image socket if connected - addPreviewOperation(system, operation->getOutputSocket(), 9); + addPreviewOperation(system, operation->getOutputSocket()); } } else { @@ -71,7 +71,7 @@ void RenderLayersNode::testSocketConnection(ExecutionSystem *system, int outputS system->addOperation(operation); operation->setScene(scene); operation->setLayerId(layerId); - addPreviewOperation(system, operation->getOutputSocket(), 9); + addPreviewOperation(system, operation->getOutputSocket()); } else { delete operation; diff --git a/source/blender/compositor/nodes/COM_SocketProxyNode.cpp b/source/blender/compositor/nodes/COM_SocketProxyNode.cpp index 42dd49bd1da..fbb25afe266 100644 --- a/source/blender/compositor/nodes/COM_SocketProxyNode.cpp +++ b/source/blender/compositor/nodes/COM_SocketProxyNode.cpp @@ -46,50 +46,48 @@ SocketProxyNode::SocketProxyNode(bNode *editorNode, bNodeSocket *editorInput, bN void SocketProxyNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) { OutputSocket * outputsocket = this->getOutputSocket(0); - if (outputsocket->isConnected()) { - SocketProxyOperation *operation = new SocketProxyOperation(); - this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0)); - this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); - graph->addOperation(operation); - } -} - -void OutputSocketProxyNode::convertToOperations(ExecutionSystem *graph, CompositorContext * context) -{ - OutputSocket * outputsocket = this->getOutputSocket(0); InputSocket * inputsocket = this->getInputSocket(0); if (outputsocket->isConnected()) { - switch (outputsocket->getActualDataType()) { - case COM_DT_VALUE: - { - SetValueOperation *operation = new SetValueOperation(); - bNodeSocketValueFloat *dval = (bNodeSocketValueFloat*)inputsocket->getbNodeSocket()->default_value; - operation->setValue(dval->value); - this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); - graph->addOperation(operation); - break; - } - case COM_DT_COLOR: - { - SetColorOperation *operation = new SetColorOperation(); - bNodeSocketValueRGBA *dval = (bNodeSocketValueRGBA*)inputsocket->getbNodeSocket()->default_value; - operation->setChannels(dval->value); - this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); - graph->addOperation(operation); - break; - } - case COM_DT_VECTOR: - { - SetVectorOperation *operation = new SetVectorOperation(); - bNodeSocketValueVector *dval = (bNodeSocketValueVector*)inputsocket->getbNodeSocket()->default_value; - operation->setVector(dval->value); - this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); + if (inputsocket->isConnected()) { + SocketProxyOperation *operation = new SocketProxyOperation(); + inputsocket->relinkConnections(operation->getInputSocket(0)); + outputsocket->relinkConnections(operation->getOutputSocket(0)); graph->addOperation(operation); - break; } - /* quiet warnings */ - case COM_DT_UNKNOWN: - break; + else { + /* If input is not connected, add a constant value operation instead */ + switch (outputsocket->getActualDataType()) { + case COM_DT_VALUE: + { + SetValueOperation *operation = new SetValueOperation(); + bNodeSocketValueFloat *dval = (bNodeSocketValueFloat*)inputsocket->getbNodeSocket()->default_value; + operation->setValue(dval->value); + outputsocket->relinkConnections(operation->getOutputSocket(0)); + graph->addOperation(operation); + break; + } + case COM_DT_COLOR: + { + SetColorOperation *operation = new SetColorOperation(); + bNodeSocketValueRGBA *dval = (bNodeSocketValueRGBA*)inputsocket->getbNodeSocket()->default_value; + operation->setChannels(dval->value); + outputsocket->relinkConnections(operation->getOutputSocket(0)); + graph->addOperation(operation); + break; + } + case COM_DT_VECTOR: + { + SetVectorOperation *operation = new SetVectorOperation(); + bNodeSocketValueVector *dval = (bNodeSocketValueVector*)inputsocket->getbNodeSocket()->default_value; + operation->setVector(dval->value); + outputsocket->relinkConnections(operation->getOutputSocket(0)); + graph->addOperation(operation); + break; + } + /* quiet warnings */ + case COM_DT_UNKNOWN: + break; + } } } } diff --git a/source/blender/compositor/nodes/COM_SocketProxyNode.h b/source/blender/compositor/nodes/COM_SocketProxyNode.h index 1b5ee699211..b73ca24a45e 100644 --- a/source/blender/compositor/nodes/COM_SocketProxyNode.h +++ b/source/blender/compositor/nodes/COM_SocketProxyNode.h @@ -37,10 +37,4 @@ public: virtual bool isProxyNode() const { return true; } }; -class OutputSocketProxyNode: public SocketProxyNode { -public: - OutputSocketProxyNode(bNode *editorNode, bNodeSocket *editorInput, bNodeSocket *editorOutput): SocketProxyNode(editorNode, editorInput, editorOutput) {} - void convertToOperations(ExecutionSystem *graph, CompositorContext * context); -}; - #endif diff --git a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp index 9f9efbd8fe5..bf434c164c0 100644 --- a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp +++ b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp @@ -45,7 +45,7 @@ void SplitViewerNode::convertToOperations(ExecutionSystem *graph, CompositorCont splitViewerOperation->setXSplit(!this->getbNode()->custom2); image1Socket->relinkConnections(splitViewerOperation->getInputSocket(0), 0, graph); image2Socket->relinkConnections(splitViewerOperation->getInputSocket(1), 1, graph); - addPreviewOperation(graph, splitViewerOperation->getInputSocket(0), 0); + addPreviewOperation(graph, splitViewerOperation->getInputSocket(0)); graph->addOperation(splitViewerOperation); } } diff --git a/source/blender/compositor/nodes/COM_TextureNode.cpp b/source/blender/compositor/nodes/COM_TextureNode.cpp index be8bb623f4c..fe8a8e2250e 100644 --- a/source/blender/compositor/nodes/COM_TextureNode.cpp +++ b/source/blender/compositor/nodes/COM_TextureNode.cpp @@ -39,7 +39,7 @@ void TextureNode::convertToOperations(ExecutionSystem *system, CompositorContext operation->setTexture(texture); operation->setScene(context->getScene()); system->addOperation(operation); - addPreviewOperation(system, operation->getOutputSocket(), 9); + addPreviewOperation(system, operation->getOutputSocket()); if (this->getOutputSocket(0)->isConnected()) { TextureAlphaOperation *alphaOperation = new TextureAlphaOperation(); diff --git a/source/blender/compositor/nodes/COM_ViewerNode.cpp b/source/blender/compositor/nodes/COM_ViewerNode.cpp index 3282929af52..f5dab52d021 100644 --- a/source/blender/compositor/nodes/COM_ViewerNode.cpp +++ b/source/blender/compositor/nodes/COM_ViewerNode.cpp @@ -36,8 +36,8 @@ void ViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext * InputSocket *alphaSocket = this->getInputSocket(1); Image *image = (Image*)this->getbNode()->id; ImageUser * imageUser = (ImageUser*) this->getbNode()->storage; + bNode *editorNode = this->getbNode(); if (imageSocket->isConnected()) { - bNode *editorNode = this->getbNode(); ViewerOperation *viewerOperation = new ViewerOperation(); viewerOperation->setColorManagement(context->getScene()->r.color_mgt_flag & R_COLOR_MANAGEMENT); viewerOperation->setColorPredivide(context->getScene()->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); @@ -51,6 +51,6 @@ void ViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext * imageSocket->relinkConnections(viewerOperation->getInputSocket(0), 0, graph); alphaSocket->relinkConnections(viewerOperation->getInputSocket(1)); graph->addOperation(viewerOperation); - addPreviewOperation(graph, viewerOperation->getInputSocket(0), 0); + addPreviewOperation(graph, viewerOperation->getInputSocket(0)); } } diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp index babea459d6a..2280ee3a435 100644 --- a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp @@ -101,7 +101,10 @@ void BlurBaseOperation::deinitExecution() void BlurBaseOperation::updateSize(MemoryBuffer **memoryBuffers) { - float result[4]; - this->getInputSocketReader(1)->read(result, 0, 0, COM_PS_NEAREST, memoryBuffers); - this->size = result[0]; + if (!this->sizeavailable) { + float result[4]; + this->getInputSocketReader(1)->read(result, 0, 0, COM_PS_NEAREST, memoryBuffers); + this->size = result[0]; + this->sizeavailable = true; + } } diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp index 1050fc57194..71a87dce2a7 100644 --- a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp @@ -34,8 +34,9 @@ BokehBlurOperation::BokehBlurOperation() : NodeOperation() this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_COLOR); this->setComplex(true); + this->setOpenCL(true); - this->size = .01; + this->size = 1.0f; this->inputProgram = NULL; this->inputBokehProgram = NULL; @@ -90,7 +91,7 @@ void BokehBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer * int bufferwidth = inputBuffer->getWidth(); int bufferstartx = inputBuffer->getRect()->xmin; int bufferstarty = inputBuffer->getRect()->ymin; - int pixelSize = this->size*this->getWidth(); + int pixelSize = this->size*this->getWidth()/100.0f; int miny = y - pixelSize; int maxy = y + pixelSize; @@ -120,9 +121,9 @@ void BokehBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer * bufferindex +=offsetadd; } } - color[0] = tempColor[0]*(1.0/overallmultiplyerr); - color[1] = tempColor[1]*(1.0/overallmultiplyerg); - color[2] = tempColor[2]*(1.0/overallmultiplyerb); + color[0] = tempColor[0] * (1.0f / overallmultiplyerr); + color[1] = tempColor[1] * (1.0f / overallmultiplyerg); + color[2] = tempColor[2] * (1.0f / overallmultiplyerb); color[3] = 1.0f; } else { @@ -142,10 +143,10 @@ bool BokehBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBuffe rcti newInput; rcti bokehInput; - newInput.xmax = input->xmax + (size*this->getWidth()); - newInput.xmin = input->xmin - (size*this->getWidth()); - newInput.ymax = input->ymax + (size*this->getWidth()); - newInput.ymin = input->ymin - (size*this->getWidth()); + newInput.xmax = input->xmax + (size*this->getWidth()/100.0f); + newInput.xmin = input->xmin - (size*this->getWidth()/100.0f); + newInput.ymax = input->ymax + (size*this->getWidth()/100.0f); + newInput.ymin = input->ymin - (size*this->getWidth()/100.0f); NodeOperation *operation = getInputOperation(1); bokehInput.xmax = operation->getWidth(); @@ -165,3 +166,27 @@ bool BokehBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBuffe } return false; } + +static cl_kernel kernel = 0; +void BokehBlurOperation::executeOpenCL(cl_context context, cl_program program, cl_command_queue queue, + MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, + MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, + list<cl_kernel> *clKernelsToCleanUp) +{ + if (!kernel) { + kernel = COM_clCreateKernel(program, "bokehBlurKernel", NULL); + } + cl_int radius = this->getWidth()*this->size/100.0f; + cl_int step = this->getStep(); + + COM_clAttachMemoryBufferToKernelParameter(context, kernel, 0, -1, clMemToCleanUp, inputMemoryBuffers, this->inputBoundingBoxReader); + COM_clAttachMemoryBufferToKernelParameter(context, kernel, 1, 4, clMemToCleanUp, inputMemoryBuffers, this->inputProgram); + COM_clAttachMemoryBufferToKernelParameter(context, kernel, 2, -1, clMemToCleanUp, inputMemoryBuffers, this->inputBokehProgram); + COM_clAttachOutputMemoryBufferToKernelParameter(kernel, 3, clOutputBuffer); + COM_clAttachMemoryBufferOffsetToKernelParameter(kernel, 5, outputMemoryBuffer); + clSetKernelArg(kernel, 6, sizeof(cl_int), &radius); + clSetKernelArg(kernel, 7, sizeof(cl_int), &step); + COM_clAttachSizeToKernelParameter(kernel, 8); + + COM_clEnqueueRange(queue, kernel, outputMemoryBuffer, 9); +} diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.h b/source/blender/compositor/operations/COM_BokehBlurOperation.h index ce14faa8596..3cdd995b1df 100644 --- a/source/blender/compositor/operations/COM_BokehBlurOperation.h +++ b/source/blender/compositor/operations/COM_BokehBlurOperation.h @@ -56,5 +56,7 @@ public: bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); void setSize(float size) {this->size = size;} + + void executeOpenCL(cl_context context, cl_program program, cl_command_queue queue, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp); }; #endif diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.cpp b/source/blender/compositor/operations/COM_BokehImageOperation.cpp index 0279b9a5bdf..a0297b12961 100644 --- a/source/blender/compositor/operations/COM_BokehImageOperation.cpp +++ b/source/blender/compositor/operations/COM_BokehImageOperation.cpp @@ -34,25 +34,25 @@ void BokehImageOperation::initExecution() this->centerY = getHeight() / 2; this->center[0] = this->centerX; this->center[1] = this->centerY; - this->inverseRounding = 1.0-this->data->rounding; + this->inverseRounding = 1.0f - this->data->rounding; this->circularDistance = getWidth()/2; - this->flapRad = (M_PI*2)/this->data->flaps; - this->flapRadAdd = (this->data->angle/360.0)*M_PI*2; - while (this->flapRadAdd<0.0f) { - this->flapRadAdd+=M_PI*2; + this->flapRad = (float)(M_PI * 2) / this->data->flaps; + this->flapRadAdd = (this->data->angle / 360.0f) * (float)(M_PI * 2.0); + while (this->flapRadAdd < 0.0f) { + this->flapRadAdd += (float)(M_PI * 2.0); } - while (this->flapRadAdd>M_PI) { - this->flapRadAdd-=M_PI*2; + while (this->flapRadAdd > (float)M_PI) { + this->flapRadAdd -= (float)(M_PI * 2.0); } } void BokehImageOperation::detemineStartPointOfFlap(float r[2], int flapNumber, float distance) { - r[0] = sin(flapRad*flapNumber + flapRadAdd)*distance+centerX; - r[1] = cos(flapRad*flapNumber + flapRadAdd)*distance+centerY; + r[0] = sinf(flapRad * flapNumber + flapRadAdd) * distance + centerX; + r[1] = cosf(flapRad * flapNumber + flapRadAdd) * distance + centerY; } float BokehImageOperation::isInsideBokeh(float distance, float x, float y) { - float insideBokeh = 0.0; + float insideBokeh = 0.0f; const float deltaX = x - centerX; const float deltaY = y - centerY; float closestPoint[2]; @@ -63,7 +63,7 @@ float BokehImageOperation::isInsideBokeh(float distance, float x, float y) point[1] = y; const float distanceToCenter = len_v2v2(point, center); - const float bearing = (atan2f(deltaX, deltaY) + (M_PI*2)); + const float bearing = (atan2f(deltaX, deltaY) + (float)(M_PI * 2.0)); int flapNumber = (int)((bearing-flapRadAdd)/flapRad); detemineStartPointOfFlap(lineP1, flapNumber, distance); @@ -73,16 +73,16 @@ float BokehImageOperation::isInsideBokeh(float distance, float x, float y) const float distanceLineToCenter = len_v2v2(center, closestPoint); const float distanceRoundingToCenter = inverseRounding*distanceLineToCenter+this->data->rounding*distance; - const float catadioptricDistanceToCenter = distanceRoundingToCenter*this->data->catadioptric; - if (distanceRoundingToCenter>=distanceToCenter && catadioptricDistanceToCenter<=distanceToCenter) { - if (distanceRoundingToCenter-distanceToCenter<1.0) { + const float catadioptricDistanceToCenter = distanceRoundingToCenter * this->data->catadioptric; + if (distanceRoundingToCenter>=distanceToCenter && catadioptricDistanceToCenter <= distanceToCenter) { + if (distanceRoundingToCenter - distanceToCenter < 1.0f) { insideBokeh = (distanceRoundingToCenter-distanceToCenter); } - else if (this->data->catadioptric != 0.0 && distanceToCenter-catadioptricDistanceToCenter<1.0) { - insideBokeh = (distanceToCenter-catadioptricDistanceToCenter); + else if (this->data->catadioptric != 0.0f && distanceToCenter - catadioptricDistanceToCenter < 1.0f) { + insideBokeh = (distanceToCenter - catadioptricDistanceToCenter); } else { - insideBokeh = 1.0; + insideBokeh = 1.0f; } } return insideBokeh; @@ -90,11 +90,11 @@ float BokehImageOperation::isInsideBokeh(float distance, float x, float y) void BokehImageOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { float shift = this->data->lensshift; - float shift2 = shift/2.0f; + float shift2 = shift / 2.0f; float distance = this->circularDistance; float insideBokehMax = isInsideBokeh(distance, x, y); - float insideBokehMed = isInsideBokeh(distance-fabs(shift2*distance), x, y); - float insideBokehMin = isInsideBokeh(distance-fabs(shift*distance), x, y); + float insideBokehMed = isInsideBokeh(distance - fabsf(shift2 * distance), x, y); + float insideBokehMin = isInsideBokeh(distance - fabsf(shift * distance), x, y); if (shift<0) { color[0] = insideBokehMax; color[1] = insideBokehMed; diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.cpp b/source/blender/compositor/operations/COM_BoxMaskOperation.cpp index 0244be4cad3..ae83115ff69 100644 --- a/source/blender/compositor/operations/COM_BoxMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_BoxMaskOperation.cpp @@ -38,7 +38,7 @@ void BoxMaskOperation::initExecution() { this->inputMask = this->getInputSocketReader(0); this->inputValue = this->getInputSocketReader(1); - const double rad = DEG2RAD(this->data->rotation); + const double rad = DEG2RAD((double)this->data->rotation); this->cosine = cos(rad); this->sine = sin(rad); this->aspectRatio = ((float)this->getWidth())/this->getHeight(); @@ -60,12 +60,12 @@ void BoxMaskOperation::executePixel(float *color, float x, float y, PixelSampler this->inputMask->read(inputMask, x, y, sampler, inputBuffers); this->inputValue->read(inputValue, x, y, sampler, inputBuffers); - float halfHeight = (this->data->height)/2.0f; - float halfWidth = this->data->width/2.0f; - bool inside = rx > this->data->x-halfWidth - && rx < this->data->x+halfWidth - && ry > this->data->y-halfHeight - && ry < this->data->y+halfHeight; + float halfHeight = this->data->height / 2.0f; + float halfWidth = this->data->width / 2.0f; + bool inside = (rx > this->data->x - halfWidth && + rx < this->data->x + halfWidth && + ry > this->data->y - halfHeight && + ry < this->data->y + halfHeight); switch (this->maskType) { case CMP_NODE_MASKTYPE_ADD: diff --git a/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp b/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp index 9b7f87e38bc..f949b0a55fa 100644 --- a/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp +++ b/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp @@ -46,7 +46,8 @@ void ChangeHSVOperation::executePixel(float *outputValue, float x, float y, Pixe inputOperation->read(inputColor1, x, y, sampler, inputBuffers); outputValue[0] = inputColor1[0] + (this->hue - 0.5f); - if (outputValue[0]>1.0f) outputValue[0]-=1.0; else if (outputValue[0]<0.0) outputValue[0]+= 1.0; + if (outputValue[0] > 1.0f) outputValue[0] -= 1.0f; + else if (outputValue[0] < 0.0f) outputValue[0] += 1.0f; outputValue[1] = inputColor1[1] * this->saturation; outputValue[2] = inputColor1[2] * this->value; outputValue[3] = inputColor1[3]; diff --git a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cpp b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cpp index cc535cd95df..6fe6bde7c09 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cpp @@ -28,7 +28,7 @@ inline float colorbalance_cdl(float in, float offset, float power, float slope) float x = in * slope + offset; /* prevent NaN */ - CLAMP(x, 0.0, 1.0); + CLAMP(x, 0.0f, 1.0f); return powf(x, power); } diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp index af28b776892..82a71f6a7a8 100644 --- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp @@ -62,21 +62,21 @@ void ColorCorrectionOperation::executePixel(float *output, float x, float y, Pix float levelShadows = 0.0; float levelMidtones = 0.0; float levelHighlights = 0.0; -#define MARGIN 0.10 -#define MARGIN_DIV (0.5/MARGIN) - if (level < this->data->startmidtones-MARGIN) { +#define MARGIN 0.10f +#define MARGIN_DIV (0.5f / MARGIN) + if (level < this->data->startmidtones - MARGIN) { levelShadows = 1.0f; } - else if (level < this->data->startmidtones+MARGIN) { - levelMidtones = ((level-this->data->startmidtones)*MARGIN_DIV)+0.5; - levelShadows = 1.0 - levelMidtones; + else if (level < this->data->startmidtones + MARGIN) { + levelMidtones = ((level - this->data->startmidtones) * MARGIN_DIV) + 0.5f; + levelShadows = 1.0f - levelMidtones; } - else if (level < this->data->endmidtones-MARGIN) { + else if (level < this->data->endmidtones - MARGIN) { levelMidtones = 1.0f; } - else if (level < this->data->endmidtones+MARGIN) { - levelHighlights = ((level-this->data->endmidtones)*MARGIN_DIV)+0.5; - levelMidtones = 1.0 - levelHighlights; + else if (level < this->data->endmidtones + MARGIN) { + levelHighlights = ((level - this->data->endmidtones) * MARGIN_DIV) + 0.5f; + levelMidtones = 1.0f - levelHighlights; } else { levelHighlights = 1.0f; @@ -93,15 +93,15 @@ void ColorCorrectionOperation::executePixel(float *output, float x, float y, Pix g = inputImageColor[1]; b = inputImageColor[2]; - float invgamma = 1.0f/gamma; - float luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; + float invgamma = 1.0f / gamma; + float luma = 0.2126f * r + 0.7152f * g + 0.0722f * b; r = (luma + saturation * (r - luma)); g = (luma + saturation * (g - luma)); b = (luma + saturation * (b - luma)); - r = 0.5+((r-0.5)*contrast); - g = 0.5+((g-0.5)*contrast); - b = 0.5+((b-0.5)*contrast); + r = 0.5f + ((r - 0.5f) * contrast); + g = 0.5f + ((g - 0.5f) * contrast); + b = 0.5f + ((b - 0.5f) * contrast); r = powf(r*gain+lift, invgamma); g = powf(g*gain+lift, invgamma); diff --git a/source/blender/compositor/operations/COM_ColorCurveOperation.cpp b/source/blender/compositor/operations/COM_ColorCurveOperation.cpp index 8aee54013b1..a38012271f1 100644 --- a/source/blender/compositor/operations/COM_ColorCurveOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorCurveOperation.cpp @@ -28,6 +28,7 @@ extern "C" { #include "BKE_colortools.h" #ifdef __cplusplus } +#include "MEM_guardedalloc.h" #endif ColorCurveOperation::ColorCurveOperation(): CurveBaseOperation() @@ -59,6 +60,9 @@ void ColorCurveOperation::initExecution() void ColorCurveOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + CurveMapping* cumap = this->curveMapping; + CurveMapping* workingCopy = (CurveMapping*)MEM_dupallocN(cumap); + float black[4]; float white[4]; float fac[4]; @@ -67,26 +71,27 @@ void ColorCurveOperation::executePixel(float *color, float x, float y, PixelSamp this->inputBlackProgram->read(black, x, y, sampler, inputBuffers); this->inputWhiteProgram->read(white, x, y, sampler, inputBuffers); - curvemapping_set_black_white(this->curveMapping, black, white); + curvemapping_set_black_white(workingCopy, black, white); this->inputFacProgram->read(fac, x, y, sampler, inputBuffers); this->inputImageProgram->read(image, x, y, sampler, inputBuffers); - if (fac[0] >= 1.0) - curvemapping_evaluate_premulRGBF(this->curveMapping, color, image); - else if (*fac<=0.0) { + if (*fac >= 1.0f) + curvemapping_evaluate_premulRGBF(workingCopy, color, image); + else if (*fac <= 0.0f) { color[0] = image[0]; color[1] = image[1]; color[2] = image[2]; } else { - float col[4], mfac = 1.0f-*fac; - curvemapping_evaluate_premulRGBF(this->curveMapping, col, image); - color[0] = mfac*image[0] + *fac*col[0]; - color[1] = mfac*image[1] + *fac*col[1]; - color[2] = mfac*image[2] + *fac*col[2]; + float col[4], mfac = 1.0f - *fac; + curvemapping_evaluate_premulRGBF(workingCopy, col, image); + color[0] = mfac * image[0] + *fac * col[0]; + color[1] = mfac * image[1] + *fac * col[1]; + color[2] = mfac * image[2] + *fac * col[2]; } color[3] = image[3]; + MEM_freeN(workingCopy); } void ColorCurveOperation::deinitExecution() @@ -97,3 +102,61 @@ void ColorCurveOperation::deinitExecution() this->inputWhiteProgram = NULL; curvemapping_premultiply(this->curveMapping, 1); } + + +// Constant level curve mapping + +ConstantLevelColorCurveOperation::ConstantLevelColorCurveOperation(): CurveBaseOperation() +{ + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + + this->inputFacProgram = NULL; + this->inputImageProgram = NULL; + + this->setResolutionInputSocketIndex(1); +} +void ConstantLevelColorCurveOperation::initExecution() +{ + CurveBaseOperation::initExecution(); + this->inputFacProgram = this->getInputSocketReader(0); + this->inputImageProgram = this->getInputSocketReader(1); + + curvemapping_premultiply(this->curveMapping, 0); + + curvemapping_set_black_white(this->curveMapping, this->black, this->white); +} + +void ConstantLevelColorCurveOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +{ + float fac[4]; + float image[4]; + + + this->inputFacProgram->read(fac, x, y, sampler, inputBuffers); + this->inputImageProgram->read(image, x, y, sampler, inputBuffers); + + if (*fac >= 1.0f) + curvemapping_evaluate_premulRGBF(this->curveMapping, color, image); + else if (*fac <= 0.0f) { + color[0] = image[0]; + color[1] = image[1]; + color[2] = image[2]; + } + else { + float col[4], mfac = 1.0f - *fac; + curvemapping_evaluate_premulRGBF(this->curveMapping, col, image); + color[0] = mfac * image[0] + *fac * col[0]; + color[1] = mfac * image[1] + *fac * col[1]; + color[2] = mfac * image[2] + *fac * col[2]; + } + color[3] = image[3]; +} + +void ConstantLevelColorCurveOperation::deinitExecution() +{ + this->inputFacProgram = NULL; + this->inputImageProgram = NULL; + curvemapping_premultiply(this->curveMapping, 1); +} diff --git a/source/blender/compositor/operations/COM_ColorCurveOperation.h b/source/blender/compositor/operations/COM_ColorCurveOperation.h index 15f9fd25e81..6ce5befb14a 100644 --- a/source/blender/compositor/operations/COM_ColorCurveOperation.h +++ b/source/blender/compositor/operations/COM_ColorCurveOperation.h @@ -53,4 +53,37 @@ public: */ void deinitExecution(); }; + +class ConstantLevelColorCurveOperation : public CurveBaseOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputFacProgram; + SocketReader * inputImageProgram; + float black[3]; + float white[3]; + +public: + ConstantLevelColorCurveOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setBlackLevel(float black[3]) {this->black[0] =black[0];this->black[1] =black[1];this->black[2] =black[2]; } + void setWhiteLevel(float white[3]) {this->white[0] =white[0];this->white[1] =white[1];this->white[2] =white[2]; } +}; + #endif diff --git a/source/blender/compositor/operations/COM_CompositorOperation.h b/source/blender/compositor/operations/COM_CompositorOperation.h index 41d43f896bb..13cb4f28324 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.h +++ b/source/blender/compositor/operations/COM_CompositorOperation.h @@ -63,7 +63,7 @@ public: bool isOutputOperation(bool rendering) const {return true;} void initExecution(); void deinitExecution(); - const int getRenderPriority() const {return 7;} + const CompositorPriority getRenderPriority() const {return COM_PRIORITY_MEDIUM;} void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); }; #endif diff --git a/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp b/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp index 628daa7c775..0b1ac1b2127 100644 --- a/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp @@ -57,16 +57,16 @@ void DifferenceMatteOperation::executePixel(float *outputValue, float x, float y this->inputImage1Program->read(inColor1, x, y, sampler, inputBuffers); this->inputImage2Program->read(inColor2, x, y, sampler, inputBuffers); - difference = (fabs(inColor2[0] - inColor1[0]) + - fabs(inColor2[1] - inColor1[1]) + - fabs(inColor2[2] - inColor1[2])); + difference = (fabsf(inColor2[0] - inColor1[0]) + + fabsf(inColor2[1] - inColor1[1]) + + fabsf(inColor2[2] - inColor1[2])); - /*average together the distances*/ - difference=difference/3.0; + /* average together the distances */ + difference = difference / 3.0f; /*make 100% transparent*/ if (difference < tolerence) { - outputValue[0]=0.0; + outputValue[0] = 0.0f; } /*in the falloff region, make partially transparent */ else if (difference < falloff+tolerence) { diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp index 30a09a45ade..43cba09d16f 100644 --- a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp @@ -51,17 +51,17 @@ void DirectionalBlurOperation::initExecution() const float height = getHeight(); const float a = angle; - const float itsc = 1.f / pow(2.f, (float)iterations); + const float itsc = 1.0f / powf(2.0f, (float)iterations); float D; D = distance * sqrtf(width*width + height*height); center_x_pix = center_x * width; center_y_pix = center_y * height; - tx= itsc * D * cos(a); - ty= -itsc * D * sin(a); - sc= itsc * zoom; - rot = itsc * spin; + tx = itsc * D * cosf(a); + ty = -itsc * D * sinf(a); + sc = itsc * zoom; + rot = itsc * spin; } diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp b/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp index 85a629f7365..650c57dd8dc 100644 --- a/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp @@ -38,7 +38,7 @@ void EllipseMaskOperation::initExecution() { this->inputMask = this->getInputSocketReader(0); this->inputValue = this->getInputSocketReader(1); - const double rad = DEG2RAD(this->data->rotation); + const double rad = DEG2RAD((double)this->data->rotation); this->cosine = cos(rad); this->sine = sin(rad); this->aspectRatio = ((float)this->getWidth())/this->getHeight(); diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp index ad8f3b12387..ad58631f2c1 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp @@ -26,13 +26,12 @@ FastGaussianBlurOperation::FastGaussianBlurOperation(): BlurBaseOperation() { - this->iirgaus = false; + this->iirgaus = NULL; } void FastGaussianBlurOperation::executePixel(float *color,int x, int y, MemoryBuffer *inputBuffers[], void *data) { MemoryBuffer *newData = (MemoryBuffer*)data; - newData->read(color, x, y); } @@ -51,10 +50,7 @@ bool FastGaussianBlurOperation::determineDependingAreaOfInterest(rcti *input, Re } else { if (this->iirgaus) { - newInput.xmax = input->xmax + (sx); - newInput.xmin = input->xmin - (sx); - newInput.ymax = input->ymax + (sy); - newInput.ymin = input->ymin - (sy); + return false; } else { newInput.xmin = 0; @@ -66,38 +62,51 @@ bool FastGaussianBlurOperation::determineDependingAreaOfInterest(rcti *input, Re } } -void *FastGaussianBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) +void FastGaussianBlurOperation::initExecution() { - MemoryBuffer *newBuf = (MemoryBuffer*)this->inputProgram->initializeTileData(rect, memoryBuffers); - MemoryBuffer *copy = newBuf->duplicate(); - updateSize(memoryBuffers); - - int c; - sx = data->sizex * this->size/2.0f; - sy = data->sizey * this->size/2.0f; - this->iirgaus = true; - - if ((sx == sy) && (sx > 0.f)) { - for (c=0; c<COM_NUMBER_OF_CHANNELS; ++c) - IIR_gauss(copy, sx, c, 3); + BlurBaseOperation::initExecution(); + BlurBaseOperation::initMutex(); +} + +void FastGaussianBlurOperation::deinitExecution() +{ + if (this->iirgaus) { + delete this->iirgaus; + this->iirgaus = NULL; } - else { - if (sx > 0.f) { + BlurBaseOperation::deinitMutex(); +} + +void *FastGaussianBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) +{ + BLI_mutex_lock(this->getMutex()); + if (!iirgaus) { + MemoryBuffer *newBuf = (MemoryBuffer*)this->inputProgram->initializeTileData(rect, memoryBuffers); + MemoryBuffer *copy = newBuf->duplicate(); + updateSize(memoryBuffers); + + int c; + sx = data->sizex * this->size/2.0f; + sy = data->sizey * this->size/2.0f; + + if ((sx == sy) && (sx > 0.f)) { for (c=0; c<COM_NUMBER_OF_CHANNELS; ++c) - IIR_gauss(copy, sx, c, 1); + IIR_gauss(copy, sx, c, 3); } - if (sy > 0.f) { - for (c=0; c<COM_NUMBER_OF_CHANNELS; ++c) - IIR_gauss(copy, sy, c, 2); + else { + if (sx > 0.f) { + for (c=0; c<COM_NUMBER_OF_CHANNELS; ++c) + IIR_gauss(copy, sx, c, 1); + } + if (sy > 0.f) { + for (c=0; c<COM_NUMBER_OF_CHANNELS; ++c) + IIR_gauss(copy, sy, c, 2); + } } + this->iirgaus = copy; } - return copy; -} - -void FastGaussianBlurOperation::deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data) -{ - MemoryBuffer *newData = (MemoryBuffer*)data; - delete newData; + BLI_mutex_unlock(this->getMutex()); + return iirgaus; } void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, int chan, int xy) diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h index 6c3e373472b..1f71fe7f9ed 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h @@ -30,7 +30,7 @@ class FastGaussianBlurOperation: public BlurBaseOperation { private: float sx; float sy; - bool iirgaus; + MemoryBuffer* iirgaus; public: FastGaussianBlurOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); @@ -38,7 +38,8 @@ public: static void IIR_gauss(MemoryBuffer *src, float sigma, int channel, int xy); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); - void deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data); + void deinitExecution(); + void initExecution(); }; #endif diff --git a/source/blender/compositor/operations/COM_FogGlowImageOperation.cpp b/source/blender/compositor/operations/COM_FogGlowImageOperation.cpp index 600bfde64d9..05a758aca7f 100644 --- a/source/blender/compositor/operations/COM_FogGlowImageOperation.cpp +++ b/source/blender/compositor/operations/COM_FogGlowImageOperation.cpp @@ -37,7 +37,7 @@ void FogGlowImageOperation::executePixel(float *color, float x, float y, PixelSa u = 2.f*(x / (float)512) - 1.f; r = (u*u + v*v)*256; d = -sqrtf(sqrtf(sqrtf(r))); - w = (0.5f + 0.5f*cos((double)u*M_PI))*(0.5f + 0.5f*cos((double)v*M_PI)); + w = (0.5f + 0.5f * cosf(u * (float)M_PI)) * (0.5f + 0.5f * cosf(v * (float)M_PI)); color[0] = expf(d*cs_r) * w; color[1] = expf(d*cs_g) * w; color[2] = expf(d*cs_b) * w; diff --git a/source/blender/compositor/operations/COM_GammaOperation.cpp b/source/blender/compositor/operations/COM_GammaOperation.cpp index f0887d4adee..989ffd5dfba 100644 --- a/source/blender/compositor/operations/COM_GammaOperation.cpp +++ b/source/blender/compositor/operations/COM_GammaOperation.cpp @@ -46,9 +46,9 @@ void GammaOperation::executePixel(float *color, float x, float y, PixelSampler s this->inputGammaProgram->read(inputGamma, x, y, sampler, inputBuffers); const float gamma = inputGamma[0]; /* check for negative to avoid nan's */ - color[0] = inputValue[0]>0.0f?pow(inputValue[0], gamma):inputValue[0]; - color[1] = inputValue[1]>0.0f?pow(inputValue[1], gamma):inputValue[1]; - color[2] = inputValue[2]>0.0f?pow(inputValue[2], gamma):inputValue[2]; + color[0] = inputValue[0] > 0.0f ? powf(inputValue[0], gamma) : inputValue[0]; + color[1] = inputValue[1] > 0.0f ? powf(inputValue[1], gamma) : inputValue[1]; + color[2] = inputValue[2] > 0.0f ? powf(inputValue[2], gamma) : inputValue[2]; color[3] = inputValue[3]; } diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp index b5d175729f3..e522d334d8b 100644 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp @@ -43,6 +43,8 @@ void *GaussianBokehBlurOperation::initializeTileData(rcti *rect, MemoryBuffer ** void GaussianBokehBlurOperation::initExecution() { + BlurBaseOperation::initExecution(); + if (this->sizeavailable) { updateGauss(NULL); } @@ -145,11 +147,11 @@ void GaussianBokehBlurOperation::executePixel(float *color, int x, int y, Memory bufferindex +=offsetadd; } } - float divider = 1.0/overallmultiplyer; - color[0] = tempColor[0]*divider; - color[1] = tempColor[1]*divider; - color[2] = tempColor[2]*divider; - color[3] = tempColor[3]*divider; + float divider = 1.0f / overallmultiplyer; + color[0] = tempColor[0] * divider; + color[1] = tempColor[1] * divider; + color[2] = tempColor[2] * divider; + color[3] = tempColor[3] * divider; } void GaussianBokehBlurOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp index 121bbbd45a0..2eb51b4577f 100644 --- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp @@ -45,6 +45,8 @@ void *GaussianXBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memo void GaussianXBlurOperation::initExecution() { + BlurBaseOperation::initExecution(); + if (this->sizeavailable) { float rad = size*this->data->sizex; if (rad<1) @@ -75,7 +77,7 @@ void GaussianXBlurOperation::executePixel(float *color, int x, int y, MemoryBuff tempColor[1] = 0; tempColor[2] = 0; tempColor[3] = 0; - float overallmultiplyer = 0; + float overallmultiplyer = 0.0f; MemoryBuffer *inputBuffer = (MemoryBuffer*)data; float *buffer = inputBuffer->getBuffer(); int bufferwidth = inputBuffer->getWidth(); @@ -104,11 +106,11 @@ void GaussianXBlurOperation::executePixel(float *color, int x, int y, MemoryBuff overallmultiplyer += multiplyer; bufferindex +=offsetadd; } - float divider = 1.0/overallmultiplyer; - color[0] = tempColor[0]*divider; - color[1] = tempColor[1]*divider; - color[2] = tempColor[2]*divider; - color[3] = tempColor[3]*divider; + float divider = 1.0f / overallmultiplyer; + color[0] = tempColor[0] * divider; + color[1] = tempColor[1] * divider; + color[2] = tempColor[2] * divider; + color[3] = tempColor[3] * divider; } void GaussianXBlurOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp index cab3e3d6094..28e8e548530 100644 --- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp @@ -101,11 +101,11 @@ void GaussianYBlurOperation::executePixel(float *color, int x, int y, MemoryBuff tempColor[3] += multiplyer * buffer[bufferindex+3]; overallmultiplyer += multiplyer; } - float divider = 1.0/overallmultiplyer; - color[0] = tempColor[0]*divider; - color[1] = tempColor[1]*divider; - color[2] = tempColor[2]*divider; - color[3] = tempColor[3]*divider; + float divider = 1.0f / overallmultiplyer; + color[0] = tempColor[0] * divider; + color[1] = tempColor[1] * divider; + color[2] = tempColor[2] * divider; + color[3] = tempColor[3] * divider; } void GaussianYBlurOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp index 2970c396493..2afcc2e5cc7 100644 --- a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp +++ b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp @@ -63,8 +63,8 @@ void HueSaturationValueCorrectOperation::executePixel(float *output, float x, fl f = curvemapping_evaluateF(this->curveMapping, 2, hsv[0]); hsv[2] *= (f * 2.f); - hsv[0] = hsv[0] - floor(hsv[0]); /* mod 1.0 */ - CLAMP(hsv[1], 0.f, 1.f); + hsv[0] = hsv[0] - floorf(hsv[0]); /* mod 1.0 */ + CLAMP(hsv[1], 0.0f, 1.0f); output[0] = hsv[0]; output[1] = hsv[1]; diff --git a/source/blender/compositor/operations/COM_ImageOperation.cpp b/source/blender/compositor/operations/COM_ImageOperation.cpp index 020dfdbdc14..04cd91d3c3a 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.cpp +++ b/source/blender/compositor/operations/COM_ImageOperation.cpp @@ -99,8 +99,8 @@ void BaseImageOperation::determineResolution(unsigned int resolution[], unsigned { ImBuf *stackbuf = getImBuf(); - resolution[0] = 0; - resolution[1] = 0; + resolution[0] = 0; + resolution[1] = 0; if (stackbuf) { resolution[0] = stackbuf->x; diff --git a/source/blender/compositor/operations/COM_MapUVOperation.cpp b/source/blender/compositor/operations/COM_MapUVOperation.cpp index 7b393cc04a8..035f5584065 100644 --- a/source/blender/compositor/operations/COM_MapUVOperation.cpp +++ b/source/blender/compositor/operations/COM_MapUVOperation.cpp @@ -61,16 +61,16 @@ void MapUVOperation::executePixel(float *color, float x, float y, PixelSampler s /* adaptive sampling, red (U) channel */ this->inputUVProgram->read(uv_a, x-1, y, COM_PS_NEAREST, inputBuffers); this->inputUVProgram->read(uv_b, x+1, y, COM_PS_NEAREST, inputBuffers); - uv_l = uv_a[2]!=0.f? fabs(inputUV[0] - uv_a[0]) : 0.f; - uv_r = uv_b[2]!=0.f? fabs(inputUV[0] - uv_b[0]) : 0.f; + uv_l = uv_a[2]!=0.f? fabsf(inputUV[0] - uv_a[0]) : 0.f; + uv_r = uv_b[2]!=0.f? fabsf(inputUV[0] - uv_b[0]) : 0.f; dx = 0.5f * (uv_l + uv_r); /* adaptive sampling, green (V) channel */ this->inputUVProgram->read(uv_a, x, y-1, COM_PS_NEAREST, inputBuffers); this->inputUVProgram->read(uv_b, x, y+1, COM_PS_NEAREST, inputBuffers); - uv_u = uv_a[2]!=0.f? fabs(inputUV[1] - uv_a[1]) : 0.f; - uv_d = uv_b[2]!=0.f? fabs(inputUV[1] - uv_b[1]) : 0.f; + uv_u = uv_a[2]!=0.f? fabsf(inputUV[1] - uv_a[1]) : 0.f; + uv_d = uv_b[2]!=0.f? fabsf(inputUV[1] - uv_b[1]) : 0.f; dy = 0.5f * (uv_u + uv_d); diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp new file mode 100644 index 00000000000..a7c1de323f1 --- /dev/null +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -0,0 +1,124 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + +#include "COM_MaskOperation.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" + +#include "DNA_scene_types.h" + +extern "C" { + #include "BKE_mask.h" +} + +MaskOperation::MaskOperation(): NodeOperation() +{ + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->mask = NULL; + this->maskWidth = 0; + this->maskHeight = 0; + this->framenumber = 0; + this->rasterizedMask = NULL; + setComplex(true); +} + +void MaskOperation::initExecution() +{ + initMutex(); + this->rasterizedMask = NULL; +} + +void MaskOperation::deinitExecution() +{ + if (this->rasterizedMask) { + MEM_freeN(rasterizedMask); + this->rasterizedMask = NULL; + } +} + +void *MaskOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) +{ + if (this->rasterizedMask) + return this->rasterizedMask; + + if (!this->mask) + return NULL; + + BLI_mutex_lock(getMutex()); + if (this->rasterizedMask == NULL) { + int width = this->getWidth(); + int height = this->getHeight(); + float *buffer; + + buffer = (float *)MEM_callocN(sizeof(float) * width * height, "rasterized mask"); + BKE_mask_rasterize(mask, width, height, buffer, TRUE, TRUE); + + this->rasterizedMask = buffer; + } + BLI_mutex_unlock(getMutex()); + + return this->rasterizedMask; +} + +void MaskOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) +{ + if (maskWidth == 0 || maskHeight == 0) { + NodeOperation::determineResolution(resolution, preferredResolution); + } + else { + unsigned int nr[2]; + + nr[0] = maskWidth; + nr[1] = maskHeight; + + NodeOperation::determineResolution(resolution, nr); + + resolution[0] = maskWidth; + resolution[1] = maskHeight; + } +} + +void MaskOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) +{ + if (!data) { + color[0] = 0; + color[1] = 0; + color[2] = 0; + color[3] = 1.0f; + } + else { + float *buffer = (float*) data; + int index = (y * this->getWidth() + x); + + color[0] = buffer[index]; + color[1] = buffer[index]; + color[2] = buffer[index]; + color[3] = 1.0f; + } +} + + diff --git a/source/blender/compositor/operations/COM_MaskOperation.h b/source/blender/compositor/operations/COM_MaskOperation.h new file mode 100644 index 00000000000..9f2c7f53f56 --- /dev/null +++ b/source/blender/compositor/operations/COM_MaskOperation.h @@ -0,0 +1,66 @@ +/* + * Copyright 2012, Blender Foundation. + * + * 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. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Sergey Sharybin + */ + + +#ifndef _COM_MaskOperation_h +#define _COM_MaskOperation_h + +#include "COM_NodeOperation.h" +#include "DNA_scene_types.h" +#include "DNA_mask_types.h" +#include "BLI_listbase.h" +#include "IMB_imbuf_types.h" + +/** + * Class with implementation of mask rasterization + */ +class MaskOperation : public NodeOperation { +protected: + Mask *mask; + int maskWidth; + int maskHeight; + int framenumber; + float *rasterizedMask; + + /** + * Determine the output resolution. The resolution is retrieved from the Renderer + */ + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + +public: + MaskOperation(); + + void initExecution(); + void deinitExecution(); + + void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + + void setMask(Mask *mask) {this->mask = mask;} + void setMaskWidth(int width) {this->maskWidth = width;} + void setMaskHeight(int height) {this->maskHeight = height;} + void setFramenumber(int framenumber) {this->framenumber = framenumber;} + + void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.cpp b/source/blender/compositor/operations/COM_MathBaseOperation.cpp index 2ea5f85253b..b943ec88fde 100644 --- a/source/blender/compositor/operations/COM_MathBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_MathBaseOperation.cpp @@ -196,8 +196,8 @@ void MathPowerOperation::executePixel(float *outputValue, float x, float y, Pixe else { float y_mod_1 = fmod(inputValue2[0], 1); /* if input value is not nearly an integer, fall back to zero, nicer than straight rounding */ - if (y_mod_1 > 0.999 || y_mod_1 < 0.001) { - outputValue[0] = pow(inputValue1[0], (float)floor(inputValue2[0] + 0.5)); + if (y_mod_1 > 0.999f || y_mod_1 < 0.001f) { + outputValue[0] = pow(inputValue1[0], floorf(inputValue2[0] + 0.5f)); } else { outputValue[0] = 0.0; diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl b/source/blender/compositor/operations/COM_OpenCLKernels.cl index 40932e54bc7..aeccfcab8b5 100644 --- a/source/blender/compositor/operations/COM_OpenCLKernels.cl +++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl @@ -1,10 +1,52 @@ /// This file contains all opencl kernels for node-operation implementations -__kernel void testKernel(__global __write_only image2d_t output) +// Global SAMPLERS +const sampler_t SAMPLER_NEAREST = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST; + +__constant const int2 zero = {0,0}; + +// KERNEL --- BOKEH BLUR --- +__kernel void bokehBlurKernel(__global __read_only image2d_t boundingBox, __global __read_only image2d_t inputImage, + __global __read_only image2d_t bokehImage, __global __write_only image2d_t output, + int2 offsetInput, int2 offsetOutput, int radius, int step, int2 dimension, int2 offset) { - int x = get_global_id(0); - int y = get_global_id(1); - int2 coords = {x, y}; - float4 color = {0.0f, 1.0f, 0.0f, 1.0f}; + int2 coords = {get_global_id(0), get_global_id(1)}; + coords += offset; + float tempBoundingBox; + float4 color = {0.0f,0.0f,0.0f,0.0f}; + float4 multiplyer = {0.0f,0.0f,0.0f,0.0f}; + float4 bokeh; + const float radius2 = radius*2.0f; + const int2 realCoordinate = coords + offsetOutput; + + tempBoundingBox = read_imagef(boundingBox, SAMPLER_NEAREST, coords).s0; + + if (tempBoundingBox > 0.0f) { + const int2 bokehImageDim = get_image_dim(bokehImage); + const int2 bokehImageCenter = bokehImageDim/2; + const int2 minXY = max(realCoordinate - radius, zero); + const int2 maxXY = min(realCoordinate + radius, dimension); + int nx, ny; + + float2 uv; + int2 inputXy; + + for (ny = minXY.y, inputXy.y = ny - offsetInput.y ; ny < maxXY.y ; ny +=step, inputXy.y+=step) { + uv.y = ((realCoordinate.y-ny)/radius2)*bokehImageDim.y+bokehImageCenter.y; + + for (nx = minXY.x, inputXy.x = nx - offsetInput.x; nx < maxXY.x ; nx +=step, inputXy.x+=step) { + uv.x = ((realCoordinate.x-nx)/radius2)*bokehImageDim.x+bokehImageCenter.x; + bokeh = read_imagef(bokehImage, SAMPLER_NEAREST, uv); + color += bokeh * read_imagef(inputImage, SAMPLER_NEAREST, inputXy); + multiplyer += bokeh; + } + } + color /= multiplyer; + + } else { + int2 imageCoordinates = realCoordinate - offsetInput; + color = read_imagef(inputImage, SAMPLER_NEAREST, imageCoordinates); + } + write_imagef(output, coords, color); } diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl.cpp b/source/blender/compositor/operations/COM_OpenCLKernels.cl.cpp deleted file mode 100644 index 1024d460044..00000000000 --- a/source/blender/compositor/operations/COM_OpenCLKernels.cl.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/// @todo: this source needs to be generated from COM_OpenCLKernels.cl. -/// not implemented yet. new data to h - -const char *sourcecode = "/// This file contains all opencl kernels for node-operation implementations \n" \ -"\n" \ -"__kernel void testKernel(__global __write_only image2d_t output)\n" \ -"{\n" \ -" int x = get_global_id(0);\n" \ -" int y = get_global_id(1);\n" \ -" int2 coords = {x, y}; \n" \ -" float4 color = {0.0f, 1.0f, 0.0f, 1.0f};\n" \ -" write_imagef(output, coords, color);\n" \ -"}\n" \ -"\0\n"; - diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl.h b/source/blender/compositor/operations/COM_OpenCLKernels.cl.h new file mode 100644 index 00000000000..3cf33c75272 --- /dev/null +++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl.h @@ -0,0 +1,55 @@ +/* clkernelstoh output of file <COM_OpenCLKernels_cl> */ + +const char * clkernelstoh_COM_OpenCLKernels_cl = "/// This file contains all opencl kernels for node-operation implementations\n" \ +"\n" \ +"// Global SAMPLERS\n" \ +"const sampler_t SAMPLER_NEAREST = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" \ +"\n" \ +"__constant const int2 zero = {0,0};\n" \ +"\n" \ +"// KERNEL --- BOKEH BLUR ---\n" \ +"__kernel void bokehBlurKernel(__global __read_only image2d_t boundingBox, __global __read_only image2d_t inputImage,\n" \ +" __global __read_only image2d_t bokehImage, __global __write_only image2d_t output,\n" \ +" int2 offsetInput, int2 offsetOutput, int radius, int step, int2 dimension, int2 offset)\n" \ +"{\n" \ +" int2 coords = {get_global_id(0), get_global_id(1)};\n" \ +" coords += offset;\n" \ +" float tempBoundingBox;\n" \ +" float4 color = {0.0f,0.0f,0.0f,0.0f};\n" \ +" float4 multiplyer = {0.0f,0.0f,0.0f,0.0f};\n" \ +" float4 bokeh;\n" \ +" const float radius2 = radius*2.0f;\n" \ +" const int2 realCoordinate = coords + offsetOutput;\n" \ +"\n" \ +" tempBoundingBox = read_imagef(boundingBox, SAMPLER_NEAREST, coords).s0;\n" \ +"\n" \ +" if (tempBoundingBox > 0.0f) {\n" \ +" const int2 bokehImageDim = get_image_dim(bokehImage);\n" \ +" const int2 bokehImageCenter = bokehImageDim/2;\n" \ +" const int2 minXY = max(realCoordinate - radius, zero);;\n" \ +" const int2 maxXY = min(realCoordinate + radius, dimension);;\n" \ +" int nx, ny;\n" \ +"\n" \ +" float2 uv;\n" \ +" int2 inputXy;\n" \ +"\n" \ +" for (ny = minXY.y, inputXy.y = ny - offsetInput.y ; ny < maxXY.y ; ny +=step, inputXy.y+=step) {\n" \ +" uv.y = ((realCoordinate.y-ny)/radius2)*bokehImageDim.y+bokehImageCenter.y;\n" \ +"\n" \ +" for (nx = minXY.x, inputXy.x = nx - offsetInput.x; nx < maxXY.x ; nx +=step, inputXy.x+=step) {\n" \ +" uv.x = ((realCoordinate.x-nx)/radius2)*bokehImageDim.x+bokehImageCenter.x;\n" \ +" bokeh = read_imagef(bokehImage, SAMPLER_NEAREST, uv);\n" \ +" color += bokeh * read_imagef(inputImage, SAMPLER_NEAREST, inputXy);\n" \ +" multiplyer += bokeh;\n" \ +" }\n" \ +" }\n" \ +" color /= multiplyer;\n" \ +"\n" \ +" } else {\n" \ +" int2 imageCoordinates = realCoordinate - offsetInput;\n" \ +" color = read_imagef(inputImage, SAMPLER_NEAREST, imageCoordinates);\n" \ +" }\n" \ +"\n" \ +" write_imagef(output, coords, color);\n" \ +"}\n" \ +"\0"; diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.h b/source/blender/compositor/operations/COM_OutputFileOperation.h index 0e37432ca5b..9b9fb023467 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.h +++ b/source/blender/compositor/operations/COM_OutputFileOperation.h @@ -49,7 +49,7 @@ public: bool isOutputOperation(bool rendering) const {return true;} void initExecution(); void deinitExecution(); - const int getRenderPriority() const {return 7;} + const CompositorPriority getRenderPriority() const {return COM_PRIORITY_LOW;} }; /* extra info for OpenEXR layers */ @@ -83,7 +83,7 @@ public: bool isOutputOperation(bool rendering) const {return true;} void initExecution(); void deinitExecution(); - const int getRenderPriority() const {return 7;} + const CompositorPriority getRenderPriority() const {return COM_PRIORITY_LOW;} }; #endif diff --git a/source/blender/compositor/operations/COM_PreviewOperation.cpp b/source/blender/compositor/operations/COM_PreviewOperation.cpp index a7b6fc93b25..4975f13a285 100644 --- a/source/blender/compositor/operations/COM_PreviewOperation.cpp +++ b/source/blender/compositor/operations/COM_PreviewOperation.cpp @@ -46,7 +46,6 @@ PreviewOperation::PreviewOperation() : NodeOperation() this->input = NULL; this->divider = 1.0f; this->node = NULL; - this->priority = 0; } void PreviewOperation::initExecution() @@ -129,7 +128,7 @@ void PreviewOperation::determineResolution(unsigned int resolution[], unsigned i resolution[1] = height; } -const int PreviewOperation::getRenderPriority() const +const CompositorPriority PreviewOperation::getRenderPriority() const { - return this->priority; + return COM_PRIORITY_LOW; } diff --git a/source/blender/compositor/operations/COM_PreviewOperation.h b/source/blender/compositor/operations/COM_PreviewOperation.h index 8450b7fc556..3d1cd38a5ea 100644 --- a/source/blender/compositor/operations/COM_PreviewOperation.h +++ b/source/blender/compositor/operations/COM_PreviewOperation.h @@ -37,20 +37,18 @@ protected: const bNodeTree *tree; SocketReader *input; float divider; - int priority; public: PreviewOperation(); bool isOutputOperation(bool rendering) const {return true;} void initExecution(); void deinitExecution(); - const int getRenderPriority() const; + const CompositorPriority getRenderPriority() const; void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer **memoryBuffers); void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); void setbNode(bNode *node) { this->node = node;} void setbNodeTree(const bNodeTree *tree) { this->tree = tree;} bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void setPriority(int priority) { this->priority = priority; } }; #endif diff --git a/source/blender/compositor/operations/COM_RotateOperation.cpp b/source/blender/compositor/operations/COM_RotateOperation.cpp index 313e49d8609..af2633f0e53 100644 --- a/source/blender/compositor/operations/COM_RotateOperation.cpp +++ b/source/blender/compositor/operations/COM_RotateOperation.cpp @@ -43,7 +43,7 @@ void RotateOperation::initExecution() this->degreeSocket->read(degree, 0, 0, COM_PS_NEAREST, NULL); double rad; if (this->doDegree2RadConversion) { - rad = DEG2RAD(degree[0]); + rad = DEG2RAD((double)degree[0]); } else { rad = degree[0]; diff --git a/source/blender/compositor/operations/COM_TonemapOperation.cpp b/source/blender/compositor/operations/COM_TonemapOperation.cpp index 56830f4970d..d8089bdf3ea 100644 --- a/source/blender/compositor/operations/COM_TonemapOperation.cpp +++ b/source/blender/compositor/operations/COM_TonemapOperation.cpp @@ -53,14 +53,14 @@ void TonemapOperation::executePixel(float *color, int x, int y, MemoryBuffer *in float dr = output[0] + this->data->offset; float dg = output[1] + this->data->offset; float db = output[2] + this->data->offset; - output[0] /= ((dr == 0.f) ? 1.f : dr); - output[1] /= ((dg == 0.f) ? 1.f : dg); - output[2] /= ((db == 0.f) ? 1.f : db); + output[0] /= ((dr == 0.f) ? 1.0f : dr); + output[1] /= ((dg == 0.f) ? 1.0f : dg); + output[2] /= ((db == 0.f) ? 1.0f : db); const float igm = avg->igm; - if (igm != 0.f) { - output[0] = pow((double)MAX2(output[0], 0.), (double)igm); - output[1] = pow((double)MAX2(output[1], 0.), (double)igm); - output[2] = pow((double)MAX2(output[2], 0.), (double)igm); + if (igm != 0.0f) { + output[0] = powf(MAX2(output[0], 0.0f), igm); + output[1] = powf(MAX2(output[1], 0.0f), igm); + output[2] = powf(MAX2(output[2], 0.0f), igm); } color[0] = output[0]; @@ -68,31 +68,31 @@ void TonemapOperation::executePixel(float *color, int x, int y, MemoryBuffer *in color[2] = output[2]; color[3] = output[3]; } -void PhotoreceptorTonemapOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void * data) +void PhotoreceptorTonemapOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { - AvgLogLum * avg = (AvgLogLum*)data; + AvgLogLum *avg = (AvgLogLum *)data; NodeTonemap *ntm = this->data; - const float f = exp((double)-this->data->f); - const float m = (ntm->m > 0.f) ? ntm->m : (0.3f + 0.7f*pow((double)avg->auto_key, 1.4)); - const float ic = 1.f - ntm->c, ia = 1.f - ntm->a; + const float f = expf(-this->data->f); + const float m = (ntm->m > 0.0f) ? ntm->m : (0.3f + 0.7f * powf(avg->auto_key, 1.4f)); + const float ic = 1.0f - ntm->c, ia = 1.0f - ntm->a; float output[4]; this->imageReader->read(output, x, y, inputBuffers, NULL); - const float L = 0.212671f*output[0] + 0.71516f*output[1] + 0.072169f*output[2]; - float I_l = output[0] + ic*(L - output[0]); - float I_g = avg->cav[0] + ic*(avg->lav - avg->cav[0]); - float I_a = I_l + ia*(I_g - I_l); - output[0] /= (output[0] + pow((double)f*I_a, (double)m)); - I_l = output[1] + ic*(L - output[1]); - I_g = avg->cav[1] + ic*(avg->lav - avg->cav[1]); - I_a = I_l + ia*(I_g - I_l); - output[1] /= (output[1] + pow((double)f*I_a,(double)m)); - I_l = output[2] + ic*(L - output[2]); - I_g = avg->cav[2] + ic*(avg->lav - avg->cav[2]); - I_a = I_l + ia*(I_g - I_l); - output[2] /= (output[2] + pow((double)f*I_a, (double)m)); + const float L = 0.212671f * output[0] + 0.71516f * output[1] + 0.072169f * output[2]; + float I_l = output[0] + ic * (L - output[0]); + float I_g = avg->cav[0] + ic * (avg->lav - avg->cav[0]); + float I_a = I_l + ia * (I_g - I_l); + output[0] /= (output[0] + powf(f * I_a, m)); + I_l = output[1] + ic * (L - output[1]); + I_g = avg->cav[1] + ic * (avg->lav - avg->cav[1]); + I_a = I_l + ia * (I_g - I_l); + output[1] /= (output[1] + powf(f * I_a, m)); + I_l = output[2] + ic * (L - output[2]); + I_g = avg->cav[2] + ic * (avg->lav - avg->cav[2]); + I_a = I_l + ia * (I_g - I_l); + output[2] /= (output[2] + powf(f * I_a, m)); color[0] = output[0]; color[1] = output[1]; @@ -133,20 +133,20 @@ void *TonemapOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuff float * buffer = tile->getBuffer(); - float lsum = 0; + float lsum = 0.0f; int p = tile->getWidth() * tile->getHeight(); float *bc = buffer; float avl, maxl = -1e10f, minl = 1e10f; - const float sc = 1.f/(p); + const float sc = 1.0f / p; float Lav = 0.f; float cav[4] = {0.0f,0.0f,0.0f,0.0f}; while (p--) { - float L = 0.212671f*bc[0] + 0.71516f*bc[1] + 0.072169f*bc[2]; + float L = 0.212671f * bc[0] + 0.71516f * bc[1] + 0.072169f * bc[2]; Lav += L; cav[0] += bc[0]; cav[1] += bc[1]; cav[2] += bc[2]; - lsum += (float)log((double)MAX2(L, 0.0) + 1e-5); + lsum += logf(MAX2(L, 0.0f) + 1e-5f); maxl = (L > maxl) ? L : maxl; minl = (L < minl) ? L : minl; bc+=4; @@ -155,7 +155,7 @@ void *TonemapOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuff data->cav[0] = cav[0]*sc; data->cav[1] = cav[1]*sc; data->cav[2] = cav[2]*sc; - maxl = log((double)maxl + 1e-5); minl = log((double)minl + 1e-5f); avl = lsum*sc; + maxl = log((double)maxl + 1e-5); minl = log((double)minl + 1e-5); avl = lsum * sc; data->auto_key = (maxl > minl) ? ((maxl - avl) / (maxl - minl)) : 1.f; float al = exp((double)avl); data->al = (al == 0.f) ? 0.f : (this->data->key / al); diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp index f14de097dfd..270fedc174b 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp @@ -89,7 +89,7 @@ void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, Me if (nx == x && ny == y) { /* pass */ } - else if (size>= fabs(dx) && size >= fabs(dy)) { + else if (size >= fabsf(dx) && size >= fabsf(dy)) { float u = 256 + dx*256/size; float v = 256 + dy*256/size; inputBokehProgram->read(bokeh, u, v, COM_PS_NEAREST, inputBuffers); @@ -104,9 +104,9 @@ void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, Me } } } - color[0] = tempColor[0]*(1.0/overallmultiplyerr); - color[1] = tempColor[1]*(1.0/overallmultiplyerg); - color[2] = tempColor[2]*(1.0/overallmultiplyerb); + color[0] = tempColor[0] * (1.0f / overallmultiplyerr); + color[1] = tempColor[1] * (1.0f / overallmultiplyerg); + color[2] = tempColor[2] * (1.0f / overallmultiplyerb); color[3] = 1.0f; } diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp index 44b4c26fb64..809c688195f 100644 --- a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp @@ -50,8 +50,9 @@ ViewerBaseOperation::ViewerBaseOperation() : NodeOperation() void ViewerBaseOperation::initExecution() { - // When initializing the tree during initial load the width and height can be zero. - initImage(); + if (isActiveViewerOutput()) { + initImage(); + } } void ViewerBaseOperation::initImage() @@ -79,7 +80,6 @@ void ViewerBaseOperation::initImage() } void ViewerBaseOperation:: updateImage(rcti *rect) { - /// @todo: introduce new event to update smaller area WM_main_add_notifier(NC_WINDOW|ND_DRAW, NULL); } @@ -88,12 +88,12 @@ void ViewerBaseOperation::deinitExecution() this->outputBuffer = NULL; } -const int ViewerBaseOperation::getRenderPriority() const +const CompositorPriority ViewerBaseOperation::getRenderPriority() const { if (this->isActiveViewerOutput()) { - return 8; + return COM_PRIORITY_HIGH; } else { - return 0; + return COM_PRIORITY_LOW; } } diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.h b/source/blender/compositor/operations/COM_ViewerBaseOperation.h index 58101911550..51fa8cecc0d 100644 --- a/source/blender/compositor/operations/COM_ViewerBaseOperation.h +++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.h @@ -42,7 +42,7 @@ protected: bool doColorPredivide; public: - bool isOutputOperation(bool rendering) const {return true;} + bool isOutputOperation(bool rendering) const {return isActiveViewerOutput();} void initExecution(); void deinitExecution(); void setImage(Image *image) {this->image = image;} @@ -56,7 +56,7 @@ public: float getCenterX() { return this->centerX; } float getCenterY() { return this->centerY; } OrderOfChunks getChunkOrder() { return this->chunkOrder; } - const int getRenderPriority() const; + const CompositorPriority getRenderPriority() const; void setColorManagement(bool doColorManagement) {this->doColorManagement = doColorManagement;} void setColorPredivide(bool doColorPredivide) {this->doColorPredivide = doColorPredivide;} bool isViewerOperation() {return true;} diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp index 498add2fc87..222b879645c 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp @@ -111,10 +111,9 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, Me memoryBuffer->setCreatedState(); } -void WriteBufferOperation::executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, unsigned int chunkNumber, MemoryBuffer** inputMemoryBuffers) +void WriteBufferOperation::executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, unsigned int chunkNumber, MemoryBuffer** inputMemoryBuffers, MemoryBuffer* outputBuffer) { - MemoryBuffer *outputMemoryBuffer = this->getMemoryProxy()->getBuffer();// @todo wrong implementation needs revision - float *outputFloatBuffer = outputMemoryBuffer->getBuffer(); + float *outputFloatBuffer = outputBuffer->getBuffer(); cl_int error; /* * 1. create cl_mem from outputbuffer @@ -125,8 +124,8 @@ void WriteBufferOperation::executeOpenCLRegion(cl_context context, cl_program pr * note: list of cl_mem will be filled by 2, and needs to be cleaned up by 4 */ // STEP 1 - const unsigned int outputBufferWidth = outputMemoryBuffer->getWidth(); - const unsigned int outputBufferHeight = outputMemoryBuffer->getHeight(); + const unsigned int outputBufferWidth = outputBuffer->getWidth(); + const unsigned int outputBufferHeight = outputBuffer->getHeight(); const cl_image_format imageFormat = { CL_RGBA, @@ -141,19 +140,26 @@ void WriteBufferOperation::executeOpenCLRegion(cl_context context, cl_program pr clMemToCleanUp->push_back(clOutputBuffer); list<cl_kernel> *clKernelsToCleanUp = new list<cl_kernel>(); - this->input->executeOpenCL(context, program, queue, outputMemoryBuffer, clOutputBuffer, inputMemoryBuffers, clMemToCleanUp, clKernelsToCleanUp); + this->input->executeOpenCL(context, program, queue, outputBuffer, clOutputBuffer, inputMemoryBuffers, clMemToCleanUp, clKernelsToCleanUp); // STEP 3 size_t origin[3] = {0,0,0}; size_t region[3] = {outputBufferWidth,outputBufferHeight,1}; +// clFlush(queue); +// clFinish(queue); + error = clEnqueueBarrier(queue); if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } error = clEnqueueReadImage(queue, clOutputBuffer, CL_TRUE, origin, region, 0, 0, outputFloatBuffer, 0, NULL, NULL); if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + + this->getMemoryProxy()->getBuffer()->copyContentFrom(outputBuffer); + // STEP 4 + while (clMemToCleanUp->size()>0) { cl_mem mem = clMemToCleanUp->front(); error = clReleaseMemObject(mem); diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.h b/source/blender/compositor/operations/COM_WriteBufferOperation.h index b17122d68f0..6f2c49c49bd 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.h +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.h @@ -46,7 +46,7 @@ public: void initExecution(); void deinitExecution(); void setbNodeTree(const bNodeTree *tree) {this->tree = tree;} - void executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, unsigned int chunkNumber, MemoryBuffer** memoryBuffers); + void executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, unsigned int chunkNumber, MemoryBuffer** memoryBuffers, MemoryBuffer* outputBuffer); }; #endif diff --git a/source/blender/editors/CMakeLists.txt b/source/blender/editors/CMakeLists.txt index 088376b20ef..67ed77bcc4b 100644 --- a/source/blender/editors/CMakeLists.txt +++ b/source/blender/editors/CMakeLists.txt @@ -24,6 +24,7 @@ if(WITH_BLENDER) add_subdirectory(curve) add_subdirectory(gpencil) add_subdirectory(interface) + add_subdirectory(mask) add_subdirectory(mesh) add_subdirectory(metaball) add_subdirectory(object) diff --git a/source/blender/editors/SConscript b/source/blender/editors/SConscript index ed66a76a324..d08b496f0ef 100644 --- a/source/blender/editors/SConscript +++ b/source/blender/editors/SConscript @@ -8,6 +8,7 @@ SConscript(['datafiles/SConscript', 'interface/SConscript', 'animation/SConscript', 'armature/SConscript', + 'mask/SConscript', 'mesh/SConscript', 'metaball/SConscript', 'object/SConscript', diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index a735f159e1b..9be0ab37510 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -55,6 +55,7 @@ #include "DNA_world_types.h" #include "DNA_gpencil_types.h" #include "DNA_speaker_types.h" +#include "DNA_mask_types.h" #include "RNA_access.h" @@ -396,11 +397,8 @@ static short acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListEle /* get backdrop color for summary widget */ static void acf_summary_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float r_color[3]) { - // FIXME: hardcoded color - same as the 'action' line in NLA - // reddish color - r_color[0] = 0.8f; - r_color[1] = 0.2f; - r_color[2] = 0.0f; + /* reddish color - same as the 'action' line in NLA */ + UI_GetThemeColor3fv(TH_ANIM_ACTIVE, r_color); } /* backdrop for summary widget */ @@ -2597,6 +2595,172 @@ static bAnimChannelType ACF_GPL = acf_gpl_setting_ptr /* pointer for setting */ }; + +/* Mask Datablock ------------------------------------------- */ + +/* get backdrop color for mask datablock widget */ +static void acf_mask_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float r_color[3]) +{ + /* these are ID-blocks, but not exactly standalone... */ + UI_GetThemeColorShade3fv(TH_DOPESHEET_CHANNELSUBOB, 20, r_color); +} + +// TODO: just get this from RNA? +static int acf_mask_icon(bAnimListElem *UNUSED(ale)) +{ + return ICON_GREASEPENCIL; // MASK_TODO - need real icon +} + +/* check if some setting exists for this channel */ +static short acf_mask_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) +{ + switch (setting) { + /* only select and expand supported */ + case ACHANNEL_SETTING_SELECT: + case ACHANNEL_SETTING_EXPAND: + return 1; + + default: + return 0; + } +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_mask_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +{ + /* clear extra return data first */ + *neg = 0; + + switch (setting) { + case ACHANNEL_SETTING_SELECT: /* selected */ + return AGRP_SELECTED; + + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return MASK_ANIMF_EXPAND; + } + + /* this shouldn't happen */ + return 0; +} + +/* get pointer to the setting */ +static void *acf_mask_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type) +{ + Mask *mask = (Mask *)ale->data; + + /* all flags are just in mask->flag for now... */ + return GET_ACF_FLAG_PTR(mask->flag, type); +} + +/* mask datablock type define */ +static bAnimChannelType ACF_MASKDATA = +{ + "Mask Datablock", /* type name */ + + acf_mask_color, /* backdrop color */ + acf_group_backdrop, /* backdrop */ + acf_generic_indention_0, /* indent level */ + acf_generic_group_offset, /* offset */ + + acf_generic_idblock_name, /* name */ + acf_generic_idfill_nameprop, /* name prop */ + acf_mask_icon, /* icon */ + + acf_mask_setting_valid, /* has setting */ + acf_mask_setting_flag, /* flag for setting */ + acf_mask_setting_ptr /* pointer for setting */ +}; + +/* Mask Layer ------------------------------------------- */ + +/* name for grease pencil layer entries */ +static void acf_masklay_name(bAnimListElem *ale, char *name) +{ + MaskLayer *masklay = (MaskLayer *)ale->data; + + if (masklay && name) + BLI_strncpy(name, masklay->name, ANIM_CHAN_NAME_SIZE); +} + +/* name property for grease pencil layer entries */ +static short acf_masklay_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) +{ + if (ale->data) { + RNA_pointer_create(ale->id, &RNA_MaskLayer, ale->data, ptr); + *prop = RNA_struct_name_property(ptr->type); + + return (*prop != NULL); + } + + return 0; +} + +/* check if some setting exists for this channel */ +static short acf_masklay_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) +{ + switch (setting) { + /* unsupported */ + case ACHANNEL_SETTING_EXPAND: /* mask layers are more like F-Curves than groups */ + case ACHANNEL_SETTING_VISIBLE: /* graph editor only */ + return 0; + + /* always available */ + default: + return 1; + } +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_masklay_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +{ + /* clear extra return data first */ + *neg = 0; + + switch (setting) { + case ACHANNEL_SETTING_SELECT: /* selected */ + return MASK_LAYERFLAG_SELECT; + +// case ACHANNEL_SETTING_MUTE: /* muted */ +// return GP_LAYER_HIDE; + + case ACHANNEL_SETTING_PROTECT: /* protected */ + // *neg = 1; - if we change this to edtiability + return MASK_LAYERFLAG_LOCKED; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_masklay_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type) +{ + MaskLayer *masklay = (MaskLayer *)ale->data; + + /* all flags are just in agrp->flag for now... */ + return GET_ACF_FLAG_PTR(masklay->flag, type); +} + +/* grease pencil layer type define */ +static bAnimChannelType ACF_MASKLAYER = +{ + "Mask Layer", /* type name */ + + acf_generic_channel_color, /* backdrop color */ + acf_generic_channel_backdrop, /* backdrop */ + acf_generic_indention_flexible, /* indent level */ + acf_generic_group_offset, /* offset */ + + acf_masklay_name, /* name */ + acf_masklay_name_prop, /* name prop */ + NULL, /* icon */ + + acf_masklay_setting_valid, /* has setting */ + acf_masklay_setting_flag, /* flag for setting */ + acf_masklay_setting_ptr /* pointer for setting */ +}; + + /* *********************************************** */ /* Type Registration and General Access */ @@ -2648,6 +2812,9 @@ static void ANIM_init_channel_typeinfo_data(void) animchannelTypeInfo[type++] = &ACF_GPD; /* Grease Pencil Datablock */ animchannelTypeInfo[type++] = &ACF_GPL; /* Grease Pencil Layer */ + animchannelTypeInfo[type++] = &ACF_MASKDATA; /* Mask Datablock */ + animchannelTypeInfo[type++] = &ACF_MASKLAYER; /* Mask Layer */ + // TODO: these types still need to be implemented!!! // probably need a few extra flags for these special cases... animchannelTypeInfo[type++] = NULL; /* NLA Track */ diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index bbf89dfa74d..c2beeb17fe0 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -43,6 +43,7 @@ #include "DNA_scene_types.h" #include "DNA_key_types.h" #include "DNA_gpencil_types.h" +#include "DNA_mask_types.h" #include "RNA_access.h" #include "RNA_define.h" @@ -51,6 +52,7 @@ #include "BKE_fcurve.h" #include "BKE_gpencil.h" #include "BKE_context.h" +#include "BKE_mask.h" #include "BKE_global.h" #include "UI_view2d.h" @@ -261,6 +263,10 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, short datatype, s if (ale->flag & GP_LAYER_SELECT) sel = ACHANNEL_SETFLAG_CLEAR; break; + case ANIMTYPE_MASKLAYER: + if (ale->flag & MASK_LAYERFLAG_SELECT) + sel = ACHANNEL_SETFLAG_CLEAR; + break; } } } @@ -358,6 +364,14 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, short datatype, s ACHANNEL_SET_FLAG(gpl, sel, GP_LAYER_SELECT); } break; + + case ANIMTYPE_MASKLAYER: + { + MaskLayer *masklay = (MaskLayer *)ale->data; + + ACHANNEL_SET_FLAG(masklay, sel, MASK_LAYERFLAG_SELECT); + } + break; } } @@ -1059,6 +1073,10 @@ static int animchannels_rearrange_exec(bContext *C, wmOperator *op) /* Grease Pencil channels */ printf("Grease Pencil not supported for moving yet\n"); } + else if (ac.datatype == ANIMCONT_MASK) { + /* Grease Pencil channels */ + printf("Mask does not supported for moving yet\n"); + } else if (ac.datatype == ANIMCONT_ACTION) { /* Directly rearrange action's channels */ rearrange_action_channels(&ac, ac.data, mode); @@ -1209,6 +1227,17 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op)) BLI_freelinkN(&gpd->layers, gpl); } break; + + case ANIMTYPE_MASKLAYER: + { + /* Grease Pencil layer */ + Mask *mask = (Mask *)ale->id; + MaskLayer *masklay = (MaskLayer *)ale->data; + + /* try to delete the layer's data and the layer itself */ + BKE_mask_layer_remove(mask, masklay); + } + break; } } @@ -2292,6 +2321,36 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in notifierFlags |= (ND_ANIMCHAN | NA_EDITED); } break; + case ANIMTYPE_MASKDATABLOCK: + { + Mask *mask = (Mask *)ale->data; + + /* toggle expand + * - although the triangle widget already allows this, the whole channel can also be used for this purpose + */ + mask->flag ^= MASK_ANIMF_EXPAND; + + notifierFlags |= (ND_ANIMCHAN | NA_EDITED); + } + break; + case ANIMTYPE_MASKLAYER: + { + MaskLayer *masklay = (MaskLayer *)ale->data; + + /* select/deselect */ + if (selectmode == SELECT_INVERT) { + /* invert selection status of this layer only */ + masklay->flag ^= MASK_LAYERFLAG_SELECT; + } + else { + /* select layer by itself */ + ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); + masklay->flag |= MASK_LAYERFLAG_SELECT; + } + + notifierFlags |= (ND_ANIMCHAN | NA_EDITED); + } + break; default: if (G.debug & G_DEBUG) printf("Error: Invalid channel type in mouse_anim_channels()\n"); diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index cebc0e8810e..103b23be466 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -57,6 +57,7 @@ #include "DNA_lattice_types.h" #include "DNA_linestyle_types.h" #include "DNA_key_types.h" +#include "DNA_mask_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meta_types.h" @@ -87,6 +88,7 @@ #include "BKE_main.h" #include "BKE_material.h" #include "BKE_node.h" +#include "BKE_mask.h" #include "BKE_sequencer.h" #include "BKE_utildefines.h" @@ -174,6 +176,22 @@ static short actedit_get_context(bAnimContext *ac, SpaceAction *saction) ac->mode = saction->mode; return 1; + case SACTCONT_MASK: /* Grease Pencil */ // XXX review how this mode is handled... + /* update scene-pointer (no need to check for pinning yet, as not implemented) */ +{ + // TODO, other methods to get the mask + // Sequence *seq = BKE_sequencer_active_get(ac->scene); + //MovieClip *clip = ac->scene->clip; +// struct Mask *mask = seq ? seq->mask : NULL; + + saction->ads.source = (ID *)ac->scene;; + + ac->datatype = ANIMCONT_MASK; + ac->data = &saction->ads; + + ac->mode = saction->mode; + return 1; +} case SACTCONT_DOPESHEET: /* DopeSheet */ /* update scene-pointer (no need to check for pinning yet, as not implemented) */ saction->ads.source = (ID *)ac->scene; @@ -821,7 +839,18 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->datatype = ALE_GPFRAME; } break; - + + case ANIMTYPE_MASKLAYER: + { + MaskLayer *masklay = (MaskLayer *)data; + + ale->flag = masklay->flag; + + ale->key_data = NULL; + ale->datatype = ALE_MASKLAY; + } + break; + case ANIMTYPE_NLATRACK: { NlaTrack *nlt = (NlaTrack *)data; @@ -1367,6 +1396,83 @@ static size_t animdata_filter_gpencil(ListBase *anim_data, void *UNUSED(data), i return items; } +static size_t animdata_filter_mask_data(ListBase *anim_data, Mask *mask, const int filter_mode) +{ + MaskLayer *masklay_act = BKE_mask_layer_active(mask); + MaskLayer *masklay; + size_t items = 0; + + /* loop over layers as the conditions are acceptable */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + /* only if selected */ + if (ANIMCHANNEL_SELOK(SEL_MASKLAY(masklay)) ) { + /* only if editable */ +// if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_GPL(gpl)) { + /* active... */ + if (!(filter_mode & ANIMFILTER_ACTIVE) || (masklay_act == masklay)) { + /* add to list */ + ANIMCHANNEL_NEW_CHANNEL(masklay, ANIMTYPE_MASKLAYER, mask); + + +// if (filter_mode & ANIMFILTER_TMP_PEEK) +// return 1; +// else { +// bAnimListElem *ale = make_new_animlistelem(masklay, channel_type, (ID *)owner_id); +// if (ale) { +// BLI_addtail(anim_data, ale); +// items ++; +// } +// } + + } +// } + } + } + + return items; +} + +static size_t animdata_filter_mask(ListBase *anim_data, void *UNUSED(data), int filter_mode) +{ + Mask *mask; + size_t items = 0; + + /* for now, grab grease pencil datablocks directly from main */ + // XXX: this is not good... + for (mask = G.main->mask.first; mask; mask = mask->id.next) { + ListBase tmp_data = {NULL, NULL}; + size_t tmp_items = 0; + + /* only show if gpd is used by something... */ + if (ID_REAL_USERS(mask) < 1) + continue; + + /* add gpencil animation channels */ + BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_MASK(mask)) + { + tmp_items += animdata_filter_mask_data(&tmp_data, mask, filter_mode); + } + END_ANIMFILTER_SUBCHANNELS; + + /* did we find anything? */ + if (tmp_items) { + /* include data-expand widget first */ + if (filter_mode & ANIMFILTER_LIST_CHANNELS) { + /* add gpd as channel too (if for drawing, and it has layers) */ + ANIMCHANNEL_NEW_CHANNEL(mask, ANIMTYPE_MASKDATABLOCK, NULL); + } + + /* now add the list of collected channels */ + BLI_movelisttolist(anim_data, &tmp_data); + BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL)); + items += tmp_items; + } + } + + /* return the number of items added to the list */ + return items; +} + /* NOTE: owner_id is scene, material, or texture block, which is the direct owner of the node tree in question */ // TODO: how to handle group nodes is still unclear... static size_t animdata_filter_ds_nodetree(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, bNodeTree *ntree, int filter_mode) @@ -2347,7 +2453,7 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, int filter_mo items += animfilter_action(ac, anim_data, ads, data, filter_mode, (ID *)obact); } break; - + case ANIMCONT_SHAPEKEY: /* 'ShapeKey Editor' */ { /* the check for the DopeSheet summary is included here since the summary works here too */ @@ -2361,7 +2467,13 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, int filter_mo items = animdata_filter_gpencil(anim_data, data, filter_mode); } break; - + + case ANIMCONT_MASK: + { + items = animdata_filter_mask(anim_data, data, filter_mode); + } + break; + case ANIMCONT_DOPESHEET: /* 'DopeSheet Editor' */ { /* the DopeSheet editor is the primary place where the DopeSheet summaries are useful */ diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index cb7dc7ac206..e6fc4d5a168 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -60,6 +60,7 @@ #include "DNA_speaker_types.h" #include "DNA_world_types.h" #include "DNA_gpencil_types.h" +#include "DNA_mask_types.h" #include "BKE_key.h" #include "BKE_material.h" @@ -184,6 +185,50 @@ static void nupdate_ak_gpframe(void *node, void *data) ak->modified += 1; } +/* ......... */ + +/* Comparator callback used for ActKeyColumns and GPencil frame */ +static short compare_ak_masklayshape(void *node, void *data) +{ + ActKeyColumn *ak = (ActKeyColumn *)node; + MaskLayerShape *masklay_shape = (MaskLayerShape *)data; + + if (masklay_shape->frame < ak->cfra) + return -1; + else if (masklay_shape->frame > ak->cfra) + return 1; + else + return 0; +} + +/* New node callback used for building ActKeyColumns from GPencil frames */ +static DLRBT_Node *nalloc_ak_masklayshape(void *data) +{ + ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF"); + MaskLayerShape *masklay_shape = (MaskLayerShape *)data; + + /* store settings based on state of BezTriple */ + ak->cfra = masklay_shape->frame; + ak->sel = (masklay_shape->flag & MASK_SHAPE_SELECT) ? SELECT : 0; + + /* set 'modified', since this is used to identify long keyframes */ + ak->modified = 1; + + return (DLRBT_Node *)ak; +} + +/* Node updater callback used for building ActKeyColumns from GPencil frames */ +static void nupdate_ak_masklayshape(void *node, void *data) +{ + ActKeyColumn *ak = (ActKeyColumn *)node; + MaskLayerShape *masklay_shape = (MaskLayerShape *)data; + + /* set selection status and 'touched' status */ + if (masklay_shape->flag & MASK_SHAPE_SELECT) ak->sel = SELECT; + ak->modified += 1; +} + + /* --------------- */ /* Add the given BezTriple to the given 'list' of Keyframes */ @@ -204,6 +249,15 @@ static void add_gpframe_to_keycolumns_list(DLRBT_Tree *keys, bGPDframe *gpf) BLI_dlrbTree_add(keys, compare_ak_gpframe, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf); } +/* Add the given MaskLayerShape Frame to the given 'list' of Keyframes */ +static void add_masklay_to_keycolumns_list(DLRBT_Tree *keys, MaskLayerShape *masklay_shape) +{ + if (ELEM(NULL, keys, masklay_shape)) + return; + else + BLI_dlrbTree_add(keys, compare_ak_masklayshape, nalloc_ak_masklayshape, nupdate_ak_masklayshape, masklay_shape); +} + /* ActBeztColumns (Helpers for Long Keyframes) ------------------------------ */ /* maximum size of default buffer for BezTriple columns */ @@ -764,6 +818,21 @@ void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos) BLI_dlrbTree_free(&keys); } +void draw_masklay_channel(View2D *v2d, bDopeSheet *ads, MaskLayer *masklay, float ypos) +{ + DLRBT_Tree keys; + + BLI_dlrbTree_init(&keys); + + mask_to_keylist(ads, masklay, &keys); + + BLI_dlrbTree_linkedlist_sync(&keys); + + draw_keylist(v2d, &keys, NULL, ypos, (masklay->flag & MASK_LAYERFLAG_LOCKED)); + + BLI_dlrbTree_free(&keys); +} + /* *************************** Keyframe List Conversions *************************** */ void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, DLRBT_Tree *blocks) @@ -940,3 +1009,17 @@ void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, DLRBT_Tree *keys) } } +void mask_to_keylist(bDopeSheet *UNUSED(ads), MaskLayer *masklay, DLRBT_Tree *keys) +{ + MaskLayerShape *masklay_shape; + + if (masklay && keys) { + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + add_masklay_to_keycolumns_list(keys, masklay_shape); + } + } +} + diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index ac37b6c4141..14bee00a72a 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -374,16 +374,16 @@ void smooth_fcurve(FCurve *fcu) /* ---------------- */ /* little cache for values... */ -typedef struct tempFrameValCache { +typedef struct TempFrameValCache { float frame, val; -} tempFrameValCache; +} TempFrameValCache; /* Evaluates the curves between each selected keyframe on each frame, and keys the value */ void sample_fcurve(FCurve *fcu) { BezTriple *bezt, *start = NULL, *end = NULL; - tempFrameValCache *value_cache, *fp; + TempFrameValCache *value_cache, *fp; int sfra, range; int i, n, nIndex; @@ -406,7 +406,7 @@ void sample_fcurve(FCurve *fcu) sfra = (int)(floor(start->vec[1][0]) ); if (range) { - value_cache = MEM_callocN(sizeof(tempFrameValCache) * range, "IcuFrameValCache"); + value_cache = MEM_callocN(sizeof(TempFrameValCache) * range, "IcuFrameValCache"); /* sample values */ for (n = 1, fp = value_cache; n < range && fp; n++, fp++) { diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index fdebddbf41d..ea3c8685525 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -756,7 +756,7 @@ static int pose_visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op)) * * TODO, loop over children before parents if multiple bones * at once are to be predictable*/ - CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones) + CTX_DATA_BEGIN(C, bPoseChannel *, pchan, selected_pose_bones) { float delta_mat[4][4]; @@ -923,7 +923,7 @@ int join_armature_exec(bContext *C, wmOperator *UNUSED(op)) pose = ob->pose; ob->mode &= ~OB_MODE_POSE; - CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) + CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases) { if ((base->object->type == OB_ARMATURE) && (base->object != ob)) { bArmature *curarm = base->object->data; @@ -1195,7 +1195,7 @@ static int separate_armature_exec(bContext *C, wmOperator *UNUSED(op)) /* 1) only edit-base selected */ // TODO: use context iterators for this? - CTX_DATA_BEGIN (C, Base *, base, visible_bases) + CTX_DATA_BEGIN(C, Base *, base, visible_bases) { if (base->object == obedit) base->flag |= 1; else base->flag &= ~1; @@ -2297,7 +2297,7 @@ void add_primitive_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d) ED_armature_deselect_all(obedit, 0); - /* Create a bone */ + /* Create a bone */ bone = ED_armature_edit_bone_add(arm, "Bone"); arm->act_edbone = bone; @@ -2308,7 +2308,6 @@ void add_primitive_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d) add_v3_v3v3(bone->tail, bone->head, imat[1]); // bone with unit length 1 else add_v3_v3v3(bone->tail, bone->head, imat[2]); // bone with unit length 1, pointing up Z - } @@ -2849,7 +2848,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; /* loop over all bones, and only consider if visible */ - CTX_DATA_BEGIN (C, EditBone *, ebone, visible_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) { if (!(ebone->flag & BONE_CONNECTED) && (ebone->flag & BONE_ROOTSEL)) fill_add_joint(ebone, 0, &points); @@ -3563,7 +3562,7 @@ static int armature_subdivide_exec(bContext *C, wmOperator *op) /* loop over all editable bones */ // XXX the old code did this in reverse order though! - CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) { for (i = numcuts + 1; i > 1; i--) { /* compute cut ratio first */ @@ -3852,7 +3851,7 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op) */ /* parent selected bones to the active one */ - CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) { if (ELEM(ebone, actbone, actmirb) == 0) { if (ebone->flag & BONE_SELECTED) @@ -3878,7 +3877,7 @@ static int armature_parent_set_invoke(bContext *C, wmOperator *UNUSED(op), wmEve uiLayout *layout = uiPupMenuLayout(pup); int allchildbones = 0; - CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) { if (ebone != actbone) { if (ebone->parent != actbone) allchildbones = 1; @@ -3938,7 +3937,7 @@ static int armature_parent_clear_exec(bContext *C, wmOperator *op) bArmature *arm = (bArmature *)ob->data; int val = RNA_enum_get(op->ptr, "type"); - CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) { editbone_clear_parent(ebone, val); } @@ -3975,7 +3974,7 @@ void ARMATURE_OT_parent_clear(wmOperatorType *ot) static int armature_select_inverse_exec(bContext *C, wmOperator *UNUSED(op)) { /* Set the flags */ - CTX_DATA_BEGIN (C, EditBone *, ebone, visible_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) { /* ignore bone if selection can't change */ if ((ebone->flag & BONE_UNSELECTABLE) == 0) { @@ -4018,7 +4017,7 @@ static int armature_de_select_all_exec(bContext *C, wmOperator *op) } /* Set the flags */ - CTX_DATA_BEGIN (C, EditBone *, ebone, visible_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) { /* ignore bone if selection can't change */ if ((ebone->flag & BONE_UNSELECTABLE) == 0) { @@ -4438,7 +4437,7 @@ static int armature_align_bones_exec(bContext *C, wmOperator *op) */ /* align selected bones to the active one */ - CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) { if (ELEM(ebone, actbone, actmirb) == 0) { if (ebone->flag & BONE_SELECTED) @@ -4524,13 +4523,12 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor * note, special exception for armature mode so we can do multi-select * we could check for multi-select explicitly but think its fine to * always give predictable behavior in weight paint mode - campbell */ - if ((!extend && !deselect && !toggle)|| ((ob_act && (ob_act != ob) && (ob_act->mode & OB_MODE_WEIGHT_PAINT) == 0))) { + if ((!extend && !deselect && !toggle) || + ((ob_act && (ob_act != ob) && (ob_act->mode & OB_MODE_WEIGHT_PAINT) == 0))) + { ED_pose_deselectall(ob, 0); nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); arm->act_bone = nearBone; - - // XXX old cruft! use notifiers instead - //select_actionchannel_by_name(ob->action, nearBone->name, 1); } else { if (extend) { @@ -4548,17 +4546,11 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor } else { nearBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - - // XXX old cruft! use notifiers instead - //select_actionchannel_by_name(ob->action, nearBone->name, 0); } } else { nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); arm->act_bone = nearBone; - - // XXX old cruft! use notifiers instead - //select_actionchannel_by_name(ob->action, nearBone->name, 1); } } } @@ -5144,7 +5136,7 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op, } /* only clear relevant transforms for selected bones */ - CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones) + CTX_DATA_BEGIN(C, bPoseChannel *, pchan, selected_pose_bones) { /* run provided clearing function */ clear_func(pchan); @@ -5288,7 +5280,7 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op) } /* Set the flags */ - CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones) + CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) { /* select pchan only if selectable, but deselect works always */ switch (action) { @@ -5684,7 +5676,7 @@ static int armature_flip_names_exec(bContext *C, wmOperator *UNUSED(op)) arm = ob->data; /* loop through selected bones, auto-naming them */ - CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) { flip_side_name(newname, ebone->name, TRUE); // 1 = do strip off number extensions ED_armature_bone_rename(arm, ebone->name, newname); @@ -5729,7 +5721,7 @@ static int armature_autoside_names_exec(bContext *C, wmOperator *op) arm = ob->data; /* loop through selected bones, auto-naming them */ - CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) { BLI_strncpy(newname, ebone->name, sizeof(newname)); if (bone_autoside_name(newname, 1, axis, ebone->head[axis], ebone->tail[axis])) @@ -5752,7 +5744,8 @@ void ARMATURE_OT_autoside_names(wmOperatorType *ot) {0, "XAXIS", 0, "X-Axis", "Left/Right"}, {1, "YAXIS", 0, "Y-Axis", "Front/Back"}, {2, "ZAXIS", 0, "Z-Axis", "Top/Bottom"}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; /* identifiers */ ot->name = "AutoName by Axis"; diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c index d90bd96a6f1..91c342ec070 100644 --- a/source/blender/editors/armature/editarmature_retarget.c +++ b/source/blender/editors/armature/editarmature_retarget.c @@ -81,20 +81,17 @@ typedef struct RetargetParam { bContext *context; } RetargetParam; -typedef enum -{ +typedef enum { RETARGET_LENGTH, RETARGET_AGGRESSIVE } RetargetMode; -typedef enum -{ +typedef enum { METHOD_BRUTE_FORCE = 0, METHOD_MEMOIZE = 1 } RetargetMethod; -typedef enum -{ +typedef enum { ARC_FREE = 0, ARC_TAKEN = 1, ARC_USED = 2 diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c index d642ee57c57..27c40095348 100644 --- a/source/blender/editors/curve/curve_ops.c +++ b/source/blender/editors/curve/curve_ops.c @@ -141,14 +141,14 @@ void ED_operatormacros_curve(void) wmOperatorTypeMacro *otmacro; ot = WM_operatortype_append_macro("CURVE_OT_duplicate_move", "Add Duplicate", "Duplicate curve and move", - OPTYPE_UNDO|OPTYPE_REGISTER); + OPTYPE_UNDO | OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "CURVE_OT_duplicate"); otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_enum_set(otmacro->ptr, "proportional", 0); RNA_boolean_set(otmacro->ptr, "mirror", FALSE); ot = WM_operatortype_append_macro("CURVE_OT_extrude_move", "Extrude Curve and Move", - "Extrude curve and move result", OPTYPE_UNDO|OPTYPE_REGISTER); + "Extrude curve and move result", OPTYPE_UNDO | OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "CURVE_OT_extrude"); otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_enum_set(otmacro->ptr, "proportional", 0); @@ -189,8 +189,8 @@ void ED_keymap_curve(wmKeyConfig *keyconf) RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", ENDKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", LINE_END); RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", PREV_CHAR); RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", NEXT_CHAR); - RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0)->ptr, "type", PREV_WORD); - RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0)->ptr, "type", NEXT_WORD); + RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)->ptr, "type", PREV_WORD); + RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)->ptr, "type", NEXT_WORD); RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", UPARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", PREV_LINE); RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", DOWNARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", NEXT_LINE); RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", PAGEUPKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", PREV_PAGE); @@ -224,9 +224,9 @@ void ED_keymap_curve(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "CURVE_OT_vertex_add", LEFTMOUSE, KM_CLICK, KM_CTRL, 0); kmi = WM_keymap_add_item(keymap, "CURVE_OT_select_all", AKEY, KM_PRESS, 0, 0); - RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); + RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); kmi = WM_keymap_add_item(keymap, "CURVE_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); - RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + RNA_enum_set(kmi->ptr, "action", SEL_INVERT); WM_keymap_add_item(keymap, "CURVE_OT_select_row", RKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "CURVE_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index b94d3653f60..2fa7b4b2126 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -3530,7 +3530,8 @@ void CURVE_OT_spline_type_set(wmOperatorType *ot) // {CU_CARDINAL, "CARDINAL", 0, "Cardinal", ""}, // {CU_BSPLINE, "B_SPLINE", 0, "B-Spline", ""}, {CU_NURBS, "NURBS", 0, "NURBS", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; /* identifiers */ ot->name = "Set Spline Type"; @@ -3573,7 +3574,8 @@ void CURVE_OT_handle_type_set(wmOperatorType *ot) {5, "ALIGNED", 0, "Aligned", ""}, {6, "FREE_ALIGN", 0, "Free", ""}, {3, "TOGGLE_FREE_ALIGN", 0, "Toggle Free/Align", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; /* identifiers */ ot->name = "Set Handle Type"; @@ -4886,7 +4888,8 @@ void CURVE_OT_cyclic_toggle(wmOperatorType *ot) static EnumPropertyItem direction_items[] = { {0, "CYCLIC_U", 0, "Cyclic U", ""}, {1, "CYCLIC_V", 0, "Cyclic V", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; /* identifiers */ ot->name = "Toggle Cyclic"; @@ -6007,7 +6010,8 @@ void CURVE_OT_delete(wmOperatorType *ot) {0, "SELECTED", 0, "Select", ""}, {1, "SEGMENT", 0, "Segment", ""}, {2, "ALL", 0, "All", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; /* identifiers */ ot->name = "Delete"; @@ -6101,7 +6105,7 @@ int join_curve_exec(bContext *C, wmOperator *UNUSED(op)) /* trasnform all selected curves inverse in obact */ invert_m4_m4(imat, ob->obmat); - CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) + CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases) { if (base->object->type == ob->type) { if (base->object != ob) { diff --git a/source/blender/editors/curve/lorem.c b/source/blender/editors/curve/lorem.c index 66b358e04e5..7823be3df6d 100644 --- a/source/blender/editors/curve/lorem.c +++ b/source/blender/editors/curve/lorem.c @@ -25,7 +25,7 @@ #include "curve_intern.h" -const char ED_lorem[]= { +const char ED_lorem[] = { 76, 111, 114, 101, 109, 32, 105, 112, 115, 117, 109, 32, 100, 111, 108, 111, 114, 32, 115, 105, 116, 32, 97, 109, 101, 116, 44, 32, 99, 111, 110, 115, 101, 99, 116, 101, 116, 117, 101, 114, 32, 97, 100, 105, 112, 105, 115, 99, 105, 110, 103, 32, 101, 108, 105, 116, 46, 32, 65, 108, 105, 113, 117, 97, 109, 32, 116, 114, 105, 115, 116, 105, 113, 117, 101, 32, 105, 110, 116, 101, 114, 100, 117, 109, 32, 115, 101, 109, 46, 32, 78, 117, 108, diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 8d771f0dc58..1823bbce3a1 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -669,7 +669,7 @@ static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy, // ............................ /* draw grease-pencil sketches to specified 2d-view that uses ibuf corrections */ -void draw_gpencil_2dimage(bContext *C, ImBuf *ibuf) +void draw_gpencil_2dimage(bContext *C /* , ImBuf *ibuf */) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); @@ -678,8 +678,6 @@ void draw_gpencil_2dimage(bContext *C, ImBuf *ibuf) int offsx, offsy, sizex, sizey; int dflag = GP_DRAWDATA_NOSTATUS; - /* check that we have grease-pencil stuff to draw */ - if (ELEM(NULL, sa, ibuf)) return; gpd = gpencil_data_get_active(C); // XXX if (gpd == NULL) return; @@ -706,7 +704,10 @@ void draw_gpencil_2dimage(bContext *C, ImBuf *ibuf) { SpaceSeq *sseq = (SpaceSeq *)sa->spacedata.first; float zoom, zoomx, zoomy; - + + /* check that we have grease-pencil stuff to draw */ + if (ELEM(NULL, sa, ibuf)) return; + /* calculate accessory values */ zoom = (float)(SEQ_ZOOM_FAC(sseq->zoom)); if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c index 9cc738b016e..a7beaa74eb7 100644 --- a/source/blender/editors/gpencil/editaction_gpencil.c +++ b/source/blender/editors/gpencil/editaction_gpencil.c @@ -62,7 +62,7 @@ /* Generics - Loopers */ /* Loops over the gp-frames for a gp-layer, and applies the given callback */ -short gplayer_frames_looper(bGPDlayer *gpl, Scene *scene, short (*gpf_cb)(bGPDframe *, Scene *)) +short ED_gplayer_frames_looper(bGPDlayer *gpl, Scene *scene, short (*gpf_cb)(bGPDframe *, Scene *)) { bGPDframe *gpf; @@ -85,7 +85,7 @@ short gplayer_frames_looper(bGPDlayer *gpl, Scene *scene, short (*gpf_cb)(bGPDfr /* Data Conversion Tools */ /* make a listing all the gp-frames in a layer as cfraelems */ -void gplayer_make_cfra_list(bGPDlayer *gpl, ListBase *elems, short onlysel) +void ED_gplayer_make_cfra_list(bGPDlayer *gpl, ListBase *elems, short onlysel) { bGPDframe *gpf; CfraElem *ce; @@ -111,7 +111,7 @@ void gplayer_make_cfra_list(bGPDlayer *gpl, ListBase *elems, short onlysel) /* Selection Tools */ /* check if one of the frames in this layer is selected */ -short is_gplayer_frame_selected(bGPDlayer *gpl) +short ED_gplayer_frame_select_check(bGPDlayer *gpl) { bGPDframe *gpf; @@ -149,7 +149,7 @@ static void gpframe_select(bGPDframe *gpf, short select_mode) } /* set all/none/invert select (like above, but with SELECT_* modes) */ -void select_gpencil_frames(bGPDlayer *gpl, short select_mode) +void ED_gpencil_select_frames(bGPDlayer *gpl, short select_mode) { bGPDframe *gpf; @@ -164,36 +164,33 @@ void select_gpencil_frames(bGPDlayer *gpl, short select_mode) } /* set all/none/invert select */ -void set_gplayer_frame_selection(bGPDlayer *gpl, short mode) +void ED_gplayer_frame_select_set(bGPDlayer *gpl, short mode) { /* error checking */ if (gpl == NULL) return; /* now call the standard function */ - select_gpencil_frames(gpl, mode); + ED_gpencil_select_frames(gpl, mode); } /* select the frame in this layer that occurs on this frame (there should only be one at most) */ -void select_gpencil_frame(bGPDlayer *gpl, int selx, short select_mode) +void ED_gpencil_select_frame(bGPDlayer *gpl, int selx, short select_mode) { bGPDframe *gpf; if (gpl == NULL) return; - - /* search through frames for a match */ - for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { - /* there should only be one frame with this frame-number */ - if (gpf->framenum == selx) { - gpframe_select(gpf, select_mode); - break; - } + + gpf = BKE_gpencil_layer_find_frame(gpl, selx); + + if (gpf) { + gpframe_select(gpf, select_mode); } } /* select the frames in this layer that occur within the bounds specified */ -void borderselect_gplayer_frames(bGPDlayer *gpl, float min, float max, short select_mode) +void ED_gplayer_frames_select_border(bGPDlayer *gpl, float min, float max, short select_mode) { bGPDframe *gpf; @@ -211,7 +208,7 @@ void borderselect_gplayer_frames(bGPDlayer *gpl, float min, float max, short sel /* Frame Editing Tools */ /* Delete selected frames */ -void delete_gplayer_frames(bGPDlayer *gpl) +void ED_gplayer_frames_delete(bGPDlayer *gpl) { bGPDframe *gpf, *gpfn; @@ -229,7 +226,7 @@ void delete_gplayer_frames(bGPDlayer *gpl) } /* Duplicate selected frames from given gp-layer */ -void duplicate_gplayer_frames(bGPDlayer *gpl) +void ED_gplayer_frames_duplicate(bGPDlayer *gpl) { bGPDframe *gpf, *gpfn; @@ -502,19 +499,19 @@ void snap_gplayer_frames(bGPDlayer *gpl, Scene *scene, short mode) { switch (mode) { case 1: /* snap to nearest frame */ - gplayer_frames_looper(gpl, scene, snap_gpf_nearest); + ED_gplayer_frames_looper(gpl, scene, snap_gpf_nearest); break; case 2: /* snap to current frame */ - gplayer_frames_looper(gpl, scene, snap_gpf_cframe); + ED_gplayer_frames_looper(gpl, scene, snap_gpf_cframe); break; case 3: /* snap to nearest marker */ - gplayer_frames_looper(gpl, scene, snap_gpf_nearmarker); + ED_gplayer_frames_looper(gpl, scene, snap_gpf_nearmarker); break; case 4: /* snap to nearest second */ - gplayer_frames_looper(gpl, scene, snap_gpf_nearestsec); + ED_gplayer_frames_looper(gpl, scene, snap_gpf_nearestsec); break; default: /* just in case */ - gplayer_frames_looper(gpl, scene, snap_gpf_nearest); + ED_gplayer_frames_looper(gpl, scene, snap_gpf_nearest); break; } } @@ -604,21 +601,21 @@ void mirror_gplayer_frames(bGPDlayer *gpl, Scene *scene, short mode) { switch (mode) { case 1: /* mirror over current frame */ - gplayer_frames_looper(gpl, scene, mirror_gpf_cframe); + ED_gplayer_frames_looper(gpl, scene, mirror_gpf_cframe); break; case 2: /* mirror over frame 0 */ - gplayer_frames_looper(gpl, scene, mirror_gpf_yaxis); + ED_gplayer_frames_looper(gpl, scene, mirror_gpf_yaxis); break; case 3: /* mirror over value 0 */ - gplayer_frames_looper(gpl, scene, mirror_gpf_xaxis); + ED_gplayer_frames_looper(gpl, scene, mirror_gpf_xaxis); break; case 4: /* mirror over marker */ mirror_gpf_marker(NULL, NULL); - gplayer_frames_looper(gpl, scene, mirror_gpf_marker); + ED_gplayer_frames_looper(gpl, scene, mirror_gpf_marker); mirror_gpf_marker(NULL, NULL); break; default: /* just in case */ - gplayer_frames_looper(gpl, scene, mirror_gpf_yaxis); + ED_gplayer_frames_looper(gpl, scene, mirror_gpf_yaxis); break; } } diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index 3a7e806c2ed..b59f3756819 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -40,6 +40,7 @@ #include "DNA_gpencil_types.h" #include "DNA_screen_types.h" +#include "DNA_space_types.h" #include "BKE_context.h" #include "BKE_global.h" @@ -236,6 +237,7 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin PointerRNA gpd_ptr; bGPDlayer *gpl; uiLayout *col, *row; + SpaceClip *sc= CTX_wm_space_clip(C); short v3d_stroke_opts = STROKE_OPTS_NORMAL; const short is_v3d = CTX_wm_view3d(C) != NULL; @@ -244,6 +246,16 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin /* draw gpd settings first ------------------------------------- */ col = uiLayoutColumn(layout, 0); + + if (sc) { + bScreen *screen = CTX_wm_screen(C); + PointerRNA sc_ptr; + + RNA_pointer_create(&screen->id, &RNA_SpaceClipEditor, sc, &sc_ptr); + row = uiLayoutRow(col, 1); + uiItemR(row, &sc_ptr, "grease_pencil_source", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + } + /* current Grease Pencil block */ /* TODO: show some info about who owns this? */ uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_add", NULL, "GPENCIL_OT_data_unlink"); @@ -281,14 +293,17 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin row = uiLayoutRow(col, 1); uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "VIEW", NULL, ICON_NONE); uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "CURSOR", NULL, ICON_NONE); - row = uiLayoutRow(col, 1); - uiLayoutSetActive(row, v3d_stroke_opts); - uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "SURFACE", NULL, ICON_NONE); - uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "STROKE", NULL, ICON_NONE); - row = uiLayoutRow(col, 0); - uiLayoutSetActive(row, v3d_stroke_opts == STROKE_OPTS_V3D_ON); - uiItemR(row, &gpd_ptr, "use_stroke_endpoints", 0, NULL, ICON_NONE); + if (sc == NULL) { + row = uiLayoutRow(col, 1); + uiLayoutSetActive(row, v3d_stroke_opts); + uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "SURFACE", NULL, ICON_NONE); + uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "STROKE", NULL, ICON_NONE); + + row = uiLayoutRow(col, 0); + uiLayoutSetActive(row, v3d_stroke_opts == STROKE_OPTS_V3D_ON); + uiItemR(row, &gpd_ptr, "use_stroke_endpoints", 0, NULL, ICON_NONE); + } } diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 9250d48a20c..71cbabe9114 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -57,6 +57,7 @@ #include "BKE_library.h" #include "BKE_object.h" #include "BKE_report.h" +#include "BKE_tracking.h" #include "WM_api.h" @@ -144,9 +145,23 @@ bGPdata **gpencil_data_get_pointers(bContext *C, PointerRNA *ptr) MovieClip *clip = ED_space_clip(sc); if (clip) { - /* for now, as long as there's a clip, default to using that in Clip Editor */ - if (ptr) RNA_id_pointer_create(&clip->id, ptr); - return &clip->gpd; + if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { + MovieTrackingTrack *track = BKE_tracking_active_track(&clip->tracking); + + if (!track) + return NULL; + + if (ptr) + RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, ptr); + + return &track->gpd; + } + else { + if (ptr) + RNA_id_pointer_create(&clip->id, ptr); + + return &clip->gpd; + } } } break; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 3e569f8eb96..89d8ed9c465 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -44,6 +44,7 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_report.h" +#include "BKE_tracking.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -1125,6 +1126,15 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) p->custom_color[1] = 0.0f; p->custom_color[2] = 0.5f; p->custom_color[3] = 0.9f; + + if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { + int framenr = sc->user.framenr; + MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking); + MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); + + p->imat[3][0] -= marker->pos[0]; + p->imat[3][1] -= marker->pos[1]; + } } break; diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 6ababe2becb..7afa9fe8bc5 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -89,15 +89,16 @@ typedef struct bAnimContext { /* Main Data container types */ typedef enum eAnimCont_Types { - ANIMCONT_NONE = 0, /* invalid or no data */ - ANIMCONT_ACTION, /* action (bAction) */ - ANIMCONT_SHAPEKEY, /* shapekey (Key) */ - ANIMCONT_GPENCIL, /* grease pencil (screen) */ - ANIMCONT_DOPESHEET, /* dopesheet (bDopesheet) */ - ANIMCONT_FCURVES, /* animation F-Curves (bDopesheet) */ - ANIMCONT_DRIVERS, /* drivers (bDopesheet) */ - ANIMCONT_NLA, /* nla (bDopesheet) */ - ANIMCONT_CHANNEL /* animation channel (bAnimListElem) */ + ANIMCONT_NONE = 0, /* invalid or no data */ + ANIMCONT_ACTION = 1, /* action (bAction) */ + ANIMCONT_SHAPEKEY = 2, /* shapekey (Key) */ + ANIMCONT_GPENCIL = 3, /* grease pencil (screen) */ + ANIMCONT_DOPESHEET = 4, /* dopesheet (bDopesheet) */ + ANIMCONT_FCURVES = 5, /* animation F-Curves (bDopesheet) */ + ANIMCONT_DRIVERS = 6, /* drivers (bDopesheet) */ + ANIMCONT_NLA = 7, /* nla (bDopesheet) */ + ANIMCONT_CHANNEL = 8, /* animation channel (bAnimListElem) */ + ANIMCONT_MASK = 9 /* mask dopesheet */ } eAnimCont_Types; /* --------------- Channels -------------------- */ @@ -161,6 +162,9 @@ typedef enum eAnim_ChannelType { ANIMTYPE_GPDATABLOCK, ANIMTYPE_GPLAYER, + + ANIMTYPE_MASKDATABLOCK, + ANIMTYPE_MASKLAYER, ANIMTYPE_NLATRACK, ANIMTYPE_NLAACTION, @@ -174,6 +178,7 @@ typedef enum eAnim_KeyType { ALE_NONE = 0, /* no keyframe data */ ALE_FCURVE, /* F-Curve */ ALE_GPFRAME, /* Grease Pencil Frames */ + ALE_MASKLAY, /* Mask */ ALE_NLASTRIP, /* NLA Strips */ ALE_ALL, /* All channels summary */ @@ -281,6 +286,15 @@ typedef enum eAnimFilter_Flags { #define EDITABLE_GPL(gpl) ((gpl->flag & GP_LAYER_LOCKED) == 0) #define SEL_GPL(gpl) (gpl->flag & GP_LAYER_SELECT) +/* Mask Only */ +/* Grease Pencil datablock settings */ +#define EXPANDED_MASK(mask) (mask->flag & MASK_ANIMF_EXPAND) +/* Grease Pencil Layer settings */ +#define EDITABLE_MASK(masklay) ((masklay->flag & MASK_LAYERFLAG_LOCKED) == 0) +#define SEL_MASKLAY(masklay) (masklay->flag & SELECT) + + + /* NLA only */ #define SEL_NLT(nlt) (nlt->flag & NLATRACK_SELECTED) #define EDITABLE_NLT(nlt) ((nlt->flag & NLATRACK_PROTECTED) == 0) @@ -343,20 +357,20 @@ short ANIM_animdata_context_getdata(bAnimContext *ac); /* flag-setting behavior */ typedef enum eAnimChannels_SetFlag { - ACHANNEL_SETFLAG_CLEAR = 0, /* turn off */ - ACHANNEL_SETFLAG_ADD, /* turn on */ - ACHANNEL_SETFLAG_INVERT, /* on->off, off->on */ - ACHANNEL_SETFLAG_TOGGLE /* some on -> all off // all on */ + ACHANNEL_SETFLAG_CLEAR = 0, /* turn off */ + ACHANNEL_SETFLAG_ADD = 1, /* turn on */ + ACHANNEL_SETFLAG_INVERT = 2, /* on->off, off->on */ + ACHANNEL_SETFLAG_TOGGLE = 3 /* some on -> all off // all on */ } eAnimChannels_SetFlag; /* types of settings for AnimChannels */ typedef enum eAnimChannel_Settings { - ACHANNEL_SETTING_SELECT = 0, - ACHANNEL_SETTING_PROTECT, // warning: for drawing UI's, need to check if this is off (maybe inverse this later) - ACHANNEL_SETTING_MUTE, - ACHANNEL_SETTING_EXPAND, - ACHANNEL_SETTING_VISIBLE, /* only for Graph Editor */ - ACHANNEL_SETTING_SOLO /* only for NLA Tracks */ + ACHANNEL_SETTING_SELECT = 0, + ACHANNEL_SETTING_PROTECT = 1, /* warning: for drawing UI's, need to check if this is off (maybe inverse this later) */ + ACHANNEL_SETTING_MUTE = 2, + ACHANNEL_SETTING_EXPAND = 3, + ACHANNEL_SETTING_VISIBLE = 4, /* only for Graph Editor */ + ACHANNEL_SETTING_SOLO = 5 /* only for NLA Tracks */ } eAnimChannel_Settings; diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h index 7943a17c377..1d42954a416 100644 --- a/source/blender/editors/include/ED_clip.h +++ b/source/blender/editors/include/ED_clip.h @@ -36,6 +36,7 @@ struct bContext; struct bScreen; struct ImBuf; struct Main; +struct Mask; struct MovieClip; struct SpaceClip; struct wmEvent; @@ -46,14 +47,21 @@ int ED_space_clip_poll(struct bContext *C); int ED_space_clip_view_clip_poll(struct bContext *C); int ED_space_clip_tracking_poll(struct bContext *C); -int ED_space_clip_tracking_size_poll(struct bContext *C); -int ED_space_clip_tracking_frame_poll(struct bContext *C); +int ED_space_clip_maskedit_poll(struct bContext *C); +int ED_space_clip_maskedit_mask_poll(bContext *C); void ED_space_clip_set(struct bContext *C, struct bScreen *screen, struct SpaceClip *sc, struct MovieClip *clip); struct MovieClip *ED_space_clip(struct SpaceClip *sc); +struct Mask *ED_space_clip_mask(struct SpaceClip *sc); void ED_space_clip_size(struct SpaceClip *sc, int *width, int *height); void ED_space_clip_zoom(struct SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy); void ED_space_clip_aspect(struct SpaceClip *sc, float *aspx, float *aspy); +void ED_space_clip_aspect_dimension_aware(struct SpaceClip *sc, float *aspx, float *aspy); + +int ED_space_clip_clip_framenr(struct SpaceClip *sc); + +void ED_space_clip_mask_size(struct SpaceClip *sc, int *width, int *height); +void ED_space_clip_mask_aspect(struct SpaceClip *sc, float *aspx, float *aspy); struct ImBuf *ED_space_clip_get_buffer(struct SpaceClip *sc); struct ImBuf *ED_space_clip_get_stable_buffer(struct SpaceClip *sc, float loc[2], float *scale, float *angle); @@ -72,6 +80,8 @@ void ED_space_clip_unload_movieclip_buffer(struct SpaceClip *sc); void ED_space_clip_free_texture_buffer(struct SpaceClip *sc); int ED_space_clip_show_trackedit(struct SpaceClip *sc); +int ED_space_clip_show_maskedit(struct SpaceClip *sc); +void ED_space_clip_set_mask(struct bContext *C, struct SpaceClip *sc, struct Mask *mask); /* clip_ops.c */ void ED_operatormacros_clip(void); diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index bd3e4371a79..32eb63a26d5 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -76,31 +76,34 @@ void ED_operatortypes_gpencil(void); /* ------------ Grease-Pencil Drawing API ------------------ */ /* drawgpencil.c */ -void draw_gpencil_2dimage(struct bContext *C, struct ImBuf *ibuf); +void draw_gpencil_2dimage(struct bContext *C /* , struct ImBuf *ibuf */); void draw_gpencil_view2d(struct bContext *C, short onlyv2d); void draw_gpencil_view3d(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, short only3d); void gpencil_panel_standard(const struct bContext *C, struct Panel *pa); /* ----------- Grease-Pencil AnimEdit API ------------------ */ -short gplayer_frames_looper(struct bGPDlayer *gpl, struct Scene *scene, short (*gpf_cb)(struct bGPDframe *, struct Scene *)); -void gplayer_make_cfra_list(struct bGPDlayer *gpl, ListBase *elems, short onlysel); +short ED_gplayer_frames_looper(struct bGPDlayer *gpl, struct Scene *scene, + short (*gpf_cb)(struct bGPDframe *, struct Scene *)); +void ED_gplayer_make_cfra_list(struct bGPDlayer *gpl, ListBase *elems, short onlysel); -short is_gplayer_frame_selected(struct bGPDlayer *gpl); -void set_gplayer_frame_selection(struct bGPDlayer *gpl, short mode); -void select_gpencil_frames(struct bGPDlayer *gpl, short select_mode); -void select_gpencil_frame(struct bGPDlayer *gpl, int selx, short select_mode); -void borderselect_gplayer_frames(struct bGPDlayer *gpl, float min, float max, short select_mode); +short ED_gplayer_frame_select_check(struct bGPDlayer *gpl); +void ED_gplayer_frame_select_set(struct bGPDlayer *gpl, short mode); +void ED_gplayer_frames_select_border(struct bGPDlayer *gpl, float min, float max, short select_mode); +void ED_gpencil_select_frames(struct bGPDlayer *gpl, short select_mode); +void ED_gpencil_select_frame(struct bGPDlayer *gpl, int selx, short select_mode); -void delete_gplayer_frames(struct bGPDlayer *gpl); -void duplicate_gplayer_frames(struct bGPDlayer *gpd); +void ED_gplayer_frames_delete(struct bGPDlayer *gpl); +void ED_gplayer_frames_duplicate(struct bGPDlayer *gpl); +#if 0 void free_gpcopybuf(void); void copy_gpdata(void); void paste_gpdata(void); void snap_gplayer_frames(struct bGPDlayer *gpl, short mode); void mirror_gplayer_frames(struct bGPDlayer *gpl, short mode); +#endif /* ------------ Grease-Pencil Undo System ------------------ */ int ED_gpencil_session_active(void); diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h index cd64427de78..8a65699f404 100644 --- a/source/blender/editors/include/ED_keyframes_draw.h +++ b/source/blender/editors/include/ED_keyframes_draw.h @@ -42,6 +42,7 @@ struct bActionGroup; struct Object; struct ListBase; struct bGPDlayer; +struct MaskLayer; struct Scene; struct View2D; struct DLRBT_Tree; @@ -122,6 +123,8 @@ void draw_summary_channel(struct View2D *v2d, struct bAnimContext *ac, float ypo /* Grease Pencil Layer */ // XXX not restored void draw_gpl_channel(struct View2D *v2d, struct bDopeSheet *ads, struct bGPDlayer *gpl, float ypos); +/* Mask Layer */ +void draw_masklay_channel(struct View2D *v2d, struct bDopeSheet *ads, struct MaskLayer *masklay, float ypos); /* Keydata Generation --------------- */ /* F-Curve */ @@ -139,6 +142,9 @@ void summary_to_keylist(struct bAnimContext *ac, struct DLRBT_Tree *keys, struct /* Grease Pencil Layer */ // XXX not restored void gpl_to_keylist(struct bDopeSheet *ads, struct bGPDlayer *gpl, struct DLRBT_Tree *keys); +/* Mask */ +// XXX not restored +void mask_to_keylist(struct bDopeSheet *UNUSED(ads), struct MaskLayer *masklay, struct DLRBT_Tree *keys); /* ActKeyColumn API ---------------- */ /* Comparator callback used for ActKeyColumns and cframe float-value pointer */ diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h new file mode 100644 index 00000000000..773da04bc7b --- /dev/null +++ b/source/blender/editors/include/ED_mask.h @@ -0,0 +1,74 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file ED_mask.h + * \ingroup editors + */ + +#ifndef __ED_MASK_H__ +#define __ED_MASK_H__ + +struct wmKeyConfig; +struct MaskLayer; +struct MaskLayerShape; + +/* mask_editor.c */ +void ED_operatortypes_mask(void); +void ED_keymap_mask(struct wmKeyConfig *keyconf); +void ED_operatormacros_mask(void); + +/* mask_draw.c */ +void ED_mask_draw(const bContext *C, const char draw_flag, const char draw_type); + +/* mask_shapekey.c */ +void ED_mask_layer_shape_auto_key(struct MaskLayer *masklay, const int frame); +int ED_mask_layer_shape_auto_key_all(struct Mask *mask, const int frame); +int ED_mask_layer_shape_auto_key_select(struct Mask *mask, const int frame); + +/* ----------- Mask AnimEdit API ------------------ */ +short ED_masklayer_frames_looper(struct MaskLayer *masklay, struct Scene *scene, + short (*masklay_shape_cb)(struct MaskLayerShape *, struct Scene *)); +void ED_masklayer_make_cfra_list(struct MaskLayer *masklay, ListBase *elems, short onlysel); + +short ED_masklayer_frame_select_check(struct MaskLayer *masklay); +void ED_masklayer_frame_select_set(struct MaskLayer *masklay, short mode); +void ED_masklayer_frames_select_border(struct MaskLayer *masklay, float min, float max, short select_mode); +void ED_mask_select_frames(struct MaskLayer *masklay, short select_mode); +void ED_mask_select_frame(struct MaskLayer *masklay, int selx, short select_mode); + +void ED_masklayer_frames_delete(struct MaskLayer *masklay); +void ED_masklayer_frames_duplicate(struct MaskLayer *masklay); + +#if 0 +void free_gpcopybuf(void); +void copy_gpdata(void); +void paste_gpdata(void); + + void snap_masklayer_frames(struct MaskLayer *masklay, short mode); + void mirror_masklayer_frames(struct MaskLayer *masklay, short mode); +#endif + +#endif /* __ED_MASK_H__ */ diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 8dc83df2977..9c10a270ef8 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -90,6 +90,7 @@ struct Base *ED_object_scene_link(struct Scene *scene, struct Object *ob); void ED_keymap_proportional_cycle(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap); void ED_keymap_proportional_obmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap); +void ED_keymap_proportional_maskmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap); void ED_keymap_proportional_editmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap, const short do_connected); diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 464f2db30a2..4faf82eec36 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -170,6 +170,7 @@ int ED_operator_editmball(struct bContext *C); int ED_operator_uvedit(struct bContext *C); int ED_operator_uvmap(struct bContext *C); int ED_operator_posemode(struct bContext *C); +int ED_operator_mask(struct bContext *C); /* default keymaps, bitflags */ diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index 3bef1f56655..608df8dd9b3 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -71,6 +71,7 @@ enum { TFM_BONESIZE, TFM_BONE_ENVELOPE, TFM_CURVE_SHRINKFATTEN, + TFM_MASK_SHRINKFATTEN, TFM_BONE_ROLL, TFM_TIME_TRANSLATE, TFM_TIME_SLIDE, @@ -96,12 +97,13 @@ enum { #define CTX_BMESH 64 #define CTX_NDOF 128 #define CTX_MOVIECLIP 256 +#define CTX_MASK 512 /* Standalone call to get the transformation center corresponding to the current situation * returns 1 if successful, 0 otherwise (usually means there's no selection) * (if 0 is returns, *vec is unmodified) * */ -int calculateTransformCenter(struct bContext *C, int centerMode, float *cent3d, int *cent2d); +int calculateTransformCenter(struct bContext *C, int centerMode, float cent3d[3], int cent2d[2]); struct TransInfo; struct ScrArea; @@ -166,8 +168,7 @@ typedef struct DepthPeel { struct ListBase; -typedef enum SnapMode -{ +typedef enum SnapMode { SNAP_ALL = 0, SNAP_NOT_SELECTED = 1, SNAP_NOT_OBEDIT = 2 diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 55210080e01..34892fb3c27 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -282,7 +282,7 @@ int ED_view3d_scene_layer_set(int lay, const int *values, int *active); int ED_view3d_context_activate(struct bContext *C); void ED_view3d_draw_offscreen(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, - int winx, int winy, float viewmat[][4], float winmat[][4], int draw_background); + int winx, int winy, float viewmat[][4], float winmat[][4], int do_bgpic); struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag, int draw_background, char err_out[256]); struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(struct Scene *scene, struct Object *camera, int width, int height, unsigned int flag, int drawtype, int draw_background, char err_out[256]); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index b82a0c5e480..bb6f9fad771 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -195,7 +195,8 @@ typedef struct uiLayout uiLayout; /*#define FUN 192*/ /*UNUSED*/ #define BIT 256 -#define BUTPOIN (128 + 64 + 32) +/* button reqyires a pointer */ +#define BUTPOIN (FLO | SHO | CHA) #define BUT (1 << 9) #define ROW (2 << 9) diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index ca19a8092d0..ac59d2a6983 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -151,6 +151,7 @@ enum { TH_SEQ_MOVIE, TH_SEQ_MOVIECLIP, + TH_SEQ_MASK, TH_SEQ_IMAGE, TH_SEQ_SCENE, TH_SEQ_AUDIO, @@ -203,7 +204,20 @@ enum { TH_MATCH, /* highlight color for search matches */ TH_SELECT_HIGHLIGHT, /* highlight color for selected outliner item */ - TH_SKIN_ROOT + TH_SKIN_ROOT, + + TH_ANIM_ACTIVE, /* active action */ + TH_ANIM_INACTIVE, /* no active action */ + + TH_NLA_TWEAK, /* 'tweaking' track in NLA */ + TH_NLA_TWEAK_DUPLI, /* error/warning flag for other strips referencing dupli strip */ + + TH_NLA_TRANSITION, + TH_NLA_TRANSITION_SEL, + TH_NLA_META, + TH_NLA_META_SEL, + TH_NLA_SOUND, + TH_NLA_SOUND_SEL }; /* XXX WARNING: previous is saved in file, so do not change order! */ @@ -242,6 +256,9 @@ void UI_GetThemeColor3fv(int colorid, float col[3]); void UI_GetThemeColorShade3fv(int colorid, int offset, float col[3]); void UI_GetThemeColorShade3ubv(int colorid, int offset, unsigned char col[3]); +// get four color values, scaled to 0.0-1.0 range +void UI_GetThemeColor4fv(int colorid, float col[4]); + // get the 3 or 4 byte values void UI_GetThemeColor3ubv(int colorid, unsigned char col[3]); void UI_GetThemeColor4ubv(int colorid, unsigned char col[4]); diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index a0b418c1a9a..f368e7cf4c7 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -43,6 +43,7 @@ #include "BKE_colortools.h" #include "BKE_texture.h" +#include "BKE_tracking.h" #include "IMB_imbuf.h" @@ -658,37 +659,59 @@ static void draw_scope_end(rctf *rect, GLint *scissor) } static void histogram_draw_one(float r, float g, float b, float alpha, - float x, float y, float w, float h, float *data, int res) + float x, float y, float w, float h, float *data, int res, const short is_line) { int i; - /* under the curve */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - glColor4f(r, g, b, alpha); - - glShadeModel(GL_FLAT); - glBegin(GL_QUAD_STRIP); - glVertex2f(x, y); - glVertex2f(x, y + (data[0] * h)); - for (i = 1; i < res; i++) { - float x2 = x + i * (w / (float)res); - glVertex2f(x2, y + (data[i] * h)); - glVertex2f(x2, y); + if (is_line) { + + glLineWidth(1.5); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glColor4f(r, g, b, alpha); + + /* curve outline */ + + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glEnable(GL_LINE_SMOOTH); + glBegin(GL_LINE_STRIP); + for (i = 0; i < res; i++) { + float x2 = x + i * (w / (float)res); + glVertex2f(x2, y + (data[i] * h)); + } + glEnd(); + glDisable(GL_LINE_SMOOTH); + + glLineWidth(1.0); } - glEnd(); - - /* curve outline */ - glColor4f(0.f, 0.f, 0.f, 0.25f); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_LINE_SMOOTH); - glBegin(GL_LINE_STRIP); - for (i = 0; i < res; i++) { - float x2 = x + i * (w / (float)res); - glVertex2f(x2, y + (data[i] * h)); + else { + /* under the curve */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glColor4f(r, g, b, alpha); + + glShadeModel(GL_FLAT); + glBegin(GL_QUAD_STRIP); + glVertex2f(x, y); + glVertex2f(x, y + (data[0] * h)); + for (i = 1; i < res; i++) { + float x2 = x + i * (w / (float)res); + glVertex2f(x2, y + (data[i] * h)); + glVertex2f(x2, y); + } + glEnd(); + + /* curve outline */ + glColor4f(0.f, 0.f, 0.f, 0.25f); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_LINE_SMOOTH); + glBegin(GL_LINE_STRIP); + for (i = 0; i < res; i++) { + float x2 = x + i * (w / (float)res); + glVertex2f(x2, y + (data[i] * h)); + } + glEnd(); + glDisable(GL_LINE_SMOOTH); } - glEnd(); - glDisable(GL_LINE_SMOOTH); } void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti) @@ -698,6 +721,7 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol) rctf rect; int i; float w, h; + const short is_line = (hist->flag & HISTO_FLAG_LINE) != 0; //float alpha; GLint scissor[4]; @@ -730,15 +754,19 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol) fdrawline(rect.xmin + (i / 4.f) * w, rect.ymin, rect.xmin + (i / 4.f) * w, rect.ymax); } - if (hist->mode == HISTO_MODE_LUMA) - histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_luma, res); + if (hist->mode == HISTO_MODE_LUMA) { + histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_luma, res, is_line); + } + else if (hist->mode == HISTO_MODE_ALPHA) { + histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_a, res, is_line); + } else { if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_R) - histogram_draw_one(1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res); + histogram_draw_one(1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res, is_line); if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_G) - histogram_draw_one(0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res); + histogram_draw_one(0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res, is_line); if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_B) - histogram_draw_one(0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res); + histogram_draw_one(0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res, is_line); } /* outline, scale gripper */ @@ -1480,36 +1508,10 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *rect fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax); } -static ImBuf *scale_trackpreview_ibuf(ImBuf *ibuf, float track_pos[2], int width, float height, int margin) -{ - ImBuf *scaleibuf; - const float scalex = ((float)ibuf->x - 2 * margin) / width; - const float scaley = ((float)ibuf->y - 2 * margin) / height; - /* NOTE: 1.0f = 0.5f for integer coordinate coorrection (center of pixel vs. left bottom corner of bixel) - * and 0.5f for centering image in preview (cross is draving at exact center of widget so image - * should be shifted by half of pixel for correct centering) - sergey */ - float off_x = (int)track_pos[0] - track_pos[0] + 1.0f; - float off_y = (int)track_pos[1] - track_pos[1] + 1.0f; - int x, y; - - scaleibuf = IMB_allocImBuf(width, height, 32, IB_rect); - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - float src_x = scalex * (x) + margin - off_x; - float src_y = scaley * (y) + margin - off_y; - - bicubic_interpolation(ibuf, scaleibuf, src_x, src_y, x, y); - } - } - - return scaleibuf; -} - void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti) { rctf rect; - int ok = 0; + int ok = 0, width, height; GLint scissor[4]; MovieClipScopes *scopes = (MovieClipScopes *)but->poin; @@ -1518,6 +1520,9 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc rect.ymin = (float)recti->ymin + SCOPE_RESIZE_PAD + 2; rect.ymax = (float)recti->ymax - 1; + width = rect.xmax - rect.xmin + 1; + height = rect.ymax - rect.ymin; + glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -1535,40 +1540,53 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc ok = 1; } - else if (scopes->track_preview) { - /* additional margin around image */ - /* NOTE: should be kept in sync with value from BKE_movieclip_update_scopes */ - const int margin = 3; - float zoomx, zoomy, track_pos[2], off_x, off_y; - int a, width, height; + else if ((scopes->track_search) && + ((!scopes->track_preview) || + (scopes->track_preview->x != width || scopes->track_preview->y != height))) + { + ImBuf *tmpibuf; + + if (scopes->track_preview) + IMB_freeImBuf(scopes->track_preview); + + tmpibuf = BKE_tracking_sample_pattern_imbuf(scopes->frame_width, scopes->frame_height, + scopes->track_search, &scopes->undist_marker, + width, height, scopes->track_pos); + + if (tmpibuf->rect_float) + IMB_rect_from_float(tmpibuf); + + // XXX: for debug only + // tmpibuf->ftype = PNG; + // IMB_saveiff(tmpibuf, "sample.png", IB_rect); + + if (tmpibuf->rect) + scopes->track_preview = tmpibuf; + else + IMB_freeImBuf(tmpibuf); + } + + if (!ok && scopes->track_preview) { + float track_pos[2]; + int a; ImBuf *drawibuf; glPushMatrix(); - track_pos[0] = scopes->track_pos[0] - margin; - track_pos[1] = scopes->track_pos[1] - margin; + track_pos[0] = scopes->track_pos[0]; + track_pos[1] = scopes->track_pos[1]; /* draw content of pattern area */ glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin + rect.ymin, scissor[2], scissor[3]); - width = rect.xmax - rect.xmin + 1; - height = rect.ymax - rect.ymin; - if (width > 0 && height > 0) { - zoomx = (float)width / (scopes->track_preview->x - 2 * margin); - zoomy = (float)height / (scopes->track_preview->y - 2 * margin); - - off_x = ((int)track_pos[0] - track_pos[0] + 0.5f) * zoomx; - off_y = ((int)track_pos[1] - track_pos[1] + 0.5f) * zoomy; - - drawibuf = scale_trackpreview_ibuf(scopes->track_preview, track_pos, width, height, margin); + drawibuf = scopes->track_preview; glaDrawPixelsSafe(rect.xmin, rect.ymin + 1, drawibuf->x, drawibuf->y, drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect); - IMB_freeImBuf(drawibuf); /* draw cross for pizel position */ - glTranslatef(off_x + rect.xmin + track_pos[0] * zoomx, off_y + rect.ymin + track_pos[1] * zoomy, 0.f); + glTranslatef(rect.xmin + track_pos[0], rect.ymin + track_pos[1], 0.f); glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin + rect.ymin, rect.xmax - rect.xmin, diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 8753c427816..a2adbd7a143 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -3819,22 +3819,21 @@ static int ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx Histogram *hist = (Histogram *)but->poin; /* rcti rect; */ int changed = 1; - float /* dx, */ dy, yfac = 1.f; /* UNUSED */ + float /* dx, */ dy; /* UNUSED */ /* rect.xmin = but->x1; rect.xmax = but->x2; */ /* rect.ymin = but->y1; rect.ymax = but->y2; */ /* dx = mx - data->draglastx; */ /* UNUSED */ dy = my - data->draglasty; - - + if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) { /* resize histogram widget itself */ hist->height = (but->y2 - but->y1) + (data->dragstarty - my); } else { /* scale histogram values */ - yfac = MIN2(powf(hist->ymax, 2.f), 1.f) * 0.5f; + const float yfac = MIN2(powf(hist->ymax, 2.f), 1.f) * 0.5f; hist->ymax += dy * yfac; CLAMP(hist->ymax, 1.f, 100.f); diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 21f87029cb0..7f9a998e6d0 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -166,13 +166,14 @@ static int panels_re_align(ScrArea *sa, ARegion *ar, Panel **r_pa) static void panels_collapse_all(ScrArea *sa, ARegion *ar) { - Panel *pa; - int flag = ((panel_aligned(sa, ar)==BUT_HORIZONTAL)? PNL_CLOSEDX: PNL_CLOSEDY); + Panel *pa; + int flag = ((panel_aligned(sa, ar) == BUT_HORIZONTAL) ? PNL_CLOSEDX : PNL_CLOSEDY); - for (pa= ar->panels.first; pa; pa= pa->next) { - if (pa->type && !(pa->type->flag & PNL_NO_HEADER)) - pa->flag = flag; - } + for (pa = ar->panels.first; pa; pa = pa->next) { + if (pa->type && !(pa->type->flag & PNL_NO_HEADER)) { + pa->flag = flag; + } + } } diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index dee9368bbc6..eae721ef484 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -580,8 +580,10 @@ void uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, co row = uiLayoutRow(layout, 1); /* Label - either use the provided text, or will become "ID-Block:" */ - if (text) - uiItemL(row, text, ICON_NONE); + if (text) { + if (text[0]) + uiItemL(row, text, ICON_NONE); + } else uiItemL(row, "ID-Block:", ICON_NONE); @@ -2240,6 +2242,20 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe uiItemL(split, name, ICON_OBJECT_DATA); } } + else if (itemptr->type == &RNA_MaskLayer) { + split = uiLayoutSplit(sub, 0.5f, 0); + + uiItemL(split, name, icon); + + uiBlockSetEmboss(block, UI_EMBOSSN); + row = uiLayoutRow(split, 1); + // uiItemR(row, itemptr, "alpha", 0, "", ICON_NONE); // enable when used + uiItemR(row, itemptr, "hide", 0, "", 0); + uiItemR(row, itemptr, "hide_select", 0, "", 0); + uiItemR(row, itemptr, "hide_render", 0, "", 0); + + uiBlockSetEmboss(block, UI_EMBOSS); + } /* There is a last chance to display custom controls (in addition to the name/label): * If the given item property group features a string property named as prop_list, diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 1a7fc98ef74..004c5306d65 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -162,9 +162,10 @@ static unsigned int scroll_circle_face[14][3] = { }; -static float menu_tria_vert[6][2]= { -{-0.33, 0.16}, {0.33, 0.16}, {0, 0.82}, -{0, -0.82}, {-0.33, -0.16}, {0.33, -0.16}}; +static float menu_tria_vert[6][2] = { + {-0.33, 0.16}, {0.33, 0.16}, {0, 0.82}, + {0, -0.82}, {-0.33, -0.16}, {0.33, -0.16} +}; @@ -1168,7 +1169,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b #if 0 ui_rasterpos_safe(x, y, but->aspect); - if (but->type == IDPOIN) transopts = 0; // no translation, of course! + if (but->type == IDPOIN) transopts = 0; // no translation, of course! else transopts = ui_translate_buttons(); #endif @@ -3133,7 +3134,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct if (but->drawflag & UI_BUT_DRAW_ENUM_ARROWS) wt = widget_type(UI_WTYPE_MENU_RADIO); /* with arrows */ else - wt = widget_type(UI_WTYPE_MENU_ICON_RADIO); /* no arrows */ + wt = widget_type(UI_WTYPE_MENU_ICON_RADIO); /* no arrows */ } /* with menu arrows */ else diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 027655e393f..f39510666ec 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -376,6 +376,8 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo cp = ts->movie; break; case TH_SEQ_MOVIECLIP: cp = ts->movieclip; break; + case TH_SEQ_MASK: + cp = ts->mask; break; case TH_SEQ_IMAGE: cp = ts->image; break; case TH_SEQ_SCENE: @@ -477,6 +479,39 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo case TH_SKIN_ROOT: cp = ts->skin_root; break; + + case TH_ANIM_ACTIVE: + cp = ts->anim_active; + break; + case TH_ANIM_INACTIVE: + cp = ts->anim_non_active; + break; + + case TH_NLA_TWEAK: + cp = ts->nla_tweaking; + break; + case TH_NLA_TWEAK_DUPLI: + cp = ts->nla_tweakdupli; + break; + + case TH_NLA_TRANSITION: + cp = ts->nla_transition; + break; + case TH_NLA_TRANSITION_SEL: + cp = ts->nla_transition_sel; + break; + case TH_NLA_META: + cp = ts->nla_meta; + break; + case TH_NLA_META_SEL: + cp = ts->nla_meta_sel; + break; + case TH_NLA_SOUND: + cp = ts->nla_sound; + break; + case TH_NLA_SOUND_SEL: + cp = ts->nla_sound_sel; + break; } } } @@ -741,19 +776,34 @@ void ui_theme_init_default(void) rgba_char_args_set(btheme->tipo.handle_sel_auto_clamped, 0xf0, 0xaf, 0x90, 255); btheme->tipo.handle_vertex_size = 4; - rgba_char_args_set(btheme->tipo.ds_channel, 82, 96, 110, 255); + rgba_char_args_set(btheme->tipo.ds_channel, 82, 96, 110, 255); rgba_char_args_set(btheme->tipo.ds_subchannel, 124, 137, 150, 255); - rgba_char_args_set(btheme->tipo.group, 79, 101, 73, 255); - rgba_char_args_set(btheme->tipo.group_active, 135, 177, 125, 255); + rgba_char_args_set(btheme->tipo.group, 79, 101, 73, 255); + rgba_char_args_set(btheme->tipo.group_active, 135, 177, 125, 255); /* dopesheet */ btheme->tact = btheme->tipo; rgba_char_args_set(btheme->tact.strip, 12, 10, 10, 128); rgba_char_args_set(btheme->tact.strip_select, 255, 140, 0, 255); + rgba_char_args_set(btheme->tact.anim_active, 204, 112, 26, 102); + /* space nla */ btheme->tnla = btheme->tact; + rgba_char_args_set(btheme->tnla.anim_active, 204, 112, 26, 102); /* same as for dopesheet; duplicate here for easier reference */ + rgba_char_args_set(btheme->tnla.anim_non_active, 153, 135, 97, 77); + + rgba_char_args_set(btheme->tnla.nla_tweaking, 77, 243, 26, 77); + rgba_char_args_set(btheme->tnla.nla_tweakdupli, 217, 0, 0, 255); + + rgba_char_args_set(btheme->tnla.nla_transition, 28, 38, 48, 255); + rgba_char_args_set(btheme->tnla.nla_transition_sel, 46, 117, 219, 255); + rgba_char_args_set(btheme->tnla.nla_meta, 51, 38, 66, 255); + rgba_char_args_set(btheme->tnla.nla_meta_sel, 105, 33, 150, 255); + rgba_char_args_set(btheme->tnla.nla_sound, 43, 61, 61, 255); + rgba_char_args_set(btheme->tnla.nla_sound_sel, 31, 122, 122, 255); + /* space file */ /* to have something initialized */ btheme->tfile = btheme->tv3d; @@ -777,6 +827,7 @@ void ui_theme_init_default(void) rgba_char_args_set(btheme->tseq.back, 116, 116, 116, 255); rgba_char_args_set(btheme->tseq.movie, 81, 105, 135, 255); rgba_char_args_set(btheme->tseq.movieclip, 32, 32, 143, 255); + rgba_char_args_set(btheme->tseq.mask, 152, 78, 62, 255); rgba_char_args_set(btheme->tseq.image, 109, 88, 129, 255); rgba_char_args_set(btheme->tseq.scene, 78, 152, 62, 255); rgba_char_args_set(btheme->tseq.audio, 46, 143, 143, 255); @@ -1049,6 +1100,17 @@ void UI_GetThemeColor3fv(int colorid, float col[3]) col[2] = ((float)cp[2]) / 255.0f; } +void UI_GetThemeColor4fv(int colorid, float col[4]) +{ + const unsigned char *cp; + + cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid); + col[0] = ((float)cp[0]) / 255.0f; + col[1] = ((float)cp[1]) / 255.0f; + col[2] = ((float)cp[2]) / 255.0f; + col[3] = ((float)cp[3]) / 255.0f; +} + // get the color, range 0.0-1.0, complete with shading offset void UI_GetThemeColorShade3fv(int colorid, int offset, float col[3]) { @@ -1822,6 +1884,38 @@ void init_userdef_do_versions(void) for (btheme = U.themes.first; btheme; btheme = btheme->next) rgba_char_args_set(btheme->tv3d.skin_root, 180, 77, 77, 255); } + + if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 7)) { + bTheme *btheme; + + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + /* DopeSheet Summary */ + rgba_char_args_set(btheme->tact.anim_active, 204, 112, 26, 102); + + /* NLA Colors */ + rgba_char_args_set(btheme->tnla.anim_active, 204, 112, 26, 102); /* same as dopesheet above */ + rgba_char_args_set(btheme->tnla.anim_non_active,153, 135, 97, 77); + + rgba_char_args_set(btheme->tnla.nla_tweaking, 77, 243, 26, 77); + rgba_char_args_set(btheme->tnla.nla_tweakdupli, 217, 0, 0, 255); + + rgba_char_args_set(btheme->tnla.nla_transition, 28, 38, 48, 255); + rgba_char_args_set(btheme->tnla.nla_transition_sel, 46, 117, 219, 255); + rgba_char_args_set(btheme->tnla.nla_meta, 51, 38, 66, 255); + rgba_char_args_set(btheme->tnla.nla_meta_sel, 105, 33, 150, 255); + rgba_char_args_set(btheme->tnla.nla_sound, 43, 61, 61, 255); + rgba_char_args_set(btheme->tnla.nla_sound_sel, 31, 122, 122, 255); + } + } + + if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 11)) { + bTheme *btheme; + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + if (btheme->tseq.movieclip[0] == 0) { + rgba_char_args_set(btheme->tseq.mask, 152, 78, 62, 255); + } + } + } /* Freestyle color settings */ { diff --git a/source/blender/editors/mask/CMakeLists.txt b/source/blender/editors/mask/CMakeLists.txt new file mode 100644 index 00000000000..57be5a2234a --- /dev/null +++ b/source/blender/editors/mask/CMakeLists.txt @@ -0,0 +1,52 @@ +# ***** 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) 2012 Blender Foundation. +# +# Contributor(s): Blender Foundation, +# Sergey Sharybin +# +# ***** END GPL LICENSE BLOCK ***** + +set(INC + ../include + ../../blenkernel + ../../blenloader + ../../blenlib + ../../makesdna + ../../makesrna + ../../windowmanager + ../../../../intern/guardedalloc + ${GLEW_INCLUDE_PATH} +) + +set(INC_SYS +) + +set(SRC + mask_add.c + mask_draw.c + mask_edit.c + mask_editaction.c + mask_ops.c + mask_relationships.c + mask_select.c + mask_shapekey.c + + mask_intern.h +) + +blender_add_lib(bf_editor_mask "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/editors/mask/SConscript b/source/blender/editors/mask/SConscript new file mode 100644 index 00000000000..4af000d038d --- /dev/null +++ b/source/blender/editors/mask/SConscript @@ -0,0 +1,9 @@ +#!/usr/bin/python +Import ('env') + +sources = env.Glob('*.c') +defs = [] +incs = '../include ../../blenkernel ../../blenloader ../../blenlib ../../windowmanager ../../makesdna' +incs += ' ../../makesrna #/extern/glew/include #/intern/guardedalloc' + +env.BlenderLib ( 'bf_editors_mask', sources, Split(incs), defs, libtype=['core'], priority=[100] ) diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c new file mode 100644 index 00000000000..0bc9adb6577 --- /dev/null +++ b/source/blender/editors/mask/mask_add.c @@ -0,0 +1,711 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_add.c + * \ingroup edmask + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_mask.h" + +#include "DNA_scene_types.h" +#include "DNA_mask_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_mask.h" /* own include */ + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "mask_intern.h" /* own include */ + + +static int find_nearest_diff_point(bContext *C, Mask *mask, const float normal_co[2], int threshold, int feather, + MaskLayer **masklay_r, MaskSpline **spline_r, MaskSplinePoint **point_r, + float *u_r, float tangent[2], + const short use_deform) +{ + MaskLayer *masklay, *point_masklay; + MaskSpline *point_spline; + MaskSplinePoint *point = NULL; + float dist, co[2]; + int width, height; + float u; + float scalex, scaley, aspx, aspy; + + ED_mask_size(C, &width, &height); + ED_mask_aspect(C, &aspx, &aspy); + ED_mask_pixelspace_factor(C, &scalex, &scaley); + + co[0] = normal_co[0] * scalex; + co[1] = normal_co[1] * scaley; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + MaskSplinePoint *cur_point; + + for (i = 0, cur_point = use_deform ? spline->points_deform : spline->points; + i < spline->tot_point; + i++, cur_point++) + { + float *diff_points; + int tot_diff_point; + + diff_points = BKE_mask_point_segment_diff_with_resolution(spline, cur_point, width, height, + &tot_diff_point); + + if (diff_points) { + int i, tot_feather_point, tot_point; + float *feather_points = NULL, *points; + + if (feather) { + feather_points = BKE_mask_point_segment_feather_diff_with_resolution(spline, cur_point, + width, height, + &tot_feather_point); + + points = feather_points; + tot_point = tot_feather_point; + } + else { + points = diff_points; + tot_point = tot_diff_point; + } + + for (i = 0; i < tot_point - 1; i++) { + float cur_dist, a[2], b[2]; + + a[0] = points[2 * i] * scalex; + a[1] = points[2 * i + 1] * scaley; + + b[0] = points[2 * i + 2] * scalex; + b[1] = points[2 * i + 3] * scaley; + + cur_dist = dist_to_line_segment_v2(co, a, b); + + if (point == NULL || cur_dist < dist) { + if (tangent) + sub_v2_v2v2(tangent, &diff_points[2 * i + 2], &diff_points[2 * i]); + + point_masklay = masklay; + point_spline = spline; + point = use_deform ? &spline->points[(cur_point - spline->points_deform)] : cur_point; + dist = cur_dist; + u = (float)i / tot_point; + + } + } + + if (feather_points) + MEM_freeN(feather_points); + + MEM_freeN(diff_points); + } + } + } + } + + if (point && dist < threshold) { + if (masklay_r) + *masklay_r = point_masklay; + + if (spline_r) + *spline_r = point_spline; + + if (point_r) + *point_r = point; + + if (u_r) { + u = BKE_mask_spline_project_co(point_spline, point, u, normal_co, MASK_PROJ_ANY); + + *u_r = u; + } + + return TRUE; + } + + if (masklay_r) + *masklay_r = NULL; + + if (spline_r) + *spline_r = NULL; + + if (point_r) + *point_r = NULL; + + return FALSE; +} + +/******************** add vertex *********************/ + +static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, MaskSplinePoint *new_point, + const float point_co[2], const float tangent[2], const float u, + MaskSplinePoint *reference_point, const short reference_adjacent) +{ + MaskSplinePoint *prev_point = NULL; + MaskSplinePoint *next_point = NULL; + BezTriple *bezt; + int width, height; + float co[3]; + const float len = 20.0; /* default length of handle in pixel space */ + + copy_v2_v2(co, point_co); + co[2] = 0.0f; + + ED_mask_size(C, &width, &height); + + /* point coordinate */ + bezt = &new_point->bezt; + + bezt->h1 = bezt->h2 = HD_ALIGN; + + if (reference_point) { + bezt->h1 = bezt->h2 = MAX2(reference_point->bezt.h2, reference_point->bezt.h1); + } + else if (reference_adjacent) { + if (spline->tot_point != 1) { + int index = (int)(new_point - spline->points); + prev_point = &spline->points[(index - 1) % spline->tot_point]; + next_point = &spline->points[(index + 1) % spline->tot_point]; + + bezt->h1 = bezt->h2 = MAX2(prev_point->bezt.h2, next_point->bezt.h1); + + /* note, we may want to copy other attributes later, radius? pressure? color? */ + } + } + + copy_v3_v3(bezt->vec[0], co); + copy_v3_v3(bezt->vec[1], co); + copy_v3_v3(bezt->vec[2], co); + + /* initial offset for handles */ + if (spline->tot_point == 1) { + /* first point of splien is aligned horizontally */ + bezt->vec[0][0] -= len / width; + bezt->vec[2][0] += len / width; + } + else if (tangent) { + float vec[2]; + + copy_v2_v2(vec, tangent); + + vec[0] *= width; + vec[1] *= height; + + mul_v2_fl(vec, len / len_v2(vec)); + + vec[0] /= width; + vec[1] /= height; + + sub_v2_v2(bezt->vec[0], vec); + add_v2_v2(bezt->vec[2], vec); + + if (reference_adjacent) { + BKE_mask_calc_handle_adjacent_interp(spline, new_point, u); + } + } + else { + + /* calculating auto handles works much nicer */ +#if 0 + /* next points are aligning in the direction of previous/next point */ + MaskSplinePoint *point; + float v1[2], v2[2], vec[2]; + float dir = 1.0f; + + if (new_point == spline->points) { + point = new_point + 1; + dir = -1.0f; + } + else + point = new_point - 1; + + if (spline->tot_point < 3) { + v1[0] = point->bezt.vec[1][0] * width; + v1[1] = point->bezt.vec[1][1] * height; + + v2[0] = new_point->bezt.vec[1][0] * width; + v2[1] = new_point->bezt.vec[1][1] * height; + } + else { + if (new_point == spline->points) { + v1[0] = spline->points[1].bezt.vec[1][0] * width; + v1[1] = spline->points[1].bezt.vec[1][1] * height; + + v2[0] = spline->points[spline->tot_point - 1].bezt.vec[1][0] * width; + v2[1] = spline->points[spline->tot_point - 1].bezt.vec[1][1] * height; + } + else { + v1[0] = spline->points[0].bezt.vec[1][0] * width; + v1[1] = spline->points[0].bezt.vec[1][1] * height; + + v2[0] = spline->points[spline->tot_point - 2].bezt.vec[1][0] * width; + v2[1] = spline->points[spline->tot_point - 2].bezt.vec[1][1] * height; + } + } + + sub_v2_v2v2(vec, v1, v2); + mul_v2_fl(vec, len * dir / len_v2(vec)); + + vec[0] /= width; + vec[1] /= height; + + add_v2_v2(bezt->vec[0], vec); + sub_v2_v2(bezt->vec[2], vec); +#else + BKE_mask_calc_handle_point_auto(spline, new_point, TRUE); + BKE_mask_calc_handle_adjacent_interp(spline, new_point, u); + +#endif + } + + BKE_mask_parent_init(&new_point->parent); + + /* select new point */ + MASKPOINT_SEL_ALL(new_point); + ED_mask_select_flush_all(mask); +} + + +/* **** add extrude vertex **** */ + +static void finSelectedSplinePoint(MaskLayer *masklay, MaskSpline **spline, MaskSplinePoint **point, short check_active) +{ + MaskSpline *cur_spline = masklay->splines.first; + + *spline = NULL; + *point = NULL; + + if (check_active) { + if (masklay->act_spline && masklay->act_point && MASKPOINT_ISSEL_ANY(masklay->act_point)) { + *spline = masklay->act_spline; + *point = masklay->act_point; + return; + } + } + + while (cur_spline) { + int i; + + for (i = 0; i < cur_spline->tot_point; i++) { + MaskSplinePoint *cur_point = &cur_spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(cur_point)) { + if (*spline != NULL && *spline != cur_spline) { + *spline = NULL; + *point = NULL; + return; + } + else if (*point) { + *point = NULL; + } + else { + *spline = cur_spline; + *point = cur_point; + } + } + } + + cur_spline = cur_spline->next; + } +} + +/* **** add subdivide vertex **** */ + +static void mask_spline_add_point_at_index(MaskSpline *spline, int point_index) +{ + MaskSplinePoint *new_point_array; + + new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1), "add mask vert points"); + + memcpy(new_point_array, spline->points, sizeof(MaskSplinePoint) * (point_index + 1)); + memcpy(new_point_array + point_index + 2, spline->points + point_index + 1, + sizeof(MaskSplinePoint) * (spline->tot_point - point_index - 1)); + + MEM_freeN(spline->points); + spline->points = new_point_array; + spline->tot_point++; +} + +static int add_vertex_subdivide(bContext *C, Mask *mask, const float co[2]) +{ + MaskLayer *masklay; + MaskSpline *spline; + MaskSplinePoint *point = NULL; + const float threshold = 9; + float tangent[2]; + float u; + + if (find_nearest_diff_point(C, mask, co, threshold, FALSE, &masklay, &spline, &point, &u, tangent, TRUE)) { + MaskSplinePoint *new_point; + int point_index = point - spline->points; + + ED_mask_select_toggle_all(mask, SEL_DESELECT); + + mask_spline_add_point_at_index(spline, point_index); + + new_point = &spline->points[point_index + 1]; + + setup_vertex_point(C, mask, spline, new_point, co, tangent, u, NULL, TRUE); + + /* TODO - we could pass the spline! */ + BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index + 1, TRUE, TRUE); + + masklay->act_point = new_point; + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + return TRUE; + } + + return FALSE; +} + +static int add_vertex_extrude(bContext *C, Mask *mask, MaskLayer *masklay, const float co[2]) +{ + MaskSpline *spline; + MaskSplinePoint *point; + MaskSplinePoint *new_point = NULL, *ref_point = NULL; + + /* check on which side we want to add the point */ + int point_index; + float tangent_point[2]; + float tangent_co[2]; + int do_cyclic_correct = FALSE; + int do_recalc_src = FALSE; /* when extruding from endpoints only */ + int do_prev; /* use prev point rather then next?? */ + + if (!masklay) { + return FALSE; + } + else { + finSelectedSplinePoint(masklay, &spline, &point, TRUE); + } + + ED_mask_select_toggle_all(mask, SEL_DESELECT); + + point_index = (point - spline->points); + + MASKPOINT_DESEL_ALL(point); + + if ((spline->flag & MASK_SPLINE_CYCLIC) || + (point_index > 0 && point_index != spline->tot_point - 1)) + { + BKE_mask_calc_tangent_polyline(spline, point, tangent_point); + sub_v2_v2v2(tangent_co, co, point->bezt.vec[1]); + + if (dot_v2v2(tangent_point, tangent_co) < 0.0f) { + do_prev = TRUE; + } + else { + do_prev = FALSE; + } + } + else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == 0)) { + do_prev = TRUE; + do_recalc_src = TRUE; + } + else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == spline->tot_point - 1)) { + do_prev = FALSE; + do_recalc_src = TRUE; + } + else { + do_prev = FALSE; /* quiet warning */ + /* should never get here */ + BLI_assert(0); + } + + /* use the point before the active one */ + if (do_prev) { + point_index--; + if (point_index < 0) { + point_index += spline->tot_point; /* wrap index */ + if ((spline->flag & MASK_SPLINE_CYCLIC) == 0) { + do_cyclic_correct = TRUE; + point_index = 0; + } + } + } + +// print_v2("", tangent_point); +// printf("%d\n", point_index); + + mask_spline_add_point_at_index(spline, point_index); + + if (do_cyclic_correct) { + ref_point = &spline->points[point_index + 1]; + new_point = &spline->points[point_index]; + *ref_point = *new_point; + memset(new_point, 0, sizeof(*new_point)); + } + else { + ref_point = &spline->points[point_index]; + new_point = &spline->points[point_index + 1]; + } + + masklay->act_point = new_point; + + setup_vertex_point(C, mask, spline, new_point, co, NULL, 0.5f, ref_point, FALSE); + + if (masklay->splines_shapes.first) { + point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); + BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index, TRUE, TRUE); + } + + if (do_recalc_src) { + /* TODO, update keyframes in time */ + BKE_mask_calc_handle_point_auto(spline, ref_point, FALSE); + } + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + return TRUE; +} + +static int add_vertex_new(bContext *C, Mask *mask, MaskLayer *masklay, const float co[2]) +{ + MaskSpline *spline; + MaskSplinePoint *point; + MaskSplinePoint *new_point = NULL, *ref_point = NULL; + + if (!masklay) { + /* if there's no masklay currently operationg on, create new one */ + masklay = BKE_mask_layer_new(mask, ""); + mask->masklay_act = mask->masklay_tot - 1; + spline = NULL; + point = NULL; + } + else { + finSelectedSplinePoint(masklay, &spline, &point, TRUE); + } + + ED_mask_select_toggle_all(mask, SEL_DESELECT); + + if (!spline) { + /* no selected splines in active masklay, create new spline */ + spline = BKE_mask_spline_add(masklay); + } + + masklay->act_spline = spline; + new_point = spline->points; + + masklay->act_point = new_point; + + setup_vertex_point(C, mask, spline, new_point, co, NULL, 0.5f, ref_point, FALSE); + + { + int point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); + BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index, TRUE, TRUE); + } + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + return TRUE; +} + +static int add_vertex_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + + float co[2]; + + masklay = BKE_mask_layer_active(mask); + + if (masklay && masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + masklay = NULL; + } + + RNA_float_get_array(op->ptr, "location", co); + + if (masklay && masklay->act_point && MASKPOINT_ISSEL_ANY(masklay->act_point)) { + + /* cheap trick - double click for cyclic */ + MaskSpline *spline = masklay->act_spline; + MaskSplinePoint *point = masklay->act_point; + + int is_sta = (point == spline->points); + int is_end = (point == &spline->points[spline->tot_point - 1]); + + /* then check are we overlapping the mouse */ + if ((is_sta || is_end) && equals_v2v2(co, point->bezt.vec[1])) { + if (spline->flag & MASK_SPLINE_CYCLIC) { + /* nothing to do */ + return OPERATOR_CANCELLED; + } + else { + /* recalc the connecting point as well to make a nice even curve */ + MaskSplinePoint *point_other = is_end ? spline->points : &spline->points[spline->tot_point - 1]; + spline->flag |= MASK_SPLINE_CYCLIC; + + /* TODO, update keyframes in time */ + BKE_mask_calc_handle_point_auto(spline, point, FALSE); + BKE_mask_calc_handle_point_auto(spline, point_other, FALSE); + + /* TODO: only update this spline */ + BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + return OPERATOR_FINISHED; + } + } + + if (!add_vertex_subdivide(C, mask, co)) { + if (!add_vertex_extrude(C, mask, masklay, co)) { + return OPERATOR_CANCELLED; + } + } + } + else { + if (!add_vertex_subdivide(C, mask, co)) { + if (!add_vertex_new(C, mask, masklay, co)) { + return OPERATOR_CANCELLED; + } + } + } + + /* TODO: only update this spline */ + BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); + + return OPERATOR_FINISHED; +} + +static int add_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + float co[2]; + + ED_mask_mouse_pos(C, event, co); + + RNA_float_set_array(op->ptr, "location", co); + + return add_vertex_exec(C, op); +} + +void MASK_OT_add_vertex(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Vertex"; + ot->description = "Add vertex to active spline"; + ot->idname = "MASK_OT_add_vertex"; + + /* api callbacks */ + ot->exec = add_vertex_exec; + ot->invoke = add_vertex_invoke; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, + "Location", "Location of vertex in normalized space", -1.0f, 1.0f); +} + +/******************** add feather vertex *********************/ + +static int add_feather_vertex_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + MaskSpline *spline; + MaskSplinePoint *point = NULL; + const float threshold = 9; + float co[2], u; + + RNA_float_get_array(op->ptr, "location", co); + + point = ED_mask_point_find_nearest(C, mask, co, threshold, NULL, NULL, NULL, NULL); + if (point) + return OPERATOR_FINISHED; + + if (find_nearest_diff_point(C, mask, co, threshold, TRUE, &masklay, &spline, &point, &u, NULL, TRUE)) { + Scene *scene = CTX_data_scene(C); + float w = BKE_mask_point_weight(spline, point, u); + float weight_scalar = BKE_mask_point_weight_scalar(spline, point, u); + + if (weight_scalar != 0.0f) { + w = w / weight_scalar; + } + + BKE_mask_point_add_uw(point, u, w); + + BKE_mask_update_display(mask, scene->r.cfra); + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +static int add_feather_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + float co[2]; + + ED_mask_mouse_pos(C, event, co); + + RNA_float_set_array(op->ptr, "location", co); + + return add_feather_vertex_exec(C, op); +} + +void MASK_OT_add_feather_vertex(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add feather Vertex"; + ot->description = "Add vertex to feather"; + ot->idname = "MASK_OT_add_feather_vertex"; + + /* api callbacks */ + ot->exec = add_feather_vertex_exec; + ot->invoke = add_feather_vertex_invoke; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, + "Location", "Location of vertex in normalized space", -1.0f, 1.0f); +} diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c new file mode 100644 index 00000000000..e1efb6d841b --- /dev/null +++ b/source/blender/editors/mask/mask_draw.c @@ -0,0 +1,425 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_draw.c + * \ingroup edmask + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_mask.h" + +#include "DNA_mask_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "ED_mask.h" /* own include */ +#include "BIF_gl.h" + +#include "UI_resources.h" + +#include "mask_intern.h" /* own include */ + +static void mask_spline_color_get(MaskLayer *masklay, MaskSpline *spline, const int is_sel, + unsigned char r_rgb[4]) +{ + if (is_sel) { + if (masklay->act_spline == spline) { + r_rgb[0] = r_rgb[1] = r_rgb[2] = 255; + } + else { + r_rgb[0] = 255; + r_rgb[1] = r_rgb[2] = 0; + } + } + else { + r_rgb[0] = 128; + r_rgb[1] = r_rgb[2] = 0; + } + + r_rgb[3] = 255; +} + +static void mask_spline_feather_color_get(MaskLayer *UNUSED(masklay), MaskSpline *UNUSED(spline), const int is_sel, + unsigned char r_rgb[4]) +{ + if (is_sel) { + r_rgb[1] = 255; + r_rgb[0] = r_rgb[2] = 0; + } + else { + r_rgb[1] = 128; + r_rgb[0] = r_rgb[2] = 0; + } + + r_rgb[3] = 255; +} + +#if 0 +static void draw_spline_parents(MaskLayer *UNUSED(masklay), MaskSpline *spline) +{ + int i; + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + + if (!spline->tot_point) + return; + + glColor3ub(0, 0, 0); + glEnable(GL_LINE_STIPPLE); + glLineStipple(1, 0xAAAA); + + glBegin(GL_LINES); + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &points_array[i]; + BezTriple *bezt = &point->bezt; + + if (point->parent.id) { + glVertex2f(bezt->vec[1][0], + bezt->vec[1][1]); + + glVertex2f(bezt->vec[1][0] - point->parent.offset[0], + bezt->vec[1][1] - point->parent.offset[1]); + } + } + + glEnd(); + + glDisable(GL_LINE_STIPPLE); +} +#endif + +/* return non-zero if spline is selected */ +static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline) +{ + const int is_spline_sel = (spline->flag & SELECT) && (masklay->restrictflag & MASK_RESTRICT_SELECT) == 0; + unsigned char rgb_spline[4]; + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + + int i, hsize, tot_feather_point; + float (*feather_points)[2], (*fp)[2]; + + if (!spline->tot_point) + return; + + hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); + + glPointSize(hsize); + + mask_spline_color_get(masklay, spline, is_spline_sel, rgb_spline); + + /* feather points */ + feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point); + for (i = 0; i < spline->tot_point; i++) { + + /* watch it! this is intentionally not the deform array, only check for sel */ + MaskSplinePoint *point = &spline->points[i]; + + int j; + + for (j = 0; j < point->tot_uw + 1; j++) { + int sel = FALSE; + + if (j == 0) { + sel = MASKPOINT_ISSEL_ANY(point); + } + else { + sel = point->uw[j - 1].flag & SELECT; + } + + if (sel) { + if (point == masklay->act_point) + glColor3f(1.0f, 1.0f, 1.0f); + else + glColor3f(1.0f, 1.0f, 0.0f); + } + else { + glColor3f(0.5f, 0.5f, 0.0f); + } + + glBegin(GL_POINTS); + glVertex2fv(*fp); + glEnd(); + + fp++; + } + } + MEM_freeN(feather_points); + + /* control points */ + for (i = 0; i < spline->tot_point; i++) { + + /* watch it! this is intentionally not the deform array, only check for sel */ + MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *point_deform = &points_array[i]; + BezTriple *bezt = &point_deform->bezt; + + float handle[2]; + float *vert = bezt->vec[1]; + int has_handle = BKE_mask_point_has_handle(point); + + BKE_mask_point_handle(point_deform, handle); + + /* draw handle segment */ + if (has_handle) { + glColor3ubv(rgb_spline); + + glBegin(GL_LINES); + glVertex3fv(vert); + glVertex3fv(handle); + glEnd(); + } + + /* draw CV point */ + if (MASKPOINT_ISSEL_KNOT(point)) { + if (point == masklay->act_point) + glColor3f(1.0f, 1.0f, 1.0f); + else + glColor3f(1.0f, 1.0f, 0.0f); + } + else + glColor3f(0.5f, 0.5f, 0.0f); + + glBegin(GL_POINTS); + glVertex3fv(vert); + glEnd(); + + /* draw handle points */ + if (has_handle) { + if (MASKPOINT_ISSEL_HANDLE(point)) { + if (point == masklay->act_point) + glColor3f(1.0f, 1.0f, 1.0f); + else + glColor3f(1.0f, 1.0f, 0.0f); + } + else { + glColor3f(0.5f, 0.5f, 0.0f); + } + + glBegin(GL_POINTS); + glVertex3fv(handle); + glEnd(); + } + } + + glPointSize(1.0f); +} + +/* #define USE_XOR */ + +static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot_point, + const short is_feather, const short is_smooth, + const unsigned char rgb_spline[4], const char draw_type) +{ + const int draw_method = (spline->flag & MASK_SPLINE_CYCLIC) ? GL_LINE_LOOP : GL_LINE_STRIP; + unsigned char rgb_tmp[4]; + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, points); + + switch (draw_type) { + + case MASK_DT_OUTLINE: + glLineWidth(3); + cpack(0x0); + + glDrawArrays(draw_method, 0, tot_point); + + glLineWidth(1); + glColor4ubv(rgb_spline); + glDrawArrays(draw_method, 0, tot_point); + + break; + + case MASK_DT_DASH: + default: + glEnable(GL_LINE_STIPPLE); + +#ifdef USE_XOR + glEnable(GL_COLOR_LOGIC_OP); + glLogicOp(GL_OR); +#endif + glColor4ubv(rgb_spline); + glLineStipple(3, 0xaaaa); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, points); + glDrawArrays(draw_method, 0, tot_point); + +#ifdef USE_XOR + glDisable(GL_COLOR_LOGIC_OP); +#endif + glColor4ub(0, 0, 0, 255); + glLineStipple(3, 0x5555); + glDrawArrays(draw_method, 0, tot_point); + + glDisable(GL_LINE_STIPPLE); + break; + + + case MASK_DT_BLACK: + case MASK_DT_WHITE: + if (draw_type == MASK_DT_BLACK) { rgb_tmp[0] = rgb_tmp[1] = rgb_tmp[2] = 0; } + else { rgb_tmp[0] = rgb_tmp[1] = rgb_tmp[2] = 255; } + /* alpha values seem too low but gl draws many points that compensate for it */ + if (is_feather) { rgb_tmp[3] = 64; } + else { rgb_tmp[3] = 128; } + + if (is_feather) { + rgb_tmp[0] = (unsigned char)(((short)rgb_tmp[0] + (short)rgb_spline[0]) / 2); + rgb_tmp[1] = (unsigned char)(((short)rgb_tmp[1] + (short)rgb_spline[1]) / 2); + rgb_tmp[2] = (unsigned char)(((short)rgb_tmp[2] + (short)rgb_spline[2]) / 2); + } + + if (is_smooth == FALSE && is_feather) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + glColor4ubv(rgb_tmp); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, points); + glDrawArrays(draw_method, 0, tot_point); + + glDrawArrays(draw_method, 0, tot_point); + + if (is_smooth == FALSE && is_feather) { + glDisable(GL_BLEND); + } + + break; + } + + glDisableClientState(GL_VERTEX_ARRAY); + +} + +static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, + const char draw_flag, const char draw_type, + int width, int height) +{ + unsigned char rgb_tmp[4]; + + const short is_spline_sel = (spline->flag & SELECT) && (masklay->restrictflag & MASK_RESTRICT_SELECT) == 0; + const short is_smooth = (draw_flag & MASK_DRAWFLAG_SMOOTH); + + int tot_diff_point; + float (*diff_points)[2]; + + int tot_feather_point; + float (*feather_points)[2]; + + diff_points = BKE_mask_spline_differentiate_with_resolution(spline, width, height, &tot_diff_point); + + if (!diff_points) + return; + + if (is_smooth) { + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution(spline, width, height, &tot_feather_point); + + /* draw feather */ + mask_spline_feather_color_get(masklay, spline, is_spline_sel, rgb_tmp); + mask_draw_curve_type(spline, feather_points, tot_feather_point, + TRUE, is_smooth, + rgb_tmp, draw_type); + MEM_freeN(feather_points); + + /* draw main curve */ + mask_spline_color_get(masklay, spline, is_spline_sel, rgb_tmp); + mask_draw_curve_type(spline, diff_points, tot_diff_point, + FALSE, is_smooth, + rgb_tmp, draw_type); + MEM_freeN(diff_points); + + if (draw_flag & MASK_DRAWFLAG_SMOOTH) { + glDisable(GL_LINE_SMOOTH); + glDisable(GL_BLEND); + } + + (void)draw_type; +} + +static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type, + int width, int height) +{ + MaskLayer *masklay; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + + /* draw curve itself first... */ + draw_spline_curve(masklay, spline, draw_flag, draw_type, width, height); + +// draw_spline_parents(masklay, spline); + + if (!(masklay->restrictflag & MASK_RESTRICT_SELECT)) { + /* ...and then handles over the curve so they're nicely visible */ + draw_spline_points(masklay, spline); + } + + /* show undeform for testing */ + if (0) { + void *back = spline->points_deform; + + spline->points_deform = NULL; + draw_spline_curve(masklay, spline, draw_flag, draw_type, width, height); +// draw_spline_parents(masklay, spline); + draw_spline_points(masklay, spline); + spline->points_deform = back; + } + } + } +} + +void ED_mask_draw(const bContext *C, + const char draw_flag, const char draw_type) +{ + Mask *mask = CTX_data_edit_mask(C); + int width, height; + + if (!mask) + return; + + /* TODO: for now, in the future better to make sure all utility functions + * are using const specifier for non-changing pointers + */ + ED_mask_size((bContext *)C, &width, &height); + + draw_masklays(mask, draw_flag, draw_type, width, height); +} diff --git a/source/blender/editors/mask/mask_edit.c b/source/blender/editors/mask/mask_edit.c new file mode 100644 index 00000000000..24f55f66bb8 --- /dev/null +++ b/source/blender/editors/mask/mask_edit.c @@ -0,0 +1,342 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_edit.c + * \ingroup edmask + */ + + +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_mask.h" + +#include "DNA_scene_types.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_mask.h" /* own include */ +#include "ED_object.h" /* ED_keymap_proportional_maskmode only */ +#include "ED_clip.h" +#include "ED_transform.h" + +#include "RNA_access.h" + +#include "mask_intern.h" /* own include */ + +/********************** generic poll functions *********************/ + +int ED_maskedit_poll(bContext *C) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { + return ED_space_clip_maskedit_poll(C); + } + + return FALSE; +} + +int ED_maskedit_mask_poll(bContext *C) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { + return ED_space_clip_maskedit_mask_poll(C); + } + + return FALSE; +} + +/********************** registration *********************/ + +void ED_mask_mouse_pos(bContext *C, wmEvent *event, float co[2]) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { + ED_clip_mouse_pos(C, event, co); + BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co); + } + else { + /* possible other spaces from which mask editing is available */ + zero_v2(co); + } +} + +/* input: x/y - mval space + * output: xr/yr - mask point space */ +void ED_mask_point_pos(bContext *C, float x, float y, float *xr, float *yr) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + float co[2]; + + if (sc) { + ED_clip_point_stable_pos(C, x, y, &co[0], &co[1]); + BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co); + } + else { + /* possible other spaces from which mask editing is available */ + zero_v2(co); + } + + *xr = co[0]; + *yr = co[1]; +} + +void ED_mask_point_pos__reverse(bContext *C, float x, float y, float *xr, float *yr) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + ARegion *ar = CTX_wm_region(C); + + float co[2]; + + if (sc && ar) { + co[0] = x; + co[1] = y; + BKE_mask_coord_to_movieclip(sc->clip, &sc->user, co, co); + ED_clip_point_stable_pos__reverse(sc, ar, co, co); + } + else { + /* possible other spaces from which mask editing is available */ + zero_v2(co); + } + + *xr = co[0]; + *yr = co[1]; +} + +void ED_mask_size(bContext *C, int *width, int *height) +{ + ScrArea *sa = CTX_wm_area(C); + if (sa && sa->spacedata.first) { + if (sa->spacetype == SPACE_CLIP) { + SpaceClip *sc = sa->spacedata.first; + ED_space_clip_mask_size(sc, width, height); + return; + } + else if (sa->spacetype == SPACE_SEQ) { + Scene *scene = CTX_data_scene(C); + *width = (scene->r.size * scene->r.xsch) / 100; + *height = (scene->r.size * scene->r.ysch) / 100; + return; + } + } + + /* possible other spaces from which mask editing is available */ + *width = 0; + *height = 0; +} + +void ED_mask_aspect(bContext *C, float *aspx, float *aspy) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { + ED_space_clip_mask_aspect(sc, aspx, aspy); + } + else { + /* possible other spaces from which mask editing is available */ + *aspx = 1.0f; + *aspy = 1.0f; + } +} + +void ED_mask_pixelspace_factor(bContext *C, float *scalex, float *scaley) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { + ARegion *ar = CTX_wm_region(C); + int width, height; + float zoomx, zoomy, aspx, aspy; + + ED_space_clip_size(sc, &width, &height); + ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); + ED_space_clip_aspect(sc, &aspx, &aspy); + + *scalex = ((float)width * aspx) * zoomx; + *scaley = ((float)height * aspy) * zoomy; + } + else { + /* possible other spaces from which mask editing is available */ + *scalex = 1.0f; + *scaley = 1.0f; + } +} + +/********************** registration *********************/ + +void ED_operatortypes_mask(void) +{ + WM_operatortype_append(MASK_OT_new); + + /* mask layers */ + WM_operatortype_append(MASK_OT_layer_new); + WM_operatortype_append(MASK_OT_layer_remove); + + /* add */ + WM_operatortype_append(MASK_OT_add_vertex); + WM_operatortype_append(MASK_OT_add_feather_vertex); + + /* geometry */ + WM_operatortype_append(MASK_OT_switch_direction); + WM_operatortype_append(MASK_OT_delete); + + /* select */ + WM_operatortype_append(MASK_OT_select); + WM_operatortype_append(MASK_OT_select_all); + WM_operatortype_append(MASK_OT_select_border); + WM_operatortype_append(MASK_OT_select_lasso); + WM_operatortype_append(MASK_OT_select_circle); + WM_operatortype_append(MASK_OT_select_linked_pick); + WM_operatortype_append(MASK_OT_select_linked); + + /* hide/reveal */ + WM_operatortype_append(MASK_OT_hide_view_clear); + WM_operatortype_append(MASK_OT_hide_view_set); + + /* feather */ + WM_operatortype_append(MASK_OT_feather_weight_clear); + + /* shape */ + WM_operatortype_append(MASK_OT_slide_point); + WM_operatortype_append(MASK_OT_cyclic_toggle); + WM_operatortype_append(MASK_OT_handle_type_set); + + /* relationships */ + WM_operatortype_append(MASK_OT_parent_set); + WM_operatortype_append(MASK_OT_parent_clear); + + /* shapekeys */ + WM_operatortype_append(MASK_OT_shape_key_insert); + WM_operatortype_append(MASK_OT_shape_key_clear); + WM_operatortype_append(MASK_OT_shape_key_feather_reset); +} + +void ED_keymap_mask(wmKeyConfig *keyconf) +{ + wmKeyMap *keymap; + wmKeyMapItem *kmi; + + keymap = WM_keymap_find(keyconf, "Mask Editing", 0, 0); + keymap->poll = ED_maskedit_poll; + + WM_keymap_add_item(keymap, "MASK_OT_new", NKEY, KM_PRESS, KM_ALT, 0); + + /* mask mode supports PET now */ + ED_keymap_proportional_cycle(keyconf, keymap); + ED_keymap_proportional_maskmode(keyconf, keymap); + + /* geometry */ + WM_keymap_add_item(keymap, "MASK_OT_add_vertex_slide", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "MASK_OT_add_feather_vertex_slide", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "MASK_OT_delete", XKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MASK_OT_delete", DELKEY, KM_PRESS, 0, 0); + + /* selection */ + kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_boolean_set(kmi->ptr, "deselect", FALSE); + RNA_boolean_set(kmi->ptr, "toggle", FALSE); + kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_boolean_set(kmi->ptr, "deselect", FALSE); + RNA_boolean_set(kmi->ptr, "toggle", TRUE); + + kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", AKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); + kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + + WM_keymap_add_item(keymap, "MASK_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0); + kmi = WM_keymap_add_item(keymap, "MASK_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "deselect", FALSE); + kmi = WM_keymap_add_item(keymap, "MASK_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "deselect", TRUE); + + WM_keymap_add_item(keymap, "MASK_OT_select_border", BKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MASK_OT_select_circle", CKEY, KM_PRESS, 0, 0); + + kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "deselect", FALSE); + kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT | KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "deselect", TRUE); + + /* hide/reveal */ + WM_keymap_add_item(keymap, "MASK_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0); + kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "unselected", FALSE); + + kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "unselected", TRUE); + + /* select clip while in maker view, + * this matches View3D functionality where you can select an + * object while in editmode to allow vertex parenting */ + kmi = WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + + /* shape */ + WM_keymap_add_item(keymap, "MASK_OT_cyclic_toggle", CKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "MASK_OT_slide_point", LEFTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MASK_OT_handle_type_set", VKEY, KM_PRESS, 0, 0); + // WM_keymap_add_item(keymap, "MASK_OT_feather_weight_clear", SKEY, KM_PRESS, KM_ALT, 0); + /* ... matches curve editmode */ + RNA_enum_set(WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, KM_ALT, 0)->ptr, "mode", TFM_MASK_SHRINKFATTEN); + + /* relationships */ + WM_keymap_add_item(keymap, "MASK_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "MASK_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0); + + WM_keymap_add_item(keymap, "MASK_OT_shape_key_insert", IKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MASK_OT_shape_key_clear", IKEY, KM_PRESS, KM_ALT, 0); + + + transform_keymap_for_space(keyconf, keymap, SPACE_CLIP); +} + +void ED_operatormacros_mask(void) +{ + /* XXX: just for sample */ + wmOperatorType *ot; + wmOperatorTypeMacro *otmacro; + + ot = WM_operatortype_append_macro("MASK_OT_add_vertex_slide", "Add Vertex and Slide", "Add new vertex and slide it", OPTYPE_UNDO | OPTYPE_REGISTER); + ot->description = "Add new vertex and slide it"; + WM_operatortype_macro_define(ot, "MASK_OT_add_vertex"); + otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); + RNA_boolean_set(otmacro->ptr, "release_confirm", TRUE); + + ot = WM_operatortype_append_macro("MASK_OT_add_feather_vertex_slide", "Add Feather Vertex and Slide", "Add new vertex to feater and slide it", OPTYPE_UNDO | OPTYPE_REGISTER); + ot->description = "Add new feather vertex and slide it"; + WM_operatortype_macro_define(ot, "MASK_OT_add_feather_vertex"); + otmacro = WM_operatortype_macro_define(ot, "MASK_OT_slide_point"); + RNA_boolean_set(otmacro->ptr, "slide_feather", TRUE); +} diff --git a/source/blender/editors/mask/mask_editaction.c b/source/blender/editors/mask/mask_editaction.c new file mode 100644 index 00000000000..3836b393bf8 --- /dev/null +++ b/source/blender/editors/mask/mask_editaction.c @@ -0,0 +1,250 @@ +/* + * ***** 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) 2008, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_editaction.c + * \ingroup edgpencil + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stddef.h> +#include <math.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "DNA_mask_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BKE_fcurve.h" +#include "BKE_mask.h" + +#include "ED_anim_api.h" +#include "ED_keyframes_edit.h" + +/* ***************************************** */ +/* NOTE ABOUT THIS FILE: + * This file contains code for editing Grease Pencil data in the Action Editor + * as a 'keyframes', so that a user can adjust the timing of Grease Pencil drawings. + * Therefore, this file mostly contains functions for selecting Grease-Pencil frames. + */ +/* ***************************************** */ +/* Generics - Loopers */ + +/* Loops over the gp-frames for a gp-layer, and applies the given callback */ +short ED_masklayer_frames_looper(MaskLayer *masklay, Scene *scene, short (*masklay_shape_cb)(MaskLayerShape *, Scene *)) +{ + MaskLayerShape *masklay_shape; + + /* error checker */ + if (masklay == NULL) + return 0; + + /* do loop */ + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { + /* execute callback */ + if (masklay_shape_cb(masklay_shape, scene)) + return 1; + } + + /* nothing to return */ + return 0; +} + +/* ****************************************** */ +/* Data Conversion Tools */ + +/* make a listing all the gp-frames in a layer as cfraelems */ +void ED_masklayer_make_cfra_list(MaskLayer *masklay, ListBase *elems, short onlysel) +{ + MaskLayerShape *masklay_shape; + CfraElem *ce; + + /* error checking */ + if (ELEM(NULL, masklay, elems)) + return; + + /* loop through gp-frames, adding */ + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { + if ((onlysel == 0) || (masklay_shape->flag & MASK_SHAPE_SELECT)) { + ce = MEM_callocN(sizeof(CfraElem), "CfraElem"); + + ce->cfra = (float)masklay_shape->frame; + ce->sel = (masklay_shape->flag & MASK_SHAPE_SELECT) ? 1 : 0; + + BLI_addtail(elems, ce); + } + } +} + +/* ***************************************** */ +/* Selection Tools */ + +/* check if one of the frames in this layer is selected */ +short ED_masklayer_frame_select_check(MaskLayer *masklay) +{ + MaskLayerShape *masklay_shape; + + /* error checking */ + if (masklay == NULL) + return 0; + + /* stop at the first one found */ + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { + if (masklay_shape->flag & MASK_SHAPE_SELECT) + return 1; + } + + /* not found */ + return 0; +} + +/* helper function - select gp-frame based on SELECT_* mode */ +static void masklayshape_select(MaskLayerShape *masklay_shape, short select_mode) +{ + if (masklay_shape == NULL) + return; + + switch (select_mode) { + case SELECT_ADD: + masklay_shape->flag |= MASK_SHAPE_SELECT; + break; + case SELECT_SUBTRACT: + masklay_shape->flag &= ~MASK_SHAPE_SELECT; + break; + case SELECT_INVERT: + masklay_shape->flag ^= MASK_SHAPE_SELECT; + break; + } +} + +/* set all/none/invert select (like above, but with SELECT_* modes) */ +void ED_mask_select_frames(MaskLayer *masklay, short select_mode) +{ + MaskLayerShape *masklay_shape; + + /* error checking */ + if (masklay == NULL) + return; + + /* handle according to mode */ + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { + masklayshape_select(masklay_shape, select_mode); + } +} + +/* set all/none/invert select */ +void ED_masklayer_frame_select_set(MaskLayer *masklay, short mode) +{ + /* error checking */ + if (masklay == NULL) + return; + + /* now call the standard function */ + ED_mask_select_frames(masklay, mode); +} + +/* select the frame in this layer that occurs on this frame (there should only be one at most) */ +void ED_mask_select_frame(MaskLayer *masklay, int selx, short select_mode) +{ + MaskLayerShape *masklay_shape; + + if (masklay == NULL) + return; + + masklay_shape = BKE_mask_layer_shape_find_frame(masklay, selx); + + if (masklay_shape) { + masklayshape_select(masklay_shape, select_mode); + } +} + +/* select the frames in this layer that occur within the bounds specified */ +void ED_masklayer_frames_select_border(MaskLayer *masklay, float min, float max, short select_mode) +{ + MaskLayerShape *masklay_shape; + + if (masklay == NULL) + return; + + /* only select those frames which are in bounds */ + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { + if (IN_RANGE(masklay_shape->frame, min, max)) + masklayshape_select(masklay_shape, select_mode); + } +} + +/* ***************************************** */ +/* Frame Editing Tools */ + +/* Delete selected frames */ +void ED_masklayer_frames_delete(MaskLayer *masklay) +{ + MaskLayerShape *masklay_shape, *masklay_shape_next; + + /* error checking */ + if (masklay == NULL) + return; + + /* check for frames to delete */ + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape_next) { + masklay_shape_next = masklay_shape->next; + + if (masklay_shape->flag & MASK_SHAPE_SELECT) + BKE_mask_layer_shape_unlink(masklay, masklay_shape); + } +} + +/* Duplicate selected frames from given gp-layer */ +void ED_masklayer_frames_duplicate(MaskLayer *masklay) +{ + MaskLayerShape *masklay_shape, *gpfn; + + /* error checking */ + if (masklay == NULL) + return; + + /* duplicate selected frames */ + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = gpfn) { + gpfn = masklay_shape->next; + + /* duplicate this frame */ + if (masklay_shape->flag & MASK_SHAPE_SELECT) { + MaskLayerShape *mask_shape_dupe; + + /* duplicate frame, and deselect self */ + mask_shape_dupe = BKE_mask_layer_shape_duplicate(masklay_shape); + masklay_shape->flag &= ~MASK_SHAPE_SELECT; + + // XXX - how to handle duplicate frames? + BLI_insertlinkafter(&masklay->splines_shapes, masklay_shape, mask_shape_dupe); + } + } +} diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h new file mode 100644 index 00000000000..fc6089238a1 --- /dev/null +++ b/source/blender/editors/mask/mask_intern.h @@ -0,0 +1,113 @@ +/* + * ***** 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) 2011 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_intern.h + * \ingroup spclip + */ + +#ifndef __MASK_INTERN_H__ +#define __MASK_INTERN_H__ + +struct bContext; +struct wmEvent; +struct wmOperatorType; + +/* internal exports only */ + +/* mask_add.c */ +void MASK_OT_add_vertex(struct wmOperatorType *ot); +void MASK_OT_add_feather_vertex(struct wmOperatorType *ot); + +/* mask_ops.c */ +void MASK_OT_new(struct wmOperatorType *ot); +void MASK_OT_layer_new(struct wmOperatorType *ot); +void MASK_OT_layer_remove(struct wmOperatorType *ot); +void MASK_OT_cyclic_toggle(struct wmOperatorType *ot); + +void MASK_OT_slide_point(struct wmOperatorType *ot); + +void MASK_OT_delete(struct wmOperatorType *ot); + +void MASK_OT_hide_view_clear(struct wmOperatorType *ot); +void MASK_OT_hide_view_set(struct wmOperatorType *ot); +void MASK_OT_feather_weight_clear(struct wmOperatorType *ot); +void MASK_OT_switch_direction(struct wmOperatorType *ot); + +void MASK_OT_handle_type_set(struct wmOperatorType *ot); + +int ED_mask_feather_find_nearest( + struct bContext *C, struct Mask *mask, float normal_co[2], int threshold, + struct MaskLayer **masklay_r, struct MaskSpline **spline_r, struct MaskSplinePoint **point_r, + struct MaskSplinePointUW **uw_r, float *score); + +struct MaskSplinePoint *ED_mask_point_find_nearest( + struct bContext *C, struct Mask *mask, float normal_co[2], int threshold, + struct MaskLayer **masklay_r, struct MaskSpline **spline_r, int *is_handle_r, + float *score); + +/* mask_relationships.c */ +void MASK_OT_parent_set(struct wmOperatorType *ot); +void MASK_OT_parent_clear(struct wmOperatorType *ot); + +/* mask_select.c */ +void MASK_OT_select(struct wmOperatorType *ot); +void MASK_OT_select_all(struct wmOperatorType *ot); + +void MASK_OT_select_border(struct wmOperatorType *ot); +void MASK_OT_select_lasso(struct wmOperatorType *ot); +void MASK_OT_select_circle(struct wmOperatorType *ot); +void MASK_OT_select_linked_pick(struct wmOperatorType *ot); +void MASK_OT_select_linked(struct wmOperatorType *ot); + +int ED_mask_spline_select_check(struct MaskSpline *spline); +int ED_mask_layer_select_check(struct MaskLayer *masklay); +int ED_mask_select_check(struct Mask *mask); + +void ED_mask_spline_select_set(struct MaskSpline *spline, const short do_select); +void ED_mask_layer_select_set(struct MaskLayer *masklay, const short do_select); +void ED_mask_select_toggle_all(struct Mask *mask, int action); +void ED_mask_select_flush_all(struct Mask *mask); + +/* mask_editor.c */ +int ED_maskedit_poll(struct bContext *C); +int ED_maskedit_mask_poll(struct bContext *C); + +void ED_mask_size(struct bContext *C, int *width, int *height); +void ED_mask_aspect(struct bContext *C, float *aspx, float *aspy); + +void ED_mask_pixelspace_factor(struct bContext *C, float *scalex, float *scaley); +void ED_mask_mouse_pos(struct bContext *C, struct wmEvent *event, float co[2]); + +void ED_mask_point_pos(struct bContext *C, float x, float y, float *xr, float *yr); +void ED_mask_point_pos__reverse(struct bContext *C, float x, float y, float *xr, float *yr); + +/* mask_shapekey.c */ +void MASK_OT_shape_key_insert(struct wmOperatorType *ot); +void MASK_OT_shape_key_clear(struct wmOperatorType *ot); +void MASK_OT_shape_key_feather_reset(struct wmOperatorType *ot); + +#endif /* __MASK_INTERN_H__ */ diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c new file mode 100644 index 00000000000..67fd57ed50b --- /dev/null +++ b/source/blender/editors/mask/mask_ops.c @@ -0,0 +1,1263 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_ops.c + * \ingroup edmask + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_mask.h" + +#include "DNA_scene_types.h" +#include "DNA_mask_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_mask.h" +#include "ED_clip.h" +#include "ED_keyframing.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "mask_intern.h" /* own include */ + +/******************** utility functions *********************/ + +MaskSplinePoint *ED_mask_point_find_nearest(bContext *C, Mask *mask, float normal_co[2], int threshold, + MaskLayer **masklay_r, MaskSpline **spline_r, int *is_handle_r, + float *score) +{ + MaskLayer *masklay; + MaskLayer *point_masklay = NULL; + MaskSpline *point_spline = NULL; + MaskSplinePoint *point = NULL; + float co[2], aspx, aspy; + float len = FLT_MAX, scalex, scaley; + int is_handle = FALSE, width, height; + + ED_mask_size(C, &width, &height); + ED_mask_aspect(C, &aspx, &aspy); + ED_mask_pixelspace_factor(C, &scalex, &scaley); + + co[0] = normal_co[0] * scalex; + co[1] = normal_co[1] * scaley; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *cur_point = &spline->points[i]; + MaskSplinePoint *cur_point_deform = &points_array[i]; + float cur_len, vec[2], handle[2]; + + vec[0] = cur_point_deform->bezt.vec[1][0] * scalex; + vec[1] = cur_point_deform->bezt.vec[1][1] * scaley; + + if (BKE_mask_point_has_handle(cur_point)) { + BKE_mask_point_handle(cur_point_deform, handle); + handle[0] *= scalex; + handle[1] *= scaley; + + cur_len = len_v2v2(co, handle); + + if (cur_len < len) { + point_masklay = masklay; + point_spline = spline; + point = cur_point; + len = cur_len; + is_handle = TRUE; + } + } + + cur_len = len_v2v2(co, vec); + + if (cur_len < len) { + point_spline = spline; + point_masklay = masklay; + point = cur_point; + len = cur_len; + is_handle = FALSE; + } + } + } + } + + if (len < threshold) { + if (masklay_r) + *masklay_r = point_masklay; + + if (spline_r) + *spline_r = point_spline; + + if (is_handle_r) + *is_handle_r = is_handle; + + if (score) + *score = len; + + return point; + } + + if (masklay_r) + *masklay_r = NULL; + + if (spline_r) + *spline_r = NULL; + + if (is_handle_r) + *is_handle_r = FALSE; + + return NULL; +} + +int ED_mask_feather_find_nearest(bContext *C, Mask *mask, float normal_co[2], int threshold, + MaskLayer **masklay_r, MaskSpline **spline_r, MaskSplinePoint **point_r, + MaskSplinePointUW **uw_r, float *score) +{ + MaskLayer *masklay, *point_masklay = NULL; + MaskSpline *point_spline = NULL; + MaskSplinePoint *point = NULL; + MaskSplinePointUW *uw = NULL; + float len = FLT_MAX, co[2]; + float scalex, scaley, aspx, aspy; + int width, height; + + ED_mask_size(C, &width, &height); + ED_mask_aspect(C, &aspx, &aspy); + ED_mask_pixelspace_factor(C, &scalex, &scaley); + + co[0] = normal_co[0] * scalex; + co[1] = normal_co[1] * scaley; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + for (spline = masklay->splines.first; spline; spline = spline->next) { + //MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + + int i, tot_feather_point; + float (*feather_points)[2], (*fp)[2]; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point); + + for (i = 0; i < spline->tot_point; i++) { + int j; + MaskSplinePoint *cur_point = &spline->points[i]; + + for (j = 0; j < cur_point->tot_uw + 1; j++) { + float cur_len, vec[2]; + + vec[0] = (*fp)[0] * scalex; + vec[1] = (*fp)[1] * scaley; + + cur_len = len_v2v2(vec, co); + + if (point == NULL || cur_len < len) { + if (j == 0) + uw = NULL; + else + uw = &cur_point->uw[j - 1]; + + point_masklay = masklay; + point_spline = spline; + point = cur_point; + len = cur_len; + } + + fp++; + } + } + + MEM_freeN(feather_points); + } + } + + if (len < threshold) { + if (masklay_r) + *masklay_r = point_masklay; + + if (spline_r) + *spline_r = point_spline; + + if (point_r) + *point_r = point; + + if (uw_r) + *uw_r = uw; + + if (score) + *score = len; + + return TRUE; + } + + if (masklay_r) + *masklay_r = NULL; + + if (spline_r) + *spline_r = NULL; + + if (point_r) + *point_r = NULL; + + return FALSE; +} + + +/******************** create new mask *********************/ + +static int mask_new_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + Mask *mask; + char name[MAX_ID_NAME - 2]; + + RNA_string_get(op->ptr, "name", name); + + mask = BKE_mask_new(name); + + if (sc) + ED_space_clip_set_mask(C, sc, mask); + + return OPERATOR_FINISHED; +} + +void MASK_OT_new(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "New Mask"; + ot->description = "Create new mask"; + ot->idname = "MASK_OT_new"; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* api callbacks */ + ot->exec = mask_new_exec; + ot->poll = ED_operator_mask; + + /* properties */ + RNA_def_string(ot->srna, "name", "", MAX_ID_NAME - 2, "Name", "Name of new mask"); +} + +/******************** create new masklay *********************/ + +static int masklay_new_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + char name[MAX_ID_NAME - 2]; + + RNA_string_get(op->ptr, "name", name); + + BKE_mask_layer_new(mask, name); + mask->masklay_act = mask->masklay_tot - 1; + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + return OPERATOR_FINISHED; +} + +void MASK_OT_layer_new(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Mask Layer"; + ot->description = "Add new mask layer for masking"; + ot->idname = "MASK_OT_layer_new"; + + /* api callbacks */ + ot->exec = masklay_new_exec; + ot->poll = ED_maskedit_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_string(ot->srna, "name", "", MAX_ID_NAME - 2, "Name", "Name of new mask layer"); +} + +/******************** remove mask layer *********************/ + +static int masklay_remove_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay = BKE_mask_layer_active(mask); + + if (masklay) { + BKE_mask_layer_remove(mask, masklay); + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + } + + return OPERATOR_FINISHED; +} + +void MASK_OT_layer_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Mask Layer"; + ot->description = "Remove mask layer"; + ot->idname = "MASK_OT_layer_remove"; + + /* api callbacks */ + ot->exec = masklay_remove_exec; + ot->poll = ED_maskedit_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/******************** slide *********************/ + +enum { + SLIDE_ACTION_NONE = 0, + SLIDE_ACTION_POINT = 1, + SLIDE_ACTION_HANDLE = 2, + SLIDE_ACTION_FEATHER = 3 +}; + +typedef struct SlidePointData { + int action; + + float co[2]; + float vec[3][3]; + + Mask *mask; + MaskLayer *masklay; + MaskSpline *spline, *orig_spline; + MaskSplinePoint *point; + MaskSplinePointUW *uw; + float handle[2], no[2], feather[2]; + int width, height; + float weight; + + short curvature_only, accurate; + short initial_feather, overall_feather; +} SlidePointData; + +static int slide_point_check_initial_feather(MaskSpline *spline) +{ + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (point->bezt.weight != 0.0f) + return FALSE; + + /* comment for now. if all bezt weights are zero - this is as good-as initial */ +#if 0 + int j; + for (j = 0; j < point->tot_uw; j++) { + if (point->uw[j].w != 0.0f) + return FALSE; + } +#endif + } + + return TRUE; +} + +static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) +{ + Mask *mask = CTX_data_edit_mask(C); + SlidePointData *customdata = NULL; + MaskLayer *masklay, *cv_masklay, *feather_masklay; + MaskSpline *spline, *cv_spline, *feather_spline; + MaskSplinePoint *point, *cv_point, *feather_point; + MaskSplinePointUW *uw = NULL; + int is_handle = FALSE, width, height, action = SLIDE_ACTION_NONE; + int slide_feather = RNA_boolean_get(op->ptr, "slide_feather"); + float co[2], cv_score, feather_score; + const float threshold = 19; + + ED_mask_mouse_pos(C, event, co); + ED_mask_size(C, &width, &height); + + cv_point = ED_mask_point_find_nearest(C, mask, co, threshold, &cv_masklay, &cv_spline, &is_handle, &cv_score); + + if (ED_mask_feather_find_nearest(C, mask, co, threshold, &feather_masklay, &feather_spline, &feather_point, &uw, &feather_score)) { + if (slide_feather || !cv_point || feather_score < cv_score) { + action = SLIDE_ACTION_FEATHER; + + masklay = feather_masklay; + spline = feather_spline; + point = feather_point; + } + } + + if (cv_point && action == SLIDE_ACTION_NONE) { + if (is_handle) + action = SLIDE_ACTION_HANDLE; + else + action = SLIDE_ACTION_POINT; + + masklay = cv_masklay; + spline = cv_spline; + point = cv_point; + } + + if (action != SLIDE_ACTION_NONE) { + customdata = MEM_callocN(sizeof(SlidePointData), "mask slide point data"); + + customdata->mask = mask; + customdata->masklay = masklay; + customdata->spline = spline; + customdata->point = point; + customdata->width = width; + customdata->height = height; + customdata->action = action; + customdata->uw = uw; + + if (uw) { + float co[2]; + float weight_scalar = BKE_mask_point_weight_scalar(spline, point, uw->u); + + customdata->weight = uw->w; + BKE_mask_point_segment_co(spline, point, uw->u, co); + BKE_mask_point_normal(spline, point, uw->u, customdata->no); + + madd_v2_v2v2fl(customdata->feather, co, customdata->no, uw->w * weight_scalar); + } + else { + BezTriple *bezt = &point->bezt; + + customdata->weight = bezt->weight; + BKE_mask_point_normal(spline, point, 0.0f, customdata->no); + + madd_v2_v2v2fl(customdata->feather, bezt->vec[1], customdata->no, bezt->weight); + } + + if (customdata->action == SLIDE_ACTION_FEATHER) + customdata->initial_feather = slide_point_check_initial_feather(spline); + + copy_m3_m3(customdata->vec, point->bezt.vec); + if (BKE_mask_point_has_handle(point)) + BKE_mask_point_handle(point, customdata->handle); + ED_mask_mouse_pos(C, event, customdata->co); + } + + return customdata; +} + +static int slide_point_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + SlidePointData *slidedata = slide_point_customdata(C, op, event); + + if (slidedata) { + Mask *mask = CTX_data_edit_mask(C); + + op->customdata = slidedata; + + WM_event_add_modal_handler(C, op); + + if (slidedata->uw) { + if ((slidedata->uw->flag & SELECT) == 0) { + ED_mask_select_toggle_all(mask, SEL_DESELECT); + + slidedata->uw->flag |= SELECT; + + ED_mask_select_flush_all(mask); + } + } + else if (!MASKPOINT_ISSEL_ANY(slidedata->point)) { + ED_mask_select_toggle_all(mask, SEL_DESELECT); + + BKE_mask_point_select_set(slidedata->point, TRUE); + + ED_mask_select_flush_all(mask); + } + + slidedata->masklay->act_spline = slidedata->spline; + slidedata->masklay->act_point = slidedata->point; + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_RUNNING_MODAL; + } + + return OPERATOR_PASS_THROUGH; +} + +static void slide_point_delta_all_feather(SlidePointData *data, float delta) +{ + int i; + + for (i = 0; i < data->spline->tot_point; i++) { + MaskSplinePoint *point = &data->spline->points[i]; + MaskSplinePoint *orig_point = &data->orig_spline->points[i]; + + point->bezt.weight = orig_point->bezt.weight + delta; + if (point->bezt.weight < 0.0f) + point->bezt.weight = 0.0f; + + /* not needed anymore */ +#if 0 + int j; + for (j = 0; j < point->tot_uw; j++) { + point->uw[j].w = orig_point->uw[j].w + delta; + if (point->uw[j].w < 0.0f) + point->uw[j].w = 0.0f; + } +#endif + } +} + +static void slide_point_restore_spline(SlidePointData *data) +{ + int i; + + for (i = 0; i < data->spline->tot_point; i++) { + MaskSplinePoint *point = &data->spline->points[i]; + MaskSplinePoint *orig_point = &data->orig_spline->points[i]; + int j; + + point->bezt = orig_point->bezt; + + for (j = 0; j < point->tot_uw; j++) + point->uw[j] = orig_point->uw[j]; + } +} + +static void cancel_slide_point(SlidePointData *data) +{ + /* cancel sliding */ + + if (data->orig_spline) { + slide_point_restore_spline(data); + } + else { + if (data->action == SLIDE_ACTION_FEATHER) { + if (data->uw) + data->uw->w = data->weight; + else + data->point->bezt.weight = data->weight; + } + else { + copy_m3_m3(data->point->bezt.vec, data->vec); + } + } +} + +static void free_slide_point_data(SlidePointData *data) +{ + if (data->orig_spline) + BKE_mask_spline_free(data->orig_spline); + + MEM_freeN(data); +} + +static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + SlidePointData *data = (SlidePointData *)op->customdata; + BezTriple *bezt = &data->point->bezt; + float co[2], dco[2]; + + switch (event->type) { + case LEFTCTRLKEY: + case RIGHTCTRLKEY: + case LEFTSHIFTKEY: + case RIGHTSHIFTKEY: + if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) { + if (data->action == SLIDE_ACTION_FEATHER) + data->overall_feather = event->val == KM_PRESS; + else + data->curvature_only = event->val == KM_PRESS; + } + + if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) + data->accurate = event->val == KM_PRESS; + + /* no break! update CV position */ + + case MOUSEMOVE: + ED_mask_mouse_pos(C, event, co); + sub_v2_v2v2(dco, co, data->co); + + if (data->action == SLIDE_ACTION_HANDLE) { + float delta[2], offco[2]; + + sub_v2_v2v2(delta, data->handle, data->co); + + sub_v2_v2v2(offco, co, data->co); + if (data->accurate) + mul_v2_fl(offco, 0.2f); + add_v2_v2(offco, data->co); + add_v2_v2(offco, delta); + + BKE_mask_point_set_handle(data->point, offco, data->curvature_only, data->handle, data->vec); + } + else if (data->action == SLIDE_ACTION_POINT) { + float delta[2]; + + copy_v2_v2(delta, dco); + if (data->accurate) + mul_v2_fl(delta, 0.2f); + + add_v2_v2v2(bezt->vec[0], data->vec[0], delta); + add_v2_v2v2(bezt->vec[1], data->vec[1], delta); + add_v2_v2v2(bezt->vec[2], data->vec[2], delta); + } + else if (data->action == SLIDE_ACTION_FEATHER) { + float vec[2], no[2], p[2], c[2], w, offco[2]; + float *weight = NULL; + float weight_scalar = 1.0f; + int overall_feather = data->overall_feather || data->initial_feather; + + add_v2_v2v2(offco, data->feather, dco); + + if (data->uw) { + /* project on both sides and find the closest one, + * prevents flickering when projecting onto both sides can happen */ + const float u_pos = BKE_mask_spline_project_co(data->spline, data->point, + data->uw->u, offco, MASK_PROJ_NEG); + const float u_neg = BKE_mask_spline_project_co(data->spline, data->point, + data->uw->u, offco, MASK_PROJ_POS); + float dist_pos = FLT_MAX; + float dist_neg = FLT_MAX; + float co_pos[2]; + float co_neg[2]; + float u; + + if (u_pos > 0.0f && u_pos < 1.0f) { + BKE_mask_point_segment_co(data->spline, data->point, u_pos, co_pos); + dist_pos = len_squared_v2v2(offco, co_pos); + } + + if (u_neg > 0.0f && u_neg < 1.0f) { + BKE_mask_point_segment_co(data->spline, data->point, u_neg, co_neg); + dist_neg = len_squared_v2v2(offco, co_neg); + } + + u = dist_pos < dist_neg ? u_pos : u_neg; + + if (u > 0.0f && u < 1.0f) { + data->uw->u = u; + + data->uw = BKE_mask_point_sort_uw(data->point, data->uw); + weight = &data->uw->w; + weight_scalar = BKE_mask_point_weight_scalar(data->spline, data->point, u); + if (weight_scalar != 0.0f) { + weight_scalar = 1.0f / weight_scalar; + } + + BKE_mask_point_normal(data->spline, data->point, data->uw->u, no); + BKE_mask_point_segment_co(data->spline, data->point, data->uw->u, p); + } + } + else { + weight = &bezt->weight; + /* weight_scalar = 1.0f; keep as is */ + copy_v2_v2(no, data->no); + copy_v2_v2(p, bezt->vec[1]); + } + + if (weight) { + sub_v2_v2v2(c, offco, p); + project_v2_v2v2(vec, c, no); + + w = len_v2(vec); + + if (overall_feather) { + float delta; + + if (dot_v2v2(no, vec) <= 0.0f) + w = -w; + + delta = w - data->weight; + + if (data->orig_spline == NULL) { + /* restore weight for currently sliding point, so orig_spline would be created + * with original weights used + */ + *weight = data->weight * weight_scalar; + + data->orig_spline = BKE_mask_spline_copy(data->spline); + } + + slide_point_delta_all_feather(data, delta); + } + else { + if (dot_v2v2(no, vec) <= 0.0f) + w = 0.0f; + + if (data->orig_spline) { + /* restore possible overall feather changes */ + slide_point_restore_spline(data); + + BKE_mask_spline_free(data->orig_spline); + data->orig_spline = NULL; + } + + if (weight_scalar != 0.0f) { + *weight = w * weight_scalar; + } + } + } + } + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask); + DAG_id_tag_update(&data->mask->id, 0); + + break; + + case LEFTMOUSE: + if (event->val == KM_RELEASE) { + Scene *scene = CTX_data_scene(C); + + /* dont key sliding feather uw's */ + if ((data->action == SLIDE_ACTION_FEATHER && data->uw) == FALSE) { + if (IS_AUTOKEY_ON(scene)) { + ED_mask_layer_shape_auto_key(data->masklay, CFRA); + } + } + + free_slide_point_data(op->customdata); + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask); + DAG_id_tag_update(&data->mask->id, 0); + + return OPERATOR_FINISHED; + } + + break; + + case ESCKEY: + cancel_slide_point(op->customdata); + + free_slide_point_data(op->customdata); + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask); + DAG_id_tag_update(&data->mask->id, 0); + + return OPERATOR_CANCELLED; + } + + return OPERATOR_RUNNING_MODAL; +} + +void MASK_OT_slide_point(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Slide Point"; + ot->description = "Slide control points"; + ot->idname = "MASK_OT_slide_point"; + + /* api callbacks */ + ot->invoke = slide_point_invoke; + ot->modal = slide_point_modal; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "slide_feather", 0, "Slide Feather", "First try to slide feather instead of vertex"); +} + +/******************** toggle cyclic *********************/ + +static int cyclic_toggle_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + if (ED_mask_spline_select_check(spline)) { + spline->flag ^= MASK_SPLINE_CYCLIC; + } + } + } + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + return OPERATOR_FINISHED; +} + +void MASK_OT_cyclic_toggle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Toggle Cyclic"; + ot->description = "Toggle cyclic for selected splines"; + ot->idname = "MASK_OT_cyclic_toggle"; + + /* api callbacks */ + ot->exec = cyclic_toggle_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/******************** delete *********************/ + +static void delete_feather_points(MaskSplinePoint *point) +{ + int i, count = 0; + + if (!point->tot_uw) + return; + + for (i = 0; i < point->tot_uw; i++) { + if ((point->uw[i].flag & SELECT) == 0) + count++; + } + + if (count == 0) { + MEM_freeN(point->uw); + point->uw = NULL; + point->tot_uw = 0; + } + else { + MaskSplinePointUW *new_uw; + int j = 0; + + new_uw = MEM_callocN(count * sizeof(MaskSplinePointUW), "new mask uw points"); + + for (i = 0; i < point->tot_uw; i++) { + if ((point->uw[i].flag & SELECT) == 0) { + new_uw[j++] = point->uw[i]; + } + } + + MEM_freeN(point->uw); + + point->uw = new_uw; + point->tot_uw = count; + } +} + +static int delete_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + int mask_layer_shape_ofs = 0; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + spline = masklay->splines.first; + + while (spline) { + const int tot_point_orig = spline->tot_point; + int i, count = 0; + MaskSpline *next_spline = spline->next; + + /* count unselected points */ + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (!MASKPOINT_ISSEL_ANY(point)) + count++; + } + + if (count == 0) { + + /* delete the whole spline */ + BLI_remlink(&masklay->splines, spline); + BKE_mask_spline_free(spline); + + if (spline == masklay->act_spline) { + masklay->act_spline = NULL; + masklay->act_point = NULL; + } + + BKE_mask_layer_shape_changed_remove(masklay, mask_layer_shape_ofs, tot_point_orig); + } + else { + MaskSplinePoint *new_points; + int j; + + new_points = MEM_callocN(count * sizeof(MaskSplinePoint), "deleteMaskPoints"); + + for (i = 0, j = 0; i < tot_point_orig; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (!MASKPOINT_ISSEL_ANY(point)) { + if (point == masklay->act_point) + masklay->act_point = &new_points[j]; + + delete_feather_points(point); + + new_points[j] = *point; + j++; + } + else { + if (point == masklay->act_point) + masklay->act_point = NULL; + + BKE_mask_point_free(point); + spline->tot_point--; + + BKE_mask_layer_shape_changed_remove(masklay, mask_layer_shape_ofs + j, 1); + } + } + + mask_layer_shape_ofs += spline->tot_point; + + MEM_freeN(spline->points); + spline->points = new_points; + + ED_mask_select_flush_all(mask); + } + + spline = next_spline; + } + } + + /* TODO: only update edited splines */ + BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + return OPERATOR_FINISHED; +} + +void MASK_OT_delete(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Delete"; + ot->description = "Delete selected control points or splines"; + ot->idname = "MASK_OT_delete"; + + /* api callbacks */ + ot->invoke = WM_operator_confirm; + ot->exec = delete_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/* *** switch direction *** */ +static int mask_switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + + int change = FALSE; + + /* do actual selection */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + if (ED_mask_spline_select_check(spline)) { + BKE_mask_spline_direction_switch(masklay, spline); + change = TRUE; + } + } + } + + if (change) { + /* TODO: only update this spline */ + BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void MASK_OT_switch_direction(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Switch Direction"; + ot->description = "Switch direction of selected splines"; + ot->idname = "MASK_OT_switch_direction"; + + /* api callbacks */ + ot->exec = mask_switch_direction_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + + +/******************** set handle type *********************/ + +static int set_handle_type_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int handle_type = RNA_enum_get(op->ptr, "type"); + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + int i; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(point)) { + BezTriple *bezt = &point->bezt; + + bezt->h1 = bezt->h2 = handle_type; + } + } + } + } + + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; +} + +void MASK_OT_handle_type_set(wmOperatorType *ot) +{ + static EnumPropertyItem editcurve_handle_type_items[] = { + {HD_AUTO, "AUTO", 0, "Auto", ""}, + {HD_VECT, "VECTOR", 0, "Vector", ""}, + {HD_ALIGN, "ALIGNED", 0, "Aligned", ""}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name = "Set Handle Type"; + ot->description = "Set type of handles for selected control points"; + ot->idname = "MASK_OT_handle_type_set"; + + /* api callbacks */ + ot->invoke = WM_menu_invoke; + ot->exec = set_handle_type_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "type", editcurve_handle_type_items, 1, "Type", "Spline type"); +} + + +/* ********* clear/set restrict view *********/ +static int mask_hide_view_clear_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int changed = FALSE; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + + if (masklay->restrictflag & OB_RESTRICT_VIEW) { + ED_mask_layer_select_set(masklay, TRUE); + masklay->restrictflag &= ~OB_RESTRICT_VIEW; + changed = 1; + } + } + + if (changed) { + WM_event_add_notifier(C, NC_MASK | ND_DRAW, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void MASK_OT_hide_view_clear(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name = "Clear Restrict View"; + ot->description = "Reveal the layer by setting the hide flag"; + ot->idname = "MASK_OT_hide_view_clear"; + + /* api callbacks */ + ot->exec = mask_hide_view_clear_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int mask_hide_view_set_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + const int unselected = RNA_boolean_get(op->ptr, "unselected"); + int changed = FALSE; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + + if (masklay->restrictflag & MASK_RESTRICT_SELECT) { + continue; + } + + if (!unselected) { + if (ED_mask_layer_select_check(masklay)) { + ED_mask_layer_select_set(masklay, FALSE); + + masklay->restrictflag |= OB_RESTRICT_VIEW; + changed = 1; + if (masklay == BKE_mask_layer_active(mask)) { + BKE_mask_layer_active_set(mask, NULL); + } + } + } + else { + if (!ED_mask_layer_select_check(masklay)) { + masklay->restrictflag |= OB_RESTRICT_VIEW; + changed = 1; + if (masklay == BKE_mask_layer_active(mask)) { + BKE_mask_layer_active_set(mask, NULL); + } + } + } + } + + if (changed) { + WM_event_add_notifier(C, NC_MASK | ND_DRAW, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void MASK_OT_hide_view_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Set Restrict View"; + ot->description = "Hide the layer by setting the hide flag"; + ot->idname = "MASK_OT_hide_view_set"; + + /* api callbacks */ + ot->exec = mask_hide_view_set_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected layers"); +} + + +static int mask_feather_weight_clear_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int changed = FALSE; + int i; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_SELECT | MASK_RESTRICT_VIEW)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(point)) { + BezTriple *bezt = &point->bezt; + bezt->weight = 0.0f; + changed = TRUE; + } + } + } + } + + if (changed) { + /* TODO: only update edited splines */ + BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); + + WM_event_add_notifier(C, NC_MASK | ND_DRAW, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void MASK_OT_feather_weight_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Feather Weight"; + ot->description = "Reset the feather weight to zero"; + ot->idname = "MASK_OT_feather_weight_clear"; + + /* api callbacks */ + ot->exec = mask_feather_weight_clear_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c new file mode 100644 index 00000000000..77fe2a71225 --- /dev/null +++ b/source/blender/editors/mask/mask_relationships.c @@ -0,0 +1,172 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_relationships.c + * \ingroup edmask + */ + + +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_mask.h" +#include "BKE_tracking.h" + +#include "DNA_mask_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_mask.h" /* own include */ + +#include "mask_intern.h" /* own include */ + +static int mask_parent_clear_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + int i; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(point)) { + point->parent.id = NULL; + } + } + } + } + + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; +} + +void MASK_OT_parent_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Parent"; + ot->description = "Clear the mask's parenting"; + ot->idname = "MASK_OT_parent_clear"; + + /* api callbacks */ + ot->exec = mask_parent_clear_exec; + + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + + /* parent info */ + SpaceClip *sc; + MovieClip *clip; + MovieTrackingTrack *track; + MovieTrackingMarker *marker; + MovieTrackingObject *tracking; + /* done */ + + float marker_pos_ofs[2]; + float parmask_pos[2]; + + if ((NULL == (sc = CTX_wm_space_clip(C))) || + (NULL == (clip = sc->clip)) || + (NULL == (track = clip->tracking.act_track)) || + (NULL == (marker = BKE_tracking_get_marker(track, sc->user.framenr))) || + (NULL == (tracking = BKE_tracking_active_object(&clip->tracking)))) + { + return OPERATOR_CANCELLED; + } + + add_v2_v2v2(marker_pos_ofs, marker->pos, track->offset); + + BKE_mask_coord_from_movieclip(clip, &sc->user, parmask_pos, marker_pos_ofs); + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + int i; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(point)) { + point->parent.id_type = ID_MC; + point->parent.id = &clip->id; + strcpy(point->parent.parent, tracking->name); + strcpy(point->parent.sub_parent, track->name); + + copy_v2_v2(point->parent.parent_orig, parmask_pos); + } + } + } + } + + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; +} + +/** based on #OBJECT_OT_parent_set */ +void MASK_OT_parent_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Make Parent"; + ot->description = "Set the mask's parenting"; + ot->idname = "MASK_OT_parent_set"; + + /* api callbacks */ + //ot->invoke = mask_parent_set_invoke; + ot->exec = mask_parent_set_exec; + + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c new file mode 100644 index 00000000000..55e09529320 --- /dev/null +++ b/source/blender/editors/mask/mask_select.c @@ -0,0 +1,766 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_select.c + * \ingroup edmask + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_rect.h" +#include "BLI_lasso.h" + +#include "BKE_context.h" +#include "BKE_mask.h" + +#include "DNA_mask_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_clip.h" +#include "ED_mask.h" /* own include */ + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "mask_intern.h" /* own include */ + +/* 'check' select */ +int ED_mask_spline_select_check(MaskSpline *spline) +{ + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(point)) + return TRUE; + } + + return FALSE; +} + +int ED_mask_layer_select_check(MaskLayer *masklay) +{ + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + return FALSE; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + if (ED_mask_spline_select_check(spline)) { + return TRUE; + } + } + + return FALSE; +} + +int ED_mask_select_check(Mask *mask) +{ + MaskLayer *masklay; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + if (ED_mask_layer_select_check(masklay)) { + return TRUE; + } + } + + return FALSE; +} + +/* 'sel' select */ +void ED_mask_spline_select_set(MaskSpline *spline, const short do_select) +{ + int i; + + if (do_select) + spline->flag |= SELECT; + else + spline->flag &= ~SELECT; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + BKE_mask_point_select_set(point, do_select); + } +} + +void ED_mask_layer_select_set(MaskLayer *masklay, const short do_select) +{ + MaskSpline *spline; + + if (masklay->restrictflag & MASK_RESTRICT_SELECT) { + if (do_select == TRUE) { + return; + } + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + ED_mask_spline_select_set(spline, do_select); + } +} + +void ED_mask_select_toggle_all(Mask *mask, int action) +{ + MaskLayer *masklay; + + if (action == SEL_TOGGLE) { + if (ED_mask_select_check(mask)) + action = SEL_DESELECT; + else + action = SEL_SELECT; + } + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + + if (masklay->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + + ED_mask_layer_select_set(masklay, (action == SEL_SELECT) ? TRUE : FALSE); + } +} + +void ED_mask_select_flush_all(Mask *mask) +{ + MaskLayer *masklay; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + + spline->flag &= ~SELECT; + + /* intentionally _dont_ do this in the masklay loop + * so we clear flags on all splines */ + if (masklay->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *cur_point = &spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(cur_point)) { + spline->flag |= SELECT; + } + else { + int j; + + for (j = 0; j < cur_point->tot_uw; j++) { + if (cur_point->uw[j].flag & SELECT) { + spline->flag |= SELECT; + break; + } + } + } + } + } + } +} + +/******************** toggle selection *********************/ + +static int select_all_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + int action = RNA_enum_get(op->ptr, "action"); + + ED_mask_select_toggle_all(mask, action); + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; +} + +void MASK_OT_select_all(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "(De)select All"; + ot->description = "Change selection of all curve points"; + ot->idname = "MASK_OT_select_all"; + + /* api callbacks */ + ot->exec = select_all_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_select_all(ot); +} + +/******************** select *********************/ + +static int select_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + MaskSpline *spline; + MaskSplinePoint *point = NULL; + float co[2]; + short extend = RNA_boolean_get(op->ptr, "extend"); + short deselect = RNA_boolean_get(op->ptr, "deselect"); + short toggle = RNA_boolean_get(op->ptr, "toggle"); + + int is_handle = 0; + const float threshold = 19; + + RNA_float_get_array(op->ptr, "location", co); + + point = ED_mask_point_find_nearest(C, mask, co, threshold, &masklay, &spline, &is_handle, NULL); + + if (extend == 0 && deselect == 0 && toggle == 0) + ED_mask_select_toggle_all(mask, SEL_DESELECT); + + if (point) { + + if (is_handle) { + if (extend) { + masklay->act_spline = spline; + masklay->act_point = point; + + BKE_mask_point_select_set_handle(point, TRUE); + } + else if (deselect) { + BKE_mask_point_select_set_handle(point, FALSE); + } + else { + masklay->act_spline = spline; + masklay->act_point = point; + + if (!MASKPOINT_ISSEL_HANDLE(point)) { + BKE_mask_point_select_set_handle(point, TRUE); + } + else if (toggle) { + BKE_mask_point_select_set_handle(point, FALSE); + } + } + } + else { + if (extend) { + masklay->act_spline = spline; + masklay->act_point = point; + + BKE_mask_point_select_set(point, TRUE); + } + else if (deselect) { + BKE_mask_point_select_set(point, FALSE); + } + else { + masklay->act_spline = spline; + masklay->act_point = point; + + if (!MASKPOINT_ISSEL_ANY(point)) { + BKE_mask_point_select_set(point, TRUE); + } + else if (toggle) { + BKE_mask_point_select_set(point, FALSE); + } + } + } + + masklay->act_spline = spline; + masklay->act_point = point; + + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + else { + MaskSplinePointUW *uw; + + if (ED_mask_feather_find_nearest(C, mask, co, threshold, &masklay, &spline, &point, &uw, NULL)) { + + if (extend) { + masklay->act_spline = spline; + masklay->act_point = point; + + if (uw) uw->flag |= SELECT; + } + else if (deselect) { + if (uw) uw->flag &= ~SELECT; + } + else { + masklay->act_spline = spline; + masklay->act_point = point; + + if (uw) { + if (!(uw->flag & SELECT)) { + uw->flag |= SELECT; + } + else if (toggle) { + uw->flag &= ~SELECT; + } + } + } + + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + } + + return OPERATOR_PASS_THROUGH; +} + +static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + float co[2]; + + ED_mask_mouse_pos(C, event, co); + + RNA_float_set_array(op->ptr, "location", co); + + return select_exec(C, op); +} + +void MASK_OT_select(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select"; + ot->description = "Select spline points"; + ot->idname = "MASK_OT_select"; + + /* api callbacks */ + ot->exec = select_exec; + ot->invoke = select_invoke; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_mouse_select(ot); + + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, + "Location", "Location of vertex in normalized space", -1.0f, 1.0f); +} + + + +/********************** border select operator *********************/ + +static int border_select_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int i; + + rcti rect; + rctf rectf; + int change = FALSE, mode, extend; + + /* get rectangle from operator */ + rect.xmin = RNA_int_get(op->ptr, "xmin"); + rect.ymin = RNA_int_get(op->ptr, "ymin"); + rect.xmax = RNA_int_get(op->ptr, "xmax"); + rect.ymax = RNA_int_get(op->ptr, "ymax"); + + ED_mask_point_pos(C, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin); + ED_mask_point_pos(C, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax); + + mode = RNA_int_get(op->ptr, "gesture_mode"); + extend = RNA_boolean_get(op->ptr, "extend"); + + /* do actual selection */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *point_deform = &points_array[i]; + + /* TODO: handles? */ + /* TODO: uw? */ + + if (BLI_in_rctf(&rectf, point_deform->bezt.vec[1][0], point_deform->bezt.vec[1][1])) { + BKE_mask_point_select_set(point, mode == GESTURE_MODAL_SELECT); + BKE_mask_point_select_set_handle(point, mode == GESTURE_MODAL_SELECT); + } + else if (!extend) { + BKE_mask_point_select_set(point, FALSE); + BKE_mask_point_select_set_handle(point, FALSE); + } + + change = TRUE; + } + } + } + + if (change) { + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void MASK_OT_select_border(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Border Select"; + ot->description = "Select markers using border selection"; + ot->idname = "MASK_OT_select_border"; + + /* api callbacks */ + ot->invoke = WM_border_select_invoke; + ot->exec = border_select_exec; + ot->modal = WM_border_select_modal; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_gesture_border(ot, TRUE); +} + +static int do_lasso_select_mask(bContext *C, int mcords[][2], short moves, short select) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int i; + + rcti rect; + int change = FALSE; + + /* get rectangle from operator */ + BLI_lasso_boundbox(&rect, mcords, moves); + + /* do actual selection */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *point_deform = &points_array[i]; + + /* TODO: handles? */ + /* TODO: uw? */ + + float screen_co[2]; + + /* marker in screen coords */ + ED_mask_point_pos__reverse(C, + point_deform->bezt.vec[1][0], point_deform->bezt.vec[1][1], + &screen_co[0], &screen_co[1]); + + if (BLI_in_rcti(&rect, screen_co[0], screen_co[1]) && + BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], INT_MAX)) + { + BKE_mask_point_select_set(point, select); + BKE_mask_point_select_set_handle(point, select); + } + + change = TRUE; + } + } + } + + if (change) { + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + } + + return change; +} + +static int clip_lasso_select_exec(bContext *C, wmOperator *op) +{ + int mcords_tot; + int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); + + if (mcords) { + short select; + + select = !RNA_boolean_get(op->ptr, "deselect"); + do_lasso_select_mask(C, mcords, mcords_tot, select); + + MEM_freeN(mcords); + + return OPERATOR_FINISHED; + } + return OPERATOR_PASS_THROUGH; +} + +void MASK_OT_select_lasso(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Lasso Select"; + ot->description = "Select markers using lasso selection"; + ot->idname = "MASK_OT_select_lasso"; + + /* api callbacks */ + ot->invoke = WM_gesture_lasso_invoke; + ot->modal = WM_gesture_lasso_modal; + ot->exec = clip_lasso_select_exec; + ot->poll = ED_maskedit_mask_poll; + ot->cancel = WM_gesture_lasso_cancel; + + /* flags */ + ot->flag = OPTYPE_UNDO; + + /* properties */ + RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", ""); + RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect rather than select items"); + RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection instead of deselecting everything first"); +} + +/********************** circle select operator *********************/ + +static int mask_spline_point_inside_ellipse(BezTriple *bezt, float offset[2], float ellipse[2]) +{ + /* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */ + float x, y; + + x = (bezt->vec[1][0] - offset[0]) * ellipse[0]; + y = (bezt->vec[1][1] - offset[1]) * ellipse[1]; + + return x * x + y * y < 1.0f; +} + +static int circle_select_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int i; + + SpaceClip *sc = CTX_wm_space_clip(C); + ARegion *ar = CTX_wm_region(C); + int x, y, radius, width, height, mode, change = FALSE; + float zoomx, zoomy, offset[2], ellipse[2]; + + /* get operator properties */ + x = RNA_int_get(op->ptr, "x"); + y = RNA_int_get(op->ptr, "y"); + radius = RNA_int_get(op->ptr, "radius"); + + mode = RNA_int_get(op->ptr, "gesture_mode"); + + /* TODO - make generic! - this is SpaceClip only! */ + /* compute ellipse and position in unified coordinates */ + ED_space_clip_size(sc, &width, &height); + ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); + width = height = MAX2(width, height); + + ellipse[0] = width * zoomx / radius; + ellipse[1] = height * zoomy / radius; + + ED_mask_point_pos(C, x, y, &offset[0], &offset[1]); + + /* do actual selection */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *point_deform = &points_array[i]; + + if (mask_spline_point_inside_ellipse(&point_deform->bezt, offset, ellipse)) { + BKE_mask_point_select_set(point, mode == GESTURE_MODAL_SELECT); + BKE_mask_point_select_set_handle(point, mode == GESTURE_MODAL_SELECT); + + change = TRUE; + } + } + } + } + + if (change) { + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void MASK_OT_select_circle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Circle Select"; + ot->description = "Select markers using circle selection"; + ot->idname = "MASK_OT_select_circle"; + + /* api callbacks */ + ot->invoke = WM_gesture_circle_invoke; + ot->modal = WM_gesture_circle_modal; + ot->exec = circle_select_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "radius", 0, INT_MIN, INT_MAX, "Radius", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX); +} + +static int mask_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + MaskSpline *spline; + MaskSplinePoint *point = NULL; + float co[2]; + int do_select = !RNA_boolean_get(op->ptr, "deselect"); + + int is_handle = 0; + const float threshold = 19; + int change = FALSE; + + ED_mask_mouse_pos(C, event, co); + + point = ED_mask_point_find_nearest(C, mask, co, threshold, &masklay, &spline, &is_handle, NULL); + + if (point) { + ED_mask_spline_select_set(spline, do_select); + masklay->act_spline = spline; + masklay->act_point = point; + + change = TRUE; + } + + if (change) { + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void MASK_OT_select_linked_pick(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Linked"; + ot->idname = "MASK_OT_select_linked_pick"; + ot->description = "(De)select all points linked to the curve under the mouse cursor"; + + /* api callbacks */ + ot->invoke = mask_select_linked_pick_invoke; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", ""); +} + +static int mask_select_linked_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + + int change = FALSE; + + /* do actual selection */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + if (ED_mask_spline_select_check(spline)) { + ED_mask_spline_select_set(spline, TRUE); + change = TRUE; + } + } + } + + if (change) { + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void MASK_OT_select_linked(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Linked All"; + ot->idname = "MASK_OT_select_linked"; + ot->description = "Select all vertices linked to the active mesh"; + + /* api callbacks */ + ot->exec = mask_select_linked_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c new file mode 100644 index 00000000000..8da083ab400 --- /dev/null +++ b/source/blender/editors/mask/mask_shapekey.c @@ -0,0 +1,276 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_shapekey.c + * \ingroup edmask + */ + +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_mask.h" + +#include "DNA_object_types.h" +#include "DNA_mask_types.h" +#include "DNA_scene_types.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_mask.h" /* own include */ + +#include "mask_intern.h" /* own include */ + +static int mask_shape_key_insert_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + const int frame = CFRA; + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int change = FALSE; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskLayerShape *masklay_shape; + + if (!ED_mask_layer_select_check(masklay)) { + continue; + } + + masklay_shape = BKE_mask_layer_shape_varify_frame(masklay, frame); + BKE_mask_layer_shape_from_mask(masklay, masklay_shape); + change = TRUE; + } + + if (change) { + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void MASK_OT_shape_key_insert(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Insert Shape Key"; + ot->description = ""; + ot->idname = "MASK_OT_shape_key_insert"; + + /* api callbacks */ + ot->exec = mask_shape_key_insert_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int mask_shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + const int frame = CFRA; + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int change = FALSE; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskLayerShape *masklay_shape; + + if (!ED_mask_layer_select_check(masklay)) { + continue; + } + + masklay_shape = BKE_mask_layer_shape_find_frame(masklay, frame); + + if (masklay_shape) { + BKE_mask_layer_shape_unlink(masklay, masklay_shape); + change = TRUE; + } + } + + if (change) { + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void MASK_OT_shape_key_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Shape Key"; + ot->description = ""; + ot->idname = "MASK_OT_shape_key_clear"; + + /* api callbacks */ + ot->exec = mask_shape_key_clear_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int mask_shape_key_feather_reset_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + const int frame = CFRA; + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int change = FALSE; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + if (masklay->splines_shapes.first) { + MaskLayerShape *masklay_shape_reset; + MaskLayerShape *masklay_shape; + + /* get the shapekey of the current state */ + masklay_shape_reset = BKE_mask_layer_shape_alloc(masklay, frame); + /* initialize from mask - as if inseting a keyframe */ + BKE_mask_layer_shape_from_mask(masklay, masklay_shape_reset); + + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + + if (masklay_shape_reset->tot_vert == masklay_shape->tot_vert) { + int i_abs = 0; + int i; + MaskSpline *spline; + MaskLayerShapeElem *shape_ele_src; + MaskLayerShapeElem *shape_ele_dst; + + shape_ele_src = (MaskLayerShapeElem *)masklay_shape_reset->data; + shape_ele_dst = (MaskLayerShapeElem *)masklay_shape->data; + + for (spline = masklay->splines.first; spline; spline = spline->next) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(point)) { + /* TODO - nicer access here */ + shape_ele_dst->value[6] = shape_ele_src->value[6]; + } + + shape_ele_src++; + shape_ele_dst++; + + i_abs++; + } + } + + } + else { + // printf("%s: skipping\n", __func__); + } + + change = TRUE; + } + + BKE_mask_layer_shape_free(masklay_shape_reset); + } + } + + if (change) { + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void MASK_OT_shape_key_feather_reset(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Feather Reset Animation"; + ot->description = "Resets fearther weights on all selected points animation values"; + ot->idname = "MASK_OT_shape_key_feather_reset"; + + /* api callbacks */ + ot->exec = mask_shape_key_feather_reset_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + + +/* *** Shape Key Utils *** */ + +void ED_mask_layer_shape_auto_key(MaskLayer *masklay, const int frame) +{ + MaskLayerShape *masklay_shape; + + masklay_shape = BKE_mask_layer_shape_varify_frame(masklay, frame); + BKE_mask_layer_shape_from_mask(masklay, masklay_shape); +} + +int ED_mask_layer_shape_auto_key_all(Mask *mask, const int frame) +{ + MaskLayer *masklay; + int change = FALSE; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + ED_mask_layer_shape_auto_key(masklay, frame); + change = TRUE; + } + + return change; +} + +int ED_mask_layer_shape_auto_key_select(Mask *mask, const int frame) +{ + MaskLayer *masklay; + int change = FALSE; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + + if (!ED_mask_layer_select_check(masklay)) { + continue; + } + + ED_mask_layer_shape_auto_key(masklay, frame); + change = TRUE; + } + + return change; +} diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 6bbcd1d253e..f154aec2eb4 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -2247,7 +2247,7 @@ static int find_hole_chains(KnifeTool_OpData *kcd, ListBase *hole, BMFace *f, Li ListBase *chain; BMVert *v; BMIter iter; - int nh, nf, i, j, k, m, ax, ay, ok, sep, bestsep; + int nh, nf, i, j, k, m, ax, ay, ok, sep = 0 /* Quite warnings */, bestsep; int besti[2], bestj[2]; float d, bestd; diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index 7298153791e..185c804661d 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -86,7 +86,7 @@ /* ringsel operator */ /* struct for properties used while drawing */ -typedef struct tringselOpData { +typedef struct RingSelOpData { ARegion *ar; /* region that ringsel was activated in */ void *draw_handle; /* for drawing preview loop */ @@ -102,13 +102,13 @@ typedef struct tringselOpData { int extend; int do_cut; -} tringselOpData; +} RingSelOpData; /* modal loop selection drawing callback */ static void ringsel_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) { View3D *v3d = CTX_wm_view3d(C); - tringselOpData *lcd = arg; + RingSelOpData *lcd = arg; int i; if (lcd->totedge > 0) { @@ -176,7 +176,7 @@ static void edgering_find_order(BMEdge *lasteed, BMEdge *eed, } } -static void edgering_sel(tringselOpData *lcd, int previewlines, int select) +static void edgering_sel(RingSelOpData *lcd, int previewlines, int select) { BMEditMesh *em = lcd->em; BMEdge *startedge = lcd->eed; @@ -290,7 +290,7 @@ static void edgering_sel(tringselOpData *lcd, int previewlines, int select) lcd->totedge = tot; } -static void ringsel_find_edge(tringselOpData *lcd, int cuts) +static void ringsel_find_edge(RingSelOpData *lcd, int cuts) { if (lcd->eed) { edgering_sel(lcd, cuts, 0); @@ -304,7 +304,7 @@ static void ringsel_find_edge(tringselOpData *lcd, int cuts) static void ringsel_finish(bContext *C, wmOperator *op) { - tringselOpData *lcd = op->customdata; + RingSelOpData *lcd = op->customdata; int cuts = RNA_int_get(op->ptr, "number_cuts"); if (lcd->eed) { @@ -350,7 +350,7 @@ static void ringsel_finish(bContext *C, wmOperator *op) /* called when modal loop selection is done... */ static void ringsel_exit(bContext *UNUSED(C), wmOperator *op) { - tringselOpData *lcd = op->customdata; + RingSelOpData *lcd = op->customdata; /* deactivate the extra drawing stuff in 3D-View */ ED_region_draw_cb_exit(lcd->ar->type, lcd->draw_handle); @@ -368,10 +368,10 @@ static void ringsel_exit(bContext *UNUSED(C), wmOperator *op) /* called when modal loop selection gets set up... */ static int ringsel_init(bContext *C, wmOperator *op, int do_cut) { - tringselOpData *lcd; + RingSelOpData *lcd; /* alloc new customdata */ - lcd = op->customdata = MEM_callocN(sizeof(tringselOpData), "ringsel Modal Op Data"); + lcd = op->customdata = MEM_callocN(sizeof(RingSelOpData), "ringsel Modal Op Data"); /* assign the drawing handle for drawing preview line... */ lcd->ar = CTX_wm_region(C); @@ -402,7 +402,7 @@ static int ringcut_cancel(bContext *C, wmOperator *op) static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt) { Object *obedit = CTX_data_edit_object(C); - tringselOpData *lcd; + RingSelOpData *lcd; BMEdge *edge; int dist = 75; @@ -434,7 +434,7 @@ static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt) static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event) { int cuts = RNA_int_get(op->ptr, "number_cuts"); - tringselOpData *lcd = op->customdata; + RingSelOpData *lcd = op->customdata; int show_cuts = 0; view3d_operator_needs_opengl(C); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index b7c921cd8af..09475db0ed2 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -3676,14 +3676,14 @@ enum { SRT_REVERSE, /* Reverse current order of selected elements. */ }; -typedef struct bmelemsort { +typedef struct BMElemSort { float srt; /* Sort factor */ int org_idx; /* Original index of this element _in its mempool_ */ -} bmelemsort; +} BMElemSort; static int bmelemsort_comp(const void *v1, const void *v2) { - const bmelemsort *x1 = v1, *x2 = v2; + const BMElemSort *x1 = v1, *x2 = v2; return (x1->srt > x2->srt) - (x1->srt < x2->srt); } @@ -3704,7 +3704,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const /* In all five elements below, 0 = vertices, 1 = edges, 2 = faces. */ /* Just to mark protected elements. */ char *pblock[3] = {NULL, NULL, NULL}, *pb; - bmelemsort *sblock[3] = {NULL, NULL, NULL}, *sb; + BMElemSort *sblock[3] = {NULL, NULL, NULL}, *sb; int *map[3] = {NULL, NULL, NULL}, *mp; int totelem[3] = {0, 0, 0}, tot; int affected[3] = {0, 0, 0}, aff; @@ -3733,7 +3733,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[0]) { pb = pblock[0] = MEM_callocN(sizeof(char) * totelem[0], "sort_bmelem vert pblock"); - sb = sblock[0] = MEM_callocN(sizeof(bmelemsort) * totelem[0], "sort_bmelem vert sblock"); + sb = sblock[0] = MEM_callocN(sizeof(BMElemSort) * totelem[0], "sort_bmelem vert sblock"); BM_ITER_MESH_INDEX (ve, &iter, em->bm, BM_VERTS_OF_MESH, i) { if (BM_elem_flag_test(ve, flag)) { @@ -3752,7 +3752,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[1]) { pb = pblock[1] = MEM_callocN(sizeof(char) * totelem[1], "sort_bmelem edge pblock"); - sb = sblock[1] = MEM_callocN(sizeof(bmelemsort) * totelem[1], "sort_bmelem edge sblock"); + sb = sblock[1] = MEM_callocN(sizeof(BMElemSort) * totelem[1], "sort_bmelem edge sblock"); BM_ITER_MESH_INDEX (ed, &iter, em->bm, BM_EDGES_OF_MESH, i) { if (BM_elem_flag_test(ed, flag)) { @@ -3772,7 +3772,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[2]) { pb = pblock[2] = MEM_callocN(sizeof(char) * totelem[2], "sort_bmelem face pblock"); - sb = sblock[2] = MEM_callocN(sizeof(bmelemsort) * totelem[2], "sort_bmelem face sblock"); + sb = sblock[2] = MEM_callocN(sizeof(BMElemSort) * totelem[2], "sort_bmelem face sblock"); BM_ITER_MESH_INDEX (fa, &iter, em->bm, BM_FACES_OF_MESH, i) { if (BM_elem_flag_test(fa, flag)) { @@ -3806,7 +3806,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[0]) { pb = pblock[0] = MEM_callocN(sizeof(char) * totelem[0], "sort_bmelem vert pblock"); - sb = sblock[0] = MEM_callocN(sizeof(bmelemsort) * totelem[0], "sort_bmelem vert sblock"); + sb = sblock[0] = MEM_callocN(sizeof(BMElemSort) * totelem[0], "sort_bmelem vert sblock"); BM_ITER_MESH_INDEX (ve, &iter, em->bm, BM_VERTS_OF_MESH, i) { if (BM_elem_flag_test(ve, flag)) { @@ -3822,7 +3822,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[1]) { pb = pblock[1] = MEM_callocN(sizeof(char) * totelem[1], "sort_bmelem edge pblock"); - sb = sblock[1] = MEM_callocN(sizeof(bmelemsort) * totelem[1], "sort_bmelem edge sblock"); + sb = sblock[1] = MEM_callocN(sizeof(BMElemSort) * totelem[1], "sort_bmelem edge sblock"); BM_ITER_MESH_INDEX (ed, &iter, em->bm, BM_EDGES_OF_MESH, i) { if (BM_elem_flag_test(ed, flag)) { @@ -3841,7 +3841,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[2]) { pb = pblock[2] = MEM_callocN(sizeof(char) * totelem[2], "sort_bmelem face pblock"); - sb = sblock[2] = MEM_callocN(sizeof(bmelemsort) * totelem[2], "sort_bmelem face sblock"); + sb = sblock[2] = MEM_callocN(sizeof(BMElemSort) * totelem[2], "sort_bmelem face sblock"); BM_ITER_MESH_INDEX (fa, &iter, em->bm, BM_FACES_OF_MESH, i) { if (BM_elem_flag_test(fa, flag)) { @@ -3862,7 +3862,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const /* Faces only! */ else if (action == SRT_MATERIAL && totelem[2]) { pb = pblock[2] = MEM_callocN(sizeof(char) * totelem[2], "sort_bmelem face pblock"); - sb = sblock[2] = MEM_callocN(sizeof(bmelemsort) * totelem[2], "sort_bmelem face sblock"); + sb = sblock[2] = MEM_callocN(sizeof(BMElemSort) * totelem[2], "sort_bmelem face sblock"); BM_ITER_MESH_INDEX (fa, &iter, em->bm, BM_FACES_OF_MESH, i) { if (BM_elem_flag_test(fa, flag)) { @@ -3966,7 +3966,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const * enabling/disabling an element type. */ BLI_srandom(seed); pb = pblock[0] = MEM_callocN(sizeof(char) * totelem[0], "sort_bmelem vert pblock"); - sb = sblock[0] = MEM_callocN(sizeof(bmelemsort) * totelem[0], "sort_bmelem vert sblock"); + sb = sblock[0] = MEM_callocN(sizeof(BMElemSort) * totelem[0], "sort_bmelem vert sblock"); BM_ITER_MESH_INDEX (ve, &iter, em->bm, BM_VERTS_OF_MESH, i) { if (BM_elem_flag_test(ve, flag)) { @@ -3983,7 +3983,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[1]) { BLI_srandom(seed); pb = pblock[1] = MEM_callocN(sizeof(char) * totelem[1], "sort_bmelem edge pblock"); - sb = sblock[1] = MEM_callocN(sizeof(bmelemsort) * totelem[1], "sort_bmelem edge sblock"); + sb = sblock[1] = MEM_callocN(sizeof(BMElemSort) * totelem[1], "sort_bmelem edge sblock"); BM_ITER_MESH_INDEX (ed, &iter, em->bm, BM_EDGES_OF_MESH, i) { if (BM_elem_flag_test(ed, flag)) { @@ -4000,7 +4000,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[2]) { BLI_srandom(seed); pb = pblock[2] = MEM_callocN(sizeof(char) * totelem[2], "sort_bmelem face pblock"); - sb = sblock[2] = MEM_callocN(sizeof(bmelemsort) * totelem[2], "sort_bmelem face sblock"); + sb = sblock[2] = MEM_callocN(sizeof(BMElemSort) * totelem[2], "sort_bmelem face sblock"); BM_ITER_MESH_INDEX (fa, &iter, em->bm, BM_FACES_OF_MESH, i) { if (BM_elem_flag_test(fa, flag)) { @@ -4018,7 +4018,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const else if (action == SRT_REVERSE) { if (totelem[0]) { pb = pblock[0] = MEM_callocN(sizeof(char) * totelem[0], "sort_bmelem vert pblock"); - sb = sblock[0] = MEM_callocN(sizeof(bmelemsort) * totelem[0], "sort_bmelem vert sblock"); + sb = sblock[0] = MEM_callocN(sizeof(BMElemSort) * totelem[0], "sort_bmelem vert sblock"); BM_ITER_MESH_INDEX (ve, &iter, em->bm, BM_VERTS_OF_MESH, i) { if (BM_elem_flag_test(ve, flag)) { @@ -4034,7 +4034,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[1]) { pb = pblock[1] = MEM_callocN(sizeof(char) * totelem[1], "sort_bmelem edge pblock"); - sb = sblock[1] = MEM_callocN(sizeof(bmelemsort) * totelem[1], "sort_bmelem edge sblock"); + sb = sblock[1] = MEM_callocN(sizeof(BMElemSort) * totelem[1], "sort_bmelem edge sblock"); BM_ITER_MESH_INDEX (ed, &iter, em->bm, BM_EDGES_OF_MESH, i) { if (BM_elem_flag_test(ed, flag)) { @@ -4050,7 +4050,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[2]) { pb = pblock[2] = MEM_callocN(sizeof(char) * totelem[2], "sort_bmelem face pblock"); - sb = sblock[2] = MEM_callocN(sizeof(bmelemsort) * totelem[2], "sort_bmelem face sblock"); + sb = sblock[2] = MEM_callocN(sizeof(BMElemSort) * totelem[2], "sort_bmelem face sblock"); BM_ITER_MESH_INDEX (fa, &iter, em->bm, BM_FACES_OF_MESH, i) { if (BM_elem_flag_test(fa, flag)) { @@ -4086,11 +4086,11 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const sb = sblock[j]; if (pb && sb && !map[j]) { char *p_blk; - bmelemsort *s_blk; + BMElemSort *s_blk; tot = totelem[j]; aff = affected[j]; - qsort(sb, aff, sizeof(bmelemsort), bmelemsort_comp); + qsort(sb, aff, sizeof(BMElemSort), bmelemsort_comp); mp = map[j] = MEM_mallocN(sizeof(int) * tot, "sort_bmelem map"); p_blk = pb + tot - 1; @@ -4498,13 +4498,18 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event) BevelData *opdata; float mlen[2]; - if (!edbm_bevel_init(C, op, TRUE)) + if (!edbm_bevel_init(C, op, TRUE)) { return OPERATOR_CANCELLED; + } - /* initialize mouse values */ opdata = op->customdata; - calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter); + /* initialize mouse values */ + if (!calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter)) { + /* in this case the tool will likely do nothing, + * ideally this will never happen and should be checked for above */ + opdata->mcenter[0] = opdata->mcenter[1] = 0; + } mlen[0] = opdata->mcenter[0] - event->mval[0]; mlen[1] = opdata->mcenter[1] - event->mval[1]; opdata->initial_length = len_v2(mlen); @@ -4795,8 +4800,12 @@ static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event) opdata = op->customdata; - calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter); /* initialize mouse values */ + if (!calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter)) { + /* in this case the tool will likely do nothing, + * ideally this will never happen and should be checked for above */ + opdata->mcenter[0] = opdata->mcenter[1] = 0; + } mlen[0] = opdata->mcenter[0] - event->mval[0]; mlen[1] = opdata->mcenter[1] - event->mval[1]; opdata->initial_length = len_v2(mlen); @@ -4830,13 +4839,11 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) mdiff[1] = opdata->mcenter[1] - event->mval[1]; if (opdata->modify_depth) { - amount = opdata->old_depth + (len_v2(mdiff) - - opdata->initial_length) / opdata->initial_length; + amount = opdata->old_depth + (len_v2(mdiff) - opdata->initial_length) / opdata->initial_length; RNA_float_set(op->ptr, "depth", amount); } else { - amount = opdata->old_thickness - (len_v2(mdiff) - - opdata->initial_length) / opdata->initial_length; + amount = opdata->old_thickness - (len_v2(mdiff) - opdata->initial_length) / opdata->initial_length; amount = MAX2(amount, 0.0f); RNA_float_set(op->ptr, "thickness", amount); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 24dd56a4834..3d7dd01bf30 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -180,7 +180,7 @@ static int object_hide_view_set_exec(bContext *C, wmOperator *op) short changed = 0; const int unselected = RNA_boolean_get(op->ptr, "unselected"); - CTX_DATA_BEGIN (C, Base *, base, visible_bases) + CTX_DATA_BEGIN(C, Base *, base, visible_bases) { if (!unselected) { if (base->flag & SELECT) { @@ -240,7 +240,7 @@ static int object_hide_render_clear_exec(bContext *C, wmOperator *UNUSED(op)) short changed = 0; /* XXX need a context loop to handle such cases */ - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects) { if (ob->restrictflag & OB_RESTRICT_RENDER) { ob->restrictflag &= ~OB_RESTRICT_RENDER; @@ -275,7 +275,7 @@ static int object_hide_render_set_exec(bContext *C, wmOperator *op) { const int unselected = RNA_boolean_get(op->ptr, "unselected"); - CTX_DATA_BEGIN (C, Base *, base, visible_bases) + CTX_DATA_BEGIN(C, Base *, base, visible_bases) { if (!unselected) { if (base->flag & SELECT) { @@ -1114,7 +1114,7 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene) ListBase targets = {NULL, NULL}; /* loop over objects in scene */ - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects) { /* set flag to force recalc, then grab path(s) from object */ ob->avs.recalc |= ANIMVIZ_RECALC_PATHS; @@ -1157,7 +1157,7 @@ static int object_calculate_paths_exec(bContext *C, wmOperator *op) int end = RNA_int_get(op->ptr, "end_frame"); /* set up path data for bones being calculated */ - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects) { bAnimVizSettings *avs = &ob->avs; @@ -1196,9 +1196,9 @@ void OBJECT_OT_paths_calculate(wmOperatorType *ot) /* properties */ RNA_def_int(ot->srna, "start_frame", 1, MINAFRAME, MAXFRAME, "Start", - "First frame to calculate object paths on", MINFRAME, MAXFRAME/2.0); + "First frame to calculate object paths on", MINFRAME, MAXFRAME / 2.0); RNA_def_int(ot->srna, "end_frame", 250, MINAFRAME, MAXFRAME, "End", - "Last frame to calculate object paths on", MINFRAME, MAXFRAME/2.0); + "Last frame to calculate object paths on", MINFRAME, MAXFRAME / 2.0); } /* --------- */ @@ -1231,7 +1231,7 @@ void OBJECT_OT_paths_update(wmOperatorType *ot) ot->poll = ED_operator_object_active_editable; /* TODO: this should probably check for existing paths */ /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } /* --------- */ @@ -1240,7 +1240,7 @@ void OBJECT_OT_paths_update(wmOperatorType *ot) void ED_objects_clear_paths(bContext *C) { /* loop over objects in scene */ - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects) { if (ob->mpath) { animviz_free_motionpath(ob->mpath); @@ -1288,7 +1288,7 @@ static int shade_smooth_exec(bContext *C, wmOperator *op) int clear = (strcmp(op->idname, "OBJECT_OT_shade_flat") == 0); int done = FALSE; - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects) { if (ob->type == OB_MESH) { @@ -1666,10 +1666,12 @@ static EnumPropertyItem game_properties_copy_operations[] = { {COPY_PROPERTIES_REPLACE, "REPLACE", 0, "Replace Properties", ""}, {COPY_PROPERTIES_MERGE, "MERGE", 0, "Merge Properties", ""}, {COPY_PROPERTIES_COPY, "COPY", 0, "Copy a Property", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} +}; -static EnumPropertyItem gameprops_items[]= { - {0, NULL, 0, NULL, NULL}}; +static EnumPropertyItem gameprops_items[] = { + {0, NULL, 0, NULL, NULL} +}; static EnumPropertyItem *gameprops_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) { @@ -1706,7 +1708,7 @@ static int game_property_copy_exec(bContext *C, wmOperator *op) prop = BLI_findlink(&ob->prop, propid - 1); if (prop) { - CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects) { if (ob != ob_iter) set_ob_property(ob_iter, prop); @@ -1715,7 +1717,7 @@ static int game_property_copy_exec(bContext *C, wmOperator *op) } else { - CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects) { if (ob != ob_iter) { if (type == COPY_PROPERTIES_REPLACE) @@ -1756,7 +1758,7 @@ void OBJECT_OT_game_property_copy(wmOperatorType *ot) static int game_property_clear_exec(bContext *C, wmOperator *UNUSED(op)) { - CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects) { free_properties(&ob_iter->prop); } @@ -1786,7 +1788,7 @@ static int logicbricks_copy_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = ED_object_active_context(C); - CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects) { if (ob != ob_iter) { /* first: free all logic */ @@ -1843,7 +1845,7 @@ static int game_physics_copy_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = ED_object_active_context(C); - CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects) { if (ob != ob_iter) { ob_iter->gameflag = ob->gameflag; diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index f6e8ccf4ec9..0a9944debe1 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -344,18 +344,17 @@ int mouse_lattice(bContext *C, const int mval[2], int extend, int deselect, int bp = findnearestLattvert(&vc, mval, 1); if (bp) { - if (extend) { - bp->f1 |= SELECT; - } - else if (deselect) { - bp->f1 &= ~SELECT; - } + if (extend) { + bp->f1 |= SELECT; + } + else if (deselect) { + bp->f1 &= ~SELECT; + } else if (toggle) { bp->f1 ^= SELECT; /* swap */ } - else - { - ED_setflagsLatt(vc.obedit, 0); + else { + ED_setflagsLatt(vc.obedit, 0); bp->f1 |= SELECT; } diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 7dd17e59f6f..d6b5fb9fc10 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -642,8 +642,10 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi BLI_remlink(&ob->modifiers, md); modifier_free(md); - /* ensure mesh paint mask layer remains after applying */ - ED_sculpt_mask_layers_ensure(ob, NULL); + if (ob->type == OB_MESH) { + /* ensure mesh paint mask layer remains after applying */ + ED_sculpt_mask_layers_ensure(ob, NULL); + } return 1; } diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 6e653eff57c..d0a93302b7f 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -441,6 +441,14 @@ void ED_keymap_proportional_obmode(struct wmKeyConfig *UNUSED(keyconf), struct w RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_proportional_edit_objects"); } +void ED_keymap_proportional_maskmode(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap) +{ + wmKeyMapItem *kmi; + + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", OKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_proportional_edit_mask"); +} + void ED_keymap_proportional_editmode(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap, const short do_connected) { diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 85b9d78c657..fc0aa39e733 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1929,6 +1929,7 @@ static int drop_named_material_invoke(bContext *C, wmOperator *op, wmEvent *even DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); + WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING, ma); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index fa86f089387..89f018a1b76 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -708,10 +708,11 @@ void OBJECT_OT_select_grouped(wmOperatorType *ot) static int object_select_by_layer_exec(bContext *C, wmOperator *op) { unsigned int layernum; - short extend; + short extend, match; extend = RNA_boolean_get(op->ptr, "extend"); layernum = RNA_int_get(op->ptr, "layers"); + match = RNA_enum_get(op->ptr, "match"); if (extend == 0) { CTX_DATA_BEGIN (C, Base *, base, visible_bases) @@ -723,7 +724,14 @@ static int object_select_by_layer_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN (C, Base *, base, visible_bases) { - if (base->lay == (1 << (layernum - 1))) + int ok = 0; + + if (match == 1) /* exact */ + ok = (base->lay == (1 << (layernum - 1))); + else /* shared layers */ + ok = (base->lay & (1 << (layernum - 1))); + + if (ok) ED_base_object_select(base, BA_SELECT); } CTX_DATA_END; @@ -736,6 +744,12 @@ static int object_select_by_layer_exec(bContext *C, wmOperator *op) void OBJECT_OT_select_by_layer(wmOperatorType *ot) { + static EnumPropertyItem match_items[] = { + {1, "EXACT", 0, "Exact Match", ""}, + {2, "SHARED", 0, "Shared Layers", ""}, + {0, NULL, 0, NULL, NULL} + }; + /* identifiers */ ot->name = "Select by Layer"; ot->description = "Select all visible objects on a layer"; @@ -750,6 +764,7 @@ void OBJECT_OT_select_by_layer(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ + RNA_def_enum(ot->srna, "match", match_items, 0, "Match", ""); RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first"); RNA_def_int(ot->srna, "layers", 1, 1, 20, "Layer", "", 1, 20); } diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 356ede878b5..8fa3c6f992f 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -288,11 +288,12 @@ static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str) else if (scene->r.scemode & R_SINGLE_LAYER) spos += sprintf(spos, "Single Layer | "); + spos += sprintf(spos, "Frame:%d ", (scene->r.cfra)); + if (rs->statstr) { - spos += sprintf(spos, "%s ", rs->statstr); + spos += sprintf(spos, "| %s ", rs->statstr); } else { - spos += sprintf(spos, "Fra:%d ", (scene->r.cfra)); if (rs->totvert) spos += sprintf(spos, "Ve:%d ", rs->totvert); if (rs->totface) spos += sprintf(spos, "Fa:%d ", rs->totface); if (rs->tothalo) spos += sprintf(spos, "Ha:%d ", rs->tothalo); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 8baca253519..4e98d2ae967 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -46,6 +46,7 @@ #include "DNA_scene_types.h" #include "DNA_meta_types.h" #include "DNA_mesh_types.h" +#include "DNA_mask_types.h" #include "DNA_userdef_types.h" #include "BKE_context.h" @@ -59,6 +60,7 @@ #include "BKE_screen.h" #include "BKE_tessmesh.h" #include "BKE_sound.h" +#include "BKE_mask.h" #include "WM_api.h" #include "WM_types.h" @@ -71,6 +73,7 @@ #include "ED_screen_types.h" #include "ED_keyframes_draw.h" #include "ED_view3d.h" +#include "ED_clip.h" #include "RNA_access.h" #include "RNA_define.h" @@ -453,6 +456,13 @@ int ED_operator_editmball(bContext *C) return 0; } +int ED_operator_mask(bContext *C) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + + return ED_space_clip_show_maskedit(sc); +} + /* *************************** action zone operator ************************** */ /* operator state vars used: @@ -1937,7 +1947,17 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) if (ob) ob_to_keylist(&ads, ob, &keys, NULL); - + + { + SpaceClip *sc = CTX_wm_space_clip(C); + if (sc) { + if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask) { + MaskLayer *masklay = BKE_mask_layer_active(sc->mask); + mask_to_keylist(&ads, masklay, &keys); + } + } + } + /* build linked-list for searching */ BLI_dlrbTree_linkedlist_sync(&keys); diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index b5d44676cf6..5ca436b07b2 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -333,7 +333,7 @@ static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc, float location[3]) { Scene *scene = CTX_data_scene(C); - Paint *paint = paint_get_active(scene); + Paint *paint = paint_get_active_from_context(C); Brush *brush = paint_brush(paint); float window[2]; int hit; @@ -503,7 +503,7 @@ static void paint_cursor_on_hit(Sculpt *sd, Brush *brush, ViewContext *vc, static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) { Scene *scene = CTX_data_scene(C); - Paint *paint = paint_get_active(scene); + Paint *paint = paint_get_active_from_context(C); Brush *brush = paint_brush(paint); ViewContext vc; float final_radius; @@ -605,7 +605,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) void paint_cursor_start(bContext *C, int (*poll)(bContext *C)) { - Paint *p = paint_get_active(CTX_data_scene(C)); + Paint *p = paint_get_active_from_context(C); if (p && !p->paint_cursor) p->paint_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), poll, paint_draw_cursor, NULL); diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index cd8b9164862..89c328e71d8 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -265,7 +265,7 @@ static void get_pbvh_nodes(PBVH *pbvh, float clip_planes[4][4], PartialVisArea mode) { - BLI_pbvh_SearchCallback cb; + BLI_pbvh_SearchCallback cb = NULL; /* select search callback */ switch (mode) { @@ -277,7 +277,6 @@ static void get_pbvh_nodes(PBVH *pbvh, break; case PARTIALVIS_ALL: case PARTIALVIS_MASKED: - cb = NULL; break; } diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index ed86cb67687..4dee83dbb82 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -5215,7 +5215,7 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata) Scene *scene = CTX_data_scene(C); //Brush *brush= image_paint_brush(C); - Paint *paint = paint_get_active(scene); + Paint *paint = paint_get_active_from_context(C); Brush *brush = paint_brush(paint); if (paint && brush && paint->flags & PAINT_SHOW_BRUSH) { @@ -5420,13 +5420,12 @@ void PAINT_OT_grab_clone(wmOperatorType *ot) static int sample_color_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Brush *brush = image_paint_brush(C); ARegion *ar = CTX_wm_region(C); int location[2]; RNA_int_get_array(op->ptr, "location", location); - paint_sample_color(scene, ar, location[0], location[1]); + paint_sample_color(C, ar, location[0], location[1]); WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush); diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index de149bf2806..794e7755636 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -137,7 +137,7 @@ float paint_get_tex_pixel(struct Brush *br, float u, float v); int imapaint_pick_face(struct ViewContext *vc, const int mval[2], unsigned int *index, unsigned int totface); void imapaint_pick_uv(struct Scene *scene, struct Object *ob, unsigned int faceindex, const int xy[2], float uv[2]); -void paint_sample_color(struct Scene *scene, struct ARegion *ar, int x, int y); +void paint_sample_color(const struct bContext *C, struct ARegion *ar, int x, int y); void BRUSH_OT_curve_preset(struct wmOperatorType *ot); void PAINT_OT_face_select_linked(struct wmOperatorType *ot); diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 298ecf764d6..e309bdb99cb 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -61,16 +61,16 @@ #include <stdlib.h> static void mask_flood_fill_set_elem(float *elem, - PaintMaskFloodMode mode, - float value) + PaintMaskFloodMode mode, + float value) { switch (mode) { - case PAINT_MASK_FLOOD_VALUE: - (*elem) = value; - break; - case PAINT_MASK_INVERT: - (*elem) = 1.0f - (*elem); - break; + case PAINT_MASK_FLOOD_VALUE: + (*elem) = value; + break; + case PAINT_MASK_INVERT: + (*elem) = 1.0f - (*elem); + break; } } diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 23d1c0090a0..7df6a893b5c 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -60,7 +60,7 @@ static int brush_add_exec(bContext *C, wmOperator *UNUSED(op)) { /*int type = RNA_enum_get(op->ptr, "type");*/ - Paint *paint = paint_get_active(CTX_data_scene(C)); + Paint *paint = paint_get_active_from_context(C); struct Brush *br = paint_brush(paint); if (br) @@ -68,7 +68,7 @@ static int brush_add_exec(bContext *C, wmOperator *UNUSED(op)) else br = BKE_brush_add("Brush"); - paint_brush_set(paint_get_active(CTX_data_scene(C)), br); + paint_brush_set(paint, br); return OPERATOR_FINISHED; } @@ -91,7 +91,7 @@ static void BRUSH_OT_add(wmOperatorType *ot) static int brush_scale_size_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Paint *paint = paint_get_active(scene); + Paint *paint = paint_get_active_from_context(C); struct Brush *brush = paint_brush(paint); // Object *ob= CTX_data_active_object(C); float scalar = RNA_float_get(op->ptr, "scalar"); @@ -173,7 +173,7 @@ static void PAINT_OT_vertex_color_set(wmOperatorType *ot) static int brush_reset_exec(bContext *C, wmOperator *UNUSED(op)) { - Paint *paint = paint_get_active(CTX_data_scene(C)); + Paint *paint = paint_get_active_from_context(C); struct Brush *brush = paint_brush(paint); Object *ob = CTX_data_active_object(C); diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 987ab932fd6..b53edeadb51 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -100,10 +100,11 @@ typedef struct PaintStroke { /*** Cursor ***/ static void paint_draw_smooth_stroke(bContext *C, int x, int y, void *customdata) { - Brush *brush = paint_brush(paint_get_active(CTX_data_scene(C))); + Paint *paint = paint_get_active_from_context(C); + Brush *brush = paint_brush(paint); PaintStroke *stroke = customdata; - glColor4ubv(paint_get_active(CTX_data_scene(C))->paint_cursor_col); + glColor4ubv(paint->paint_cursor_col); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); @@ -141,7 +142,7 @@ static float event_tablet_data(wmEvent *event, int *pen_flip) static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, float mouse_in[2]) { Scene *scene = CTX_data_scene(C); - Paint *paint = paint_get_active(scene); + Paint *paint = paint_get_active_from_context(C); Brush *brush = paint_brush(paint); PaintStroke *stroke = op->customdata; float mouse[3]; @@ -202,10 +203,10 @@ static int paint_smooth_stroke(PaintStroke *stroke, float output[2], if ((stroke->brush->flag & BRUSH_SMOOTH_STROKE) && !ELEM4(stroke->brush->sculpt_tool, - SCULPT_TOOL_GRAB, - SCULPT_TOOL_THUMB, - SCULPT_TOOL_ROTATE, - SCULPT_TOOL_SNAKE_HOOK) && + SCULPT_TOOL_GRAB, + SCULPT_TOOL_THUMB, + SCULPT_TOOL_ROTATE, + SCULPT_TOOL_SNAKE_HOOK) && !(stroke->brush->flag & BRUSH_ANCHORED) && !(stroke->brush->flag & BRUSH_RESTORE_MESH)) { @@ -281,7 +282,7 @@ PaintStroke *paint_stroke_new(bContext *C, { PaintStroke *stroke = MEM_callocN(sizeof(PaintStroke), "PaintStroke"); - stroke->brush = paint_brush(paint_get_active(CTX_data_scene(C))); + stroke->brush = paint_brush(paint_get_active_from_context(C)); view3d_set_viewcontext(C, &stroke->vc); view3d_get_transformation(stroke->vc.ar, stroke->vc.rv3d, stroke->vc.obact, &stroke->mats); @@ -358,12 +359,12 @@ struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf) } static void paint_stroke_add_sample(const Paint *paint, - PaintStroke *stroke, - float x, float y) + PaintStroke *stroke, + float x, float y) { PaintSample *sample = &stroke->samples[stroke->cur_sample]; int max_samples = MIN2(PAINT_MAX_INPUT_SAMPLES, - MAX2(paint->num_input_samples, 1)); + MAX2(paint->num_input_samples, 1)); sample->mouse[0] = x; sample->mouse[1] = y; @@ -376,7 +377,7 @@ static void paint_stroke_add_sample(const Paint *paint, } static void paint_stroke_sample_average(const PaintStroke *stroke, - PaintSample *average) + PaintSample *average) { int i; @@ -394,7 +395,7 @@ static void paint_stroke_sample_average(const PaintStroke *stroke, int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event) { - Paint *p = paint_get_active(CTX_data_scene(C)); + Paint *p = paint_get_active_from_context(C); PaintStroke *stroke = op->customdata; PaintSample sample_average; float mouse[2]; @@ -518,7 +519,7 @@ void paint_stroke_set_mode_data(PaintStroke *stroke, void *mode_data) int paint_poll(bContext *C) { - Paint *p = paint_get_active(CTX_data_scene(C)); + Paint *p = paint_get_active_from_context(C); Object *ob = CTX_data_active_object(C); return p && ob && paint_brush(p) && diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 4c374674c9a..082e40f8e4c 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -333,9 +333,9 @@ int imapaint_pick_face(ViewContext *vc, const int mval[2], unsigned int *index, } /* used for both 3d view and image window */ -void paint_sample_color(Scene *scene, ARegion *ar, int x, int y) /* frontbuf */ +void paint_sample_color(const bContext *C, ARegion *ar, int x, int y) /* frontbuf */ { - Brush *br = paint_brush(paint_get_active(scene)); + Brush *br = paint_brush(paint_get_active_from_context(C)); unsigned int col; char *cp; @@ -357,7 +357,7 @@ void paint_sample_color(Scene *scene, ARegion *ar, int x, int y) /* frontbuf static int brush_curve_preset_exec(bContext *C, wmOperator *op) { - Brush *br = paint_brush(paint_get_active(CTX_data_scene(C))); + Brush *br = paint_brush(paint_get_active_from_context(C)); BKE_brush_curve_preset(br, RNA_enum_get(op->ptr, "shape")); return OPERATOR_FINISHED; @@ -365,7 +365,7 @@ static int brush_curve_preset_exec(bContext *C, wmOperator *op) static int brush_curve_preset_poll(bContext *C) { - Brush *br = paint_brush(paint_get_active(CTX_data_scene(C))); + Brush *br = paint_brush(paint_get_active_from_context(C)); return br && br->curve; } diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index eb79989b90b..3c37ad8cf2a 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -2461,6 +2461,8 @@ static void wpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) } DAG_id_tag_update(ob->data, 0); + + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); } @@ -2622,10 +2624,10 @@ void PAINT_OT_vertex_paint_toggle(wmOperatorType *ot) * - revise whether op->customdata should be added in object, in set_vpaint */ -typedef struct polyfacemap_e { - struct polyfacemap_e *next, *prev; +typedef struct PolyFaceMap { + struct PolyFaceMap *next, *prev; int facenr; -} polyfacemap_e; +} PolyFaceMap; typedef struct VPaintData { ViewContext vc; @@ -2646,7 +2648,7 @@ typedef struct VPaintData { static void vpaint_build_poly_facemap(struct VPaintData *vd, Mesh *me) { MFace *mf; - polyfacemap_e *e; + PolyFaceMap *e; int *origIndex; int i; @@ -2665,7 +2667,7 @@ static void vpaint_build_poly_facemap(struct VPaintData *vd, Mesh *me) if (*origIndex == ORIGINDEX_NONE) continue; - e = BLI_memarena_alloc(vd->polyfacemap_arena, sizeof(polyfacemap_e)); + e = BLI_memarena_alloc(vd->polyfacemap_arena, sizeof(PolyFaceMap)); e->facenr = i; BLI_addtail(&vd->polyfacemap[*origIndex], e); @@ -2782,7 +2784,7 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Object *ob, MCol *mc; MLoop *ml; MLoopCol *mlc; - polyfacemap_e *e; + PolyFaceMap *e; unsigned int *lcol = ((unsigned int *)me->mloopcol) + mpoly->loopstart; unsigned int *lcolorig = ((unsigned int *)vp->vpaint_prev) + mpoly->loopstart; float alpha; @@ -2954,6 +2956,8 @@ static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) { ToolSettings *ts = CTX_data_tool_settings(C); struct VPaintData *vpd = paint_stroke_mode_data(stroke); + ViewContext *vc = &vpd->vc; + Object *ob = vc->obact; if (vpd->vertexcosnos) MEM_freeN(vpd->vertexcosnos); @@ -2966,6 +2970,8 @@ static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) BLI_memarena_free(vpd->polyfacemap_arena); } + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + MEM_freeN(vpd); } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 7b8337ff957..66ad05aec7e 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -753,8 +753,8 @@ static float tex_strength(SculptSession *ss, Brush *br, float point[3], else if (ss->texcache) { float rotation = -mtex->rot; float symm_point[3], point_2d[2]; - float x, y; - float radius; + float x = 0.0f, y = 0.0f; /* Quite warnings */ + float radius = 1.0f; /* Quite warnings */ /* if the active area is being applied for symmetry, flip it * across the symmetry axis and rotate it back to the original @@ -981,8 +981,8 @@ static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nod /* Calculate primary direction of movement for many brushes */ static void calc_sculpt_normal(Sculpt *sd, Object *ob, - PBVHNode **nodes, int totnode, - float an[3]) + PBVHNode **nodes, int totnode, + float an[3]) { const Brush *brush = paint_brush(&sd->paint); const SculptSession *ss = ob->sculpt; @@ -990,8 +990,8 @@ static void calc_sculpt_normal(Sculpt *sd, Object *ob, switch (brush->sculpt_plane) { case SCULPT_DISP_DIR_VIEW: ED_view3d_global_to_vector(ss->cache->vc->rv3d, - ss->cache->vc->rv3d->twmat[3], - an); + ss->cache->vc->rv3d->twmat[3], + an); break; case SCULPT_DISP_DIR_X: @@ -1021,7 +1021,7 @@ static void calc_sculpt_normal(Sculpt *sd, Object *ob, } static void update_sculpt_normal(Sculpt *sd, Object *ob, - PBVHNode **nodes, int totnode) + PBVHNode **nodes, int totnode) { const Brush *brush = paint_brush(&sd->paint); StrokeCache *cache = ob->sculpt->cache; @@ -1056,7 +1056,7 @@ static void calc_local_y(ViewContext *vc, const float center[3], float y[3]) } static void calc_brush_local_mat(const Brush *brush, Object *ob, - float local_mat[4][4]) + float local_mat[4][4]) { const StrokeCache *cache = ob->sculpt->cache; float tmat[4][4]; @@ -1105,10 +1105,10 @@ static void update_brush_local_mat(Sculpt *sd, Object *ob) StrokeCache *cache = ob->sculpt->cache; if (cache->mirror_symmetry_pass == 0 && - cache->radial_symmetry_pass == 0) + cache->radial_symmetry_pass == 0) { calc_brush_local_mat(paint_brush(&sd->paint), ob, - cache->brush_local_mat); + cache->brush_local_mat); } } @@ -1413,6 +1413,7 @@ static void smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, SculptSession *ss = ob->sculpt; const int max_iterations = 4; const float fract = 1.0f / max_iterations; + PBVHType type = BLI_pbvh_type(ss->pbvh); int iteration, n, count; float last; @@ -1421,16 +1422,25 @@ static void smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, count = (int)(bstrength * max_iterations); last = max_iterations * (bstrength - count * fract); + if (type == PBVH_FACES && !ss->pmap) { + BLI_assert(!"sculpt smooth: pmap missing"); + return; + } + for (iteration = 0; iteration <= count; ++iteration) { + float strength = (iteration != count) ? 1.0f : last; + #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) for (n = 0; n < totnode; n++) { - if (ss->multires) { - do_multires_smooth_brush(sd, ss, nodes[n], - iteration != count ? 1.0f : last, smooth_mask); - } - else if (ss->pmap) { - do_mesh_smooth_brush(sd, ss, nodes[n], - iteration != count ? 1.0f : last, smooth_mask); + switch(type) { + case PBVH_GRIDS: + do_multires_smooth_brush(sd, ss, nodes[n], strength, + smooth_mask); + break; + case PBVH_FACES: + do_mesh_smooth_brush(sd, ss, nodes[n], strength, + smooth_mask); + break; } } @@ -3571,6 +3581,21 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, sd->special_rotation = cache->special_rotation; } +/* Returns true iff any of the smoothing modes are active (currently + one of smooth brush, autosmooth, mask smooth, or shift-key + smooth) */ +static int sculpt_any_smooth_mode(const Brush *brush, + StrokeCache *cache, + int stroke_mode) +{ + return ((stroke_mode == BRUSH_STROKE_SMOOTH) || + (cache && cache->alt_smooth) || + (brush->sculpt_tool == SCULPT_TOOL_SMOOTH) || + (brush->autosmooth_factor > 0) || + ((brush->sculpt_tool == SCULPT_TOOL_MASK) && + (brush->mask_tool == BRUSH_MASK_SMOOTH))); +} + static void sculpt_stroke_modifiers_check(const bContext *C, Object *ob) { SculptSession *ss = ob->sculpt; @@ -3579,7 +3604,8 @@ static void sculpt_stroke_modifiers_check(const bContext *C, Object *ob) Sculpt *sd = CTX_data_tool_settings(C)->sculpt; Brush *brush = paint_brush(&sd->paint); - sculpt_update_mesh_elements(CTX_data_scene(C), sd, ob, brush->sculpt_tool == SCULPT_TOOL_SMOOTH); + sculpt_update_mesh_elements(CTX_data_scene(C), sd, ob, + sculpt_any_smooth_mode(brush, ss->cache, 0)); } } @@ -3689,11 +3715,7 @@ static int sculpt_brush_stroke_init(bContext *C, wmOperator *op) view3d_operator_needs_opengl(C); sculpt_brush_init_tex(scene, sd, ss); - is_smooth |= mode == BRUSH_STROKE_SMOOTH; - is_smooth |= brush->sculpt_tool == SCULPT_TOOL_SMOOTH; - is_smooth |= ((brush->sculpt_tool == SCULPT_TOOL_MASK) && - (brush->mask_tool == BRUSH_MASK_SMOOTH)); - + is_smooth = sculpt_any_smooth_mode(brush, NULL, mode); sculpt_update_mesh_elements(scene, sd, ob, is_smooth); return 1; diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index af7f3bd4aed..9827ffdc324 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -676,7 +676,7 @@ static int sound_poll(bContext *C) { Editing *ed = CTX_data_scene(C)->ed; - if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND) + if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_TYPE_SOUND_RAM) return 0; return 1; @@ -689,7 +689,7 @@ static int sound_pack_exec(bContext *C, wmOperator *op) Editing *ed = CTX_data_scene(C)->ed; bSound *sound; - if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND) + if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_TYPE_SOUND_RAM) return OPERATOR_CANCELLED; sound = ed->act_seq->sound; @@ -751,7 +751,7 @@ static int sound_unpack_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(even if (RNA_struct_property_is_set(op->ptr, "id")) return sound_unpack_exec(C, op); - if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND) + if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_TYPE_SOUND_RAM) return OPERATOR_CANCELLED; sound = ed->act_seq->sound; diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c index 3961e566f80..edec57d9e93 100644 --- a/source/blender/editors/space_action/action_draw.c +++ b/source/blender/editors/space_action/action_draw.c @@ -236,8 +236,8 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) switch (ale->type) { case ANIMTYPE_SUMMARY: { - // FIXME: hardcoded colors - reddish color from NLA - glColor4f(0.8f, 0.2f, 0.0f, 0.4f); + /* reddish color from NLA */ + UI_ThemeColor4(TH_ANIM_ACTIVE); } break; @@ -290,6 +290,18 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) else glColor4ub(col2[0], col2[1], col2[2], 0x44); glRectf(v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF, v2d->cur.xmax + EXTRA_SCROLL_PAD, (float)y + ACHANNEL_HEIGHT_HALF); } + else if (ac->datatype == ANIMCONT_MASK) { + /* TODO --- this is a copy of gpencil */ + /* frames less than one get less saturated background */ + if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x22); + else glColor4ub(col2[0], col2[1], col2[2], 0x22); + glRectf(0.0f, (float)y - ACHANNEL_HEIGHT_HALF, v2d->cur.xmin, (float)y + ACHANNEL_HEIGHT_HALF); + + /* frames one and higher get a saturated background */ + if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x44); + else glColor4ub(col2[0], col2[1], col2[2], 0x44); + glRectf(v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF, v2d->cur.xmax + EXTRA_SCROLL_PAD, (float)y + ACHANNEL_HEIGHT_HALF); + } } } @@ -340,6 +352,9 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) case ALE_GPFRAME: draw_gpl_channel(v2d, ads, ale->data, y); break; + case ALE_MASKLAY: + draw_masklay_channel(v2d, ads, ale->data, y); + break; } } } diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 0c32ebe549d..b5cd49cc15c 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -44,6 +44,7 @@ #include "DNA_gpencil_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_mask_types.h" #include "RNA_access.h" #include "RNA_define.h" @@ -64,6 +65,7 @@ #include "ED_screen.h" #include "ED_transform.h" #include "ED_markers.h" +#include "ED_mask.h" #include "WM_api.h" #include "WM_types.h" @@ -256,6 +258,19 @@ static void get_keyframe_extents(bAnimContext *ac, float *min, float *max, const *max = MAX2(*max, gpf->framenum); } } + else if (ale->datatype == ALE_MASKLAY) { + MaskLayer *masklay = ale->data; + MaskLayerShape *masklay_shape; + + /* find mask layer which is less than or equal to cframe */ + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + *min = MIN2(*min, masklay_shape->frame); + *max = MAX2(*max, masklay_shape->frame); + } + } else { FCurve *fcu = (FCurve *)ale->key_data; float tmin, tmax; @@ -476,11 +491,16 @@ static int actkeys_copy_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; /* copy keyframes */ - if (ac.datatype == ANIMCONT_GPENCIL) { + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { // FIXME... BKE_report(op->reports, RPT_ERROR, "Keyframe pasting is not available for Grease Pencil mode"); return OPERATOR_CANCELLED; } + else if (ac.datatype == ANIMCONT_MASK) { + // FIXME... + BKE_report(op->reports, RPT_ERROR, "Keyframe pasting is not available for mask mode"); + return OPERATOR_CANCELLED; + } else { if (copy_action_keys(&ac)) { BKE_report(op->reports, RPT_ERROR, "No keyframes copied to keyframes copy/paste buffer"); @@ -521,9 +541,9 @@ static int actkeys_paste_exec(bContext *C, wmOperator *op) ac.reports = op->reports; /* paste keyframes */ - if (ac.datatype == ANIMCONT_GPENCIL) { + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { // FIXME... - BKE_report(op->reports, RPT_ERROR, "Keyframe pasting is not available for Grease Pencil mode"); + BKE_report(op->reports, RPT_ERROR, "Keyframe pasting is not available for Grease Pencil or Mask mode"); return OPERATOR_CANCELLED; } else { @@ -625,7 +645,7 @@ static int actkeys_insertkey_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) return OPERATOR_CANCELLED; /* what channels to affect? */ @@ -671,7 +691,7 @@ static void duplicate_action_keys(bAnimContext *ac) int filter; /* filter data */ - if (ac->datatype == ANIMCONT_GPENCIL) + if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); else filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); @@ -681,8 +701,12 @@ static void duplicate_action_keys(bAnimContext *ac) for (ale = anim_data.first; ale; ale = ale->next) { if (ale->type == ANIMTYPE_FCURVE) duplicate_fcurve_keys((FCurve *)ale->key_data); + else if (ale->type == ANIMTYPE_GPLAYER) + ED_gplayer_frames_duplicate((bGPDlayer *)ale->data); + else if (ale->type == ANIMTYPE_MASKLAYER) + ED_masklayer_frames_duplicate((MaskLayer *)ale->data); else - duplicate_gplayer_frames((bGPDlayer *)ale->data); + BLI_assert(0); } /* free filtered list */ @@ -703,7 +727,7 @@ static int actkeys_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) duplicate_action_keys(&ac); /* validate keyframes after editing */ - if (ac.datatype != ANIMCONT_GPENCIL) + if (!ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) ANIM_editkeyframes_refresh(&ac); /* set notifier that keyframes have changed */ @@ -744,7 +768,7 @@ static void delete_action_keys(bAnimContext *ac) int filter; /* filter data */ - if (ac->datatype == ANIMCONT_GPENCIL) + if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); else filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); @@ -752,7 +776,13 @@ static void delete_action_keys(bAnimContext *ac) /* loop through filtered data and delete selected keys */ for (ale = anim_data.first; ale; ale = ale->next) { - if (ale->type != ANIMTYPE_GPLAYER) { + if (ale->type == ANIMTYPE_GPLAYER) { + ED_gplayer_frames_delete((bGPDlayer *)ale->data); + } + else if (ale->type == ANIMTYPE_MASKLAYER) { + ED_masklayer_frames_delete((MaskLayer *)ale->data); + } + else { FCurve *fcu = (FCurve *)ale->key_data; AnimData *adt = ale->adt; @@ -763,8 +793,6 @@ static void delete_action_keys(bAnimContext *ac) if ((fcu->totvert == 0) && (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0)) ANIM_fcurve_delete_from_animdata(ac, adt, fcu); } - else - delete_gplayer_frames((bGPDlayer *)ale->data); } /* free filtered list */ @@ -785,7 +813,7 @@ static int actkeys_delete_exec(bContext *C, wmOperator *UNUSED(op)) delete_action_keys(&ac); /* validate keyframes after editing */ - if (ac.datatype != ANIMCONT_GPENCIL) + if (!ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) ANIM_editkeyframes_refresh(&ac); /* set notifier that keyframes have changed */ @@ -840,7 +868,7 @@ static int actkeys_clean_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) return OPERATOR_PASS_THROUGH; /* get cleaning threshold */ @@ -907,7 +935,7 @@ static int actkeys_sample_exec(bContext *C, wmOperator *UNUSED(op)) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) return OPERATOR_PASS_THROUGH; /* sample keyframes */ @@ -1014,7 +1042,7 @@ static int actkeys_expo_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) return OPERATOR_PASS_THROUGH; /* get handle setting mode */ @@ -1085,7 +1113,7 @@ static int actkeys_ipo_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) return OPERATOR_PASS_THROUGH; /* get handle setting mode */ @@ -1165,7 +1193,7 @@ static int actkeys_handletype_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) return OPERATOR_PASS_THROUGH; /* get handle setting mode */ @@ -1236,7 +1264,7 @@ static int actkeys_keytype_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) return OPERATOR_PASS_THROUGH; /* get handle setting mode */ @@ -1359,7 +1387,7 @@ static void snap_action_keys(bAnimContext *ac, short mode) KeyframeEditFunc edit_cb; /* filter data */ - if (ac->datatype == ANIMCONT_GPENCIL) + if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT); else filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); @@ -1404,7 +1432,7 @@ static int actkeys_snap_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; // XXX... - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) return OPERATOR_PASS_THROUGH; /* get snapping mode */ @@ -1482,7 +1510,7 @@ static void mirror_action_keys(bAnimContext *ac, short mode) } /* filter data */ - if (ac->datatype == ANIMCONT_GPENCIL) + if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); else filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); @@ -1518,7 +1546,7 @@ static int actkeys_mirror_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; // XXX... - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) return OPERATOR_PASS_THROUGH; /* get mirroring mode */ diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index 0c6b0f5eb3d..539a32161e5 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -43,6 +43,7 @@ #include "DNA_gpencil_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_mask_types.h" #include "RNA_access.h" #include "RNA_define.h" @@ -55,6 +56,7 @@ #include "ED_anim_api.h" #include "ED_gpencil.h" +#include "ED_mask.h" #include "ED_keyframes_draw.h" #include "ED_keyframes_edit.h" #include "ED_markers.h" @@ -92,7 +94,7 @@ static void deselect_action_keys(bAnimContext *ac, short test, short sel) KeyframeEditFunc test_cb, sel_cb; /* determine type-based settings */ - if (ac->datatype == ANIMCONT_GPENCIL) + if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS); else filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); @@ -107,7 +109,13 @@ static void deselect_action_keys(bAnimContext *ac, short test, short sel) if (test) { for (ale = anim_data.first; ale; ale = ale->next) { if (ale->type == ANIMTYPE_GPLAYER) { - if (is_gplayer_frame_selected(ale->data)) { + if (ED_gplayer_frame_select_check(ale->data)) { + sel = SELECT_SUBTRACT; + break; + } + } + else if (ale->type == ANIMTYPE_MASKLAYER) { + if (ED_masklayer_frame_select_check(ale->data)) { sel = SELECT_SUBTRACT; break; } @@ -127,7 +135,9 @@ static void deselect_action_keys(bAnimContext *ac, short test, short sel) /* Now set the flags */ for (ale = anim_data.first; ale; ale = ale->next) { if (ale->type == ANIMTYPE_GPLAYER) - set_gplayer_frame_selection(ale->data, sel); + ED_gplayer_frame_select_set(ale->data, sel); + else if (ale->type == ANIMTYPE_MASKLAYER) + ED_masklayer_frame_select_set(ale->data, sel); else ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, sel_cb, NULL); } @@ -249,7 +259,9 @@ static void borderselect_action(bAnimContext *ac, rcti rect, short mode, short s { /* loop over data selecting */ if (ale->type == ANIMTYPE_GPLAYER) - borderselect_gplayer_frames(ale->data, rectf.xmin, rectf.xmax, selectmode); + ED_gplayer_frames_select_border(ale->data, rectf.xmin, rectf.xmax, selectmode); + else if (ale->type == ANIMTYPE_MASKLAYER) + ED_masklayer_frames_select_border(ale->data, rectf.xmin, rectf.xmax, selectmode); else ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL); } @@ -398,7 +410,10 @@ static void markers_selectkeys_between(bAnimContext *ac) ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); } else if (ale->type == ANIMTYPE_GPLAYER) { - borderselect_gplayer_frames(ale->data, min, max, SELECT_ADD); + ED_gplayer_frames_select_border(ale->data, min, max, SELECT_ADD); + } + else if (ale->type == ANIMTYPE_MASKLAYER) { + ED_masklayer_frames_select_border(ale->data, min, max, SELECT_ADD); } else { ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); @@ -432,7 +447,7 @@ static void columnselect_action_keys(bAnimContext *ac, short mode) ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); for (ale = anim_data.first; ale; ale = ale->next) - gplayer_make_cfra_list(ale->data, &ked.list, 1); + ED_gplayer_make_cfra_list(ale->data, &ked.list, 1); } else { filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/); @@ -467,7 +482,7 @@ static void columnselect_action_keys(bAnimContext *ac, short mode) /* loop through all of the keys and select additional keyframes * based on the keys found to be selected above */ - if (ac->datatype == ANIMCONT_GPENCIL) + if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE); else filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/); @@ -488,7 +503,9 @@ static void columnselect_action_keys(bAnimContext *ac, short mode) /* select elements with frame number matching cfraelem */ if (ale->type == ANIMTYPE_GPLAYER) - select_gpencil_frame(ale->data, ce->cfra, SELECT_ADD); + ED_gpencil_select_frame(ale->data, ce->cfra, SELECT_ADD); + else if (ale->type == ANIMTYPE_MASKLAYER) + ED_mask_select_frame(ale->data, ce->cfra, SELECT_ADD); else ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); } @@ -755,7 +772,7 @@ static void actkeys_select_leftright(bAnimContext *ac, short leftright, short se } /* filter data */ - if (ac->datatype == ANIMCONT_GPENCIL) + if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS); else filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); @@ -771,7 +788,9 @@ static void actkeys_select_leftright(bAnimContext *ac, short leftright, short se ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); } else if (ale->type == ANIMTYPE_GPLAYER) - borderselect_gplayer_frames(ale->data, ked.f1, ked.f2, select_mode); + ED_gplayer_frames_select_border(ale->data, ked.f1, ked.f2, select_mode); + else if (ale->type == ANIMTYPE_MASKLAYER) + ED_masklayer_frames_select_border(ale->data, ked.f1, ked.f2, select_mode); else ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); } @@ -908,7 +927,9 @@ static void actkeys_mselect_single(bAnimContext *ac, bAnimListElem *ale, short s /* select the nominated keyframe on the given frame */ if (ale->type == ANIMTYPE_GPLAYER) - select_gpencil_frame(ale->data, selx, select_mode); + ED_gpencil_select_frame(ale->data, selx, select_mode); + else if (ale->type == ANIMTYPE_MASKLAYER) + ED_mask_select_frame(ale->data, selx, select_mode); else ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL); } @@ -933,7 +954,7 @@ static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float se /* loop through all of the keys and select additional keyframes * based on the keys found to be selected above */ - if (ac->datatype == ANIMCONT_GPENCIL) + if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ | ANIMFILTER_NODUPLIS); else filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS); @@ -950,8 +971,10 @@ static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float se /* select elements with frame number matching cfra */ if (ale->type == ANIMTYPE_GPLAYER) - select_gpencil_frame(ale->key_data, selx, select_mode); - else + ED_gpencil_select_frame(ale->key_data, selx, select_mode); + else if (ale->type == ANIMTYPE_MASKLAYER) + ED_mask_select_frame(ale->key_data, selx, select_mode); + else ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); } @@ -1051,7 +1074,12 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_ bGPDlayer *gpl = (bGPDlayer *)ale->data; gpl_to_keylist(ads, gpl, &anim_keys); } - + else if (ale->type == ANIMTYPE_MASKLAYER) { + // TODO: why don't we just give masklayers key_data too? + MaskLayer *masklay = (MaskLayer *)ale->data; + mask_to_keylist(ads, masklay, &anim_keys); + } + /* start from keyframe at root of BST, traversing until we find one within the range that was clicked on */ for (ak = anim_keys.root; ak; ak = akn) { if (IN_RANGE(ak->cfra, rectf.xmin, rectf.xmax)) { @@ -1120,6 +1148,18 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_ //gpencil_layer_setactive(gpd, gpl); } } + else if (ac->datatype == ANIMCONT_MASK) { + /* deselect all other channels first */ + ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); + + /* Highlight GPencil Layer */ + if ((ale && ale->data) && (ale->type == ANIMTYPE_MASKLAYER)) { + MaskLayer *masklay = ale->data; + + masklay->flag |= MASK_LAYERFLAG_SELECT; + //gpencil_layer_setactive(gpd, gpl); + } + } } /* only select keyframes if we clicked on a valid channel and hit something */ diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index ae4020aaaba..c8660179945 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -361,7 +361,7 @@ static void action_listener(ScrArea *sa, wmNotifier *wmn) case NC_SCREEN: if (wmn->data == ND_GPENCIL) { /* only handle this event in GPencil mode for performance considerations */ - if (saction->mode == SACTCONT_GPENCIL) + if (saction->mode == SACTCONT_GPENCIL) ED_area_tag_redraw(sa); } break; @@ -405,6 +405,18 @@ static void action_listener(ScrArea *sa, wmNotifier *wmn) break; } break; + case NC_MASK: + if (saction->mode == SACTCONT_MASK) { + switch (wmn->data) { + case ND_DATA: + ED_area_tag_refresh(sa); + break; + default: /* just redrawing the view will do */ + ED_area_tag_redraw(sa); + break; + } + } + break; case NC_NODE: if (wmn->action == NA_SELECTED) { /* selection changed, so force refresh to flush (needs flag set to do syncing) */ diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 956aee84fd3..fa77249a7a1 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -62,6 +62,7 @@ #include "ED_mball.h" #include "ED_logic.h" #include "ED_clip.h" +#include "ED_mask.h" /* only call once on startup, storage is global in BKE kernel listbase */ void ED_spacetypes_init(void) @@ -111,6 +112,7 @@ void ED_spacetypes_init(void) ED_operatortypes_sound(); ED_operatortypes_render(); ED_operatortypes_logic(); + ED_operatortypes_mask(); UI_view2d_operatortypes(); UI_buttons_operatortypes(); @@ -133,6 +135,7 @@ void ED_spacetypes_init(void) ED_operatormacros_action(); ED_operatormacros_clip(); ED_operatormacros_curve(); + ED_operatormacros_mask(); /* register dropboxes (can use macros) */ spacetypes = BKE_spacetypes_list(); @@ -164,6 +167,7 @@ void ED_spacetypes_keymap(wmKeyConfig *keyconf) ED_keymap_physics(keyconf); ED_keymap_metaball(keyconf); ED_keymap_paint(keyconf); + ED_keymap_mask(keyconf); ED_marker_keymap(keyconf); UI_view2d_keymap(keyconf); diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c index 5c5c24f7bc1..cdecda63432 100644 --- a/source/blender/editors/space_buttons/buttons_texture.c +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -175,7 +175,7 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext * if (!(pinid || pinid == &scene->id)) { ob = (scene->basact) ? scene->basact->object : NULL; wrld = scene->world; - brush = paint_brush(paint_get_active(scene)); + brush = paint_brush(paint_get_active_from_context(C)); } if (ob && ob->type == OB_LAMP && !la) diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c index 18f191a46a6..ca2ae6e8461 100644 --- a/source/blender/editors/space_clip/clip_buttons.c +++ b/source/blender/editors/space_clip/clip_buttons.c @@ -168,7 +168,7 @@ void uiTemplateTrack(uiLayout *layout, PointerRNA *ptr, const char *propname) scopes->track_preview_height = (scopes->track_preview_height <= UI_UNIT_Y)?UI_UNIT_Y : scopes->track_preview_height; uiDefBut(block, TRACKPREVIEW, 0, "", rect.xmin, rect.ymin, rect.xmax - rect.xmin, - scopes->track_preview_height, scopes, 0, 0, 0, 0, ""); + scopes->track_preview_height, scopes, 0, 0, 0, 0, ""); } /********************* Marker Template ************************/ @@ -186,12 +186,13 @@ typedef struct { MovieClip *clip; MovieClipUser *user; /* user of clip */ MovieTrackingTrack *track; + MovieTrackingMarker *marker; int framenr; /* current frame number */ float marker_pos[2]; /* position of marker in pixel coords */ - float track_pat[2]; /* position and dimensions of marker pattern in pixel coords */ + float marker_pat[2]; /* position and dimensions of marker pattern in pixel coords */ float track_offset[2]; /* offset of "parenting" point */ - float track_search_pos[2], track_search[2]; /* position and dimensions of marker search in pixel coords */ + float marker_search_pos[2], marker_search[2]; /* position and dimensions of marker search in pixel coords */ int marker_flag; /* marker's flags */ } MarkerUpdateCb; @@ -238,60 +239,63 @@ static void marker_block_handler(bContext *C, void *arg_cb, int event) ok = TRUE; } else if (event == B_MARKER_PAT_DIM) { - float dim[2], pat_dim[2]; + float dim[2], pat_dim[2], pat_min[2], pat_max[2]; + float scale_x, scale_y; + int a; - sub_v2_v2v2(pat_dim, cb->track->pat_max, cb->track->pat_min); + BKE_tracking_marker_pattern_minmax(cb->marker, pat_min, pat_max); - dim[0] = cb->track_pat[0] / width; - dim[1] = cb->track_pat[1] / height; + sub_v2_v2v2(pat_dim, pat_max, pat_min); - sub_v2_v2(dim, pat_dim); - mul_v2_fl(dim, 0.5f); + dim[0] = cb->marker_pat[0] / width; + dim[1] = cb->marker_pat[1] / height; - cb->track->pat_min[0] -= dim[0]; - cb->track->pat_min[1] -= dim[1]; + scale_x = dim[0] / pat_dim[0]; + scale_y = dim[1] / pat_dim[1]; - cb->track->pat_max[0] += dim[0]; - cb->track->pat_max[1] += dim[1]; + for (a = 0; a < 4; a++) { + cb->marker->pattern_corners[a][0] *= scale_x; + cb->marker->pattern_corners[a][1] *= scale_y; + } - BKE_tracking_clamp_track(cb->track, CLAMP_PAT_DIM); + BKE_tracking_clamp_marker(cb->marker, CLAMP_PAT_DIM); ok = TRUE; } else if (event == B_MARKER_SEARCH_POS) { float delta[2], side[2]; - sub_v2_v2v2(side, cb->track->search_max, cb->track->search_min); + sub_v2_v2v2(side, cb->marker->search_max, cb->marker->search_min); mul_v2_fl(side, 0.5f); - delta[0] = cb->track_search_pos[0] / width; - delta[1] = cb->track_search_pos[1] / height; + delta[0] = cb->marker_search_pos[0] / width; + delta[1] = cb->marker_search_pos[1] / height; - sub_v2_v2v2(cb->track->search_min, delta, side); - add_v2_v2v2(cb->track->search_max, delta, side); + sub_v2_v2v2(cb->marker->search_min, delta, side); + add_v2_v2v2(cb->marker->search_max, delta, side); - BKE_tracking_clamp_track(cb->track, CLAMP_SEARCH_POS); + BKE_tracking_clamp_marker(cb->marker, CLAMP_SEARCH_POS); ok = TRUE; } else if (event == B_MARKER_SEARCH_DIM) { float dim[2], search_dim[2]; - sub_v2_v2v2(search_dim, cb->track->search_max, cb->track->search_min); + sub_v2_v2v2(search_dim, cb->marker->search_max, cb->marker->search_min); - dim[0] = cb->track_search[0] / width; - dim[1] = cb->track_search[1] / height; + dim[0] = cb->marker_search[0] / width; + dim[1] = cb->marker_search[1] / height; sub_v2_v2(dim, search_dim); mul_v2_fl(dim, 0.5f); - cb->track->search_min[0] -= dim[0]; - cb->track->search_min[1] -= dim[1]; + cb->marker->search_min[0] -= dim[0]; + cb->marker->search_min[1] -= dim[1]; - cb->track->search_max[0] += dim[0]; - cb->track->search_max[1] += dim[1]; + cb->marker->search_max[0] += dim[0]; + cb->marker->search_max[1] += dim[1]; - BKE_tracking_clamp_track(cb->track, CLAMP_SEARCH_DIM); + BKE_tracking_clamp_marker(cb->marker, CLAMP_SEARCH_DIM); ok = TRUE; } @@ -337,6 +341,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P MovieTrackingMarker *marker; MarkerUpdateCb *cb; const char *tip; + float pat_min[2], pat_max[2]; if (!ptr->data) return; @@ -366,6 +371,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P cb->clip = clip; cb->user = user; cb->track = track; + cb->marker = marker; cb->marker_flag = marker->flag; cb->framenr = user->framenr; @@ -383,7 +389,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P } else { int width, height, step, digits; - float pat_dim[2], pat_pos[2], search_dim[2], search_pos[2]; + float pat_dim[2], search_dim[2], search_pos[2]; uiLayout *col; BKE_movieclip_get_size(clip, user, &width, &height); @@ -399,19 +405,18 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P step = 100; digits = 2; - sub_v2_v2v2(pat_dim, track->pat_max, track->pat_min); - sub_v2_v2v2(search_dim, track->search_max, track->search_min); + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); - add_v2_v2v2(search_pos, track->search_max, track->search_min); - mul_v2_fl(search_pos, 0.5); + sub_v2_v2v2(pat_dim, pat_max, pat_min); + sub_v2_v2v2(search_dim, marker->search_max, marker->search_min); - add_v2_v2v2(pat_pos, track->pat_max, track->pat_min); - mul_v2_fl(pat_pos, 0.5); + add_v2_v2v2(search_pos, marker->search_max, marker->search_min); + mul_v2_fl(search_pos, 0.5); to_pixel_space(cb->marker_pos, marker->pos, width, height); - to_pixel_space(cb->track_pat, pat_dim, width, height); - to_pixel_space(cb->track_search, search_dim, width, height); - to_pixel_space(cb->track_search_pos, search_pos, width, height); + to_pixel_space(cb->marker_pat, pat_dim, width, height); + to_pixel_space(cb->marker_search, search_dim, width, height); + to_pixel_space(cb->marker_search_pos, search_pos, width, height); to_pixel_space(cb->track_offset, track->offset, width, height); cb->marker_flag = marker->flag; @@ -447,19 +452,19 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P -10*height, 10.0*height, step, digits, "Y-offset to parenting point"); uiDefBut(block, LABEL, 0, "Pattern Area:", 0, 114, 300, 19, NULL, 0, 0, 0, 0, ""); - uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Width:", 10, 95, 300, 19, &cb->track_pat[0], 3.0f, + uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Width:", 10, 95, 300, 19, &cb->marker_pat[0], 3.0f, 10.0*width, step, digits, "Width of marker's pattern in screen coordinates"); - uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Height:", 10, 76, 300, 19, &cb->track_pat[1], 3.0f, + uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Height:", 10, 76, 300, 19, &cb->marker_pat[1], 3.0f, 10.0*height, step, digits, "Height of marker's pattern in screen coordinates"); uiDefBut(block, LABEL, 0, "Search Area:", 0, 57, 300, 19, NULL, 0, 0, 0, 0, ""); - uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "X:", 10, 38, 145, 19, &cb->track_search_pos[0], + uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "X:", 10, 38, 145, 19, &cb->marker_search_pos[0], -width, width, step, digits, "X-position of search at frame relative to marker's position"); - uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "Y:", 165, 38, 145, 19, &cb->track_search_pos[1], + uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "Y:", 165, 38, 145, 19, &cb->marker_search_pos[1], -height, height, step, digits, "X-position of search at frame relative to marker's position"); - uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Width:", 10, 19, 300, 19, &cb->track_search[0], 3.0f, + uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Width:", 10, 19, 300, 19, &cb->marker_search[0], 3.0f, 10.0*width, step, digits, "Width of marker's search in screen soordinates"); - uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Height:", 10, 0, 300, 19, &cb->track_search[1], 3.0f, + uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Height:", 10, 0, 300, 19, &cb->marker_search[1], 3.0f, 10.0*height, step, digits, "Height of marker's search in screen soordinates"); uiBlockEndAlign(block); diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index e264d7f3885..67609fee653 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -25,7 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/editors/space_clip/clip_graph_draw.c +/** \file blender/editors/space_clip/clip_dopesheet_draw.c * \ingroup spclip */ @@ -200,8 +200,8 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) /* tracked segments */ for (i = 0; i < channel->tot_segment; i++) { - int start_frame = channel->segments[2 * i]; - int end_frame = channel->segments[2 * i + 1]; + int start_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i]); + int end_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i + 1]); if (sel) glColor4fv(selected_strip); @@ -224,8 +224,11 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) while (i < track->markersnr) { MovieTrackingMarker *marker = &track->markers[i]; - if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0) - draw_keyframe_shape(marker->framenr, y, xscale, yscale, sel, alpha); + if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0) { + int framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr); + + draw_keyframe_shape(framenr, y, xscale, yscale, sel, alpha); + } i++; } diff --git a/source/blender/editors/space_clip/clip_dopesheet_ops.c b/source/blender/editors/space_clip/clip_dopesheet_ops.c index 0fd17523425..914e82472bb 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_ops.c +++ b/source/blender/editors/space_clip/clip_dopesheet_ops.c @@ -25,7 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/editors/space_clip/clip_graph_ops.c +/** \file blender/editors/space_clip/clip_dopesheet_ops.c * \ingroup spclip */ @@ -93,6 +93,10 @@ static int dopesheet_select_channel_exec(bContext *C, wmOperator *op) track->flag ^= TRACK_DOPE_SEL; else track->flag |= TRACK_DOPE_SEL; + + if (track->flag & TRACK_DOPE_SEL) { + tracking->act_track = track; + } } else if (!extend) track->flag &= ~TRACK_DOPE_SEL; diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index c00359f0f32..2e16a9095f0 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -33,12 +33,14 @@ #include "DNA_movieclip_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" /* SELECT */ +#include "DNA_mask_types.h" #include "MEM_guardedalloc.h" #include "BKE_context.h" #include "BKE_movieclip.h" #include "BKE_tracking.h" +#include "BKE_mask.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -124,7 +126,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc if (act_track) { MovieTrackingTrack *track = act_track; - for (i = sfra, a = 0; i <= efra; i++) { + for (i = sfra - clip->start_frame + 1, a = 0; i <= efra - clip->start_frame + 1; i++) { int framenr; MovieTrackingMarker *marker; @@ -153,7 +155,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc else glColor4ub(255, 255, 0, 96); - glRecti((i - sfra) * framelen, 0, (i - sfra + 1)*framelen, 4); + glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 4); } } } @@ -181,7 +183,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc } if (!ok) - glRecti((i - sfra) * framelen, 0, (i - sfra + 1) * framelen, 8); + glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 8); } } @@ -194,6 +196,32 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc glRecti(x, 0, x + framelen, 8); clip_draw_curfra_label(sc, x, 8.0f); + + /* movie clip animation */ + if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask) { + MaskLayer *masklay = BKE_mask_layer_active(sc->mask); + if (masklay) { + MaskLayerShape *masklay_shape; + + glColor4ub(255, 175, 0, 255); + glBegin(GL_LINES); + + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + i = masklay_shape->frame; + + /* glRecti((i - sfra) * framelen, 0, (i - sfra + 1) * framelen, 4); */ + + /* use a line so we always see the keyframes */ + glVertex2i((i - sfra) * framelen, 0); + glVertex2i((i - sfra) * framelen, (i == CFRA) ? 22 : 10); + } + + glEnd(); + } + } } static void draw_movieclip_notes(SpaceClip *sc, ARegion *ar) @@ -310,17 +338,17 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin int count = sc->path_length; int i, a, b, curindex = -1; float path[102][2]; - int tiny = sc->flag & SC_SHOW_TINY_MARKER, framenr; + int tiny = sc->flag & SC_SHOW_TINY_MARKER, framenr, start_frame; MovieTrackingMarker *marker; if (count == 0) return; - marker = BKE_tracking_get_marker(track, sc->user.framenr); - if (marker->framenr != sc->user.framenr || marker->flag & MARKER_DISABLED) - return; + start_frame = framenr = ED_space_clip_clip_framenr(sc); - framenr = marker->framenr; + marker = BKE_tracking_get_marker(track, framenr); + if (marker->framenr != framenr || marker->flag & MARKER_DISABLED) + return; a = count; i = framenr - 1; @@ -334,7 +362,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin add_v2_v2v2(path[--a], marker->pos, track->offset); ED_clip_point_undistorted_pos(sc, path[a], path[a]); - if (marker->framenr == sc->user.framenr) + if (marker->framenr == start_frame) curindex = a; } else { @@ -353,7 +381,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin break; if (marker->framenr == i) { - if (marker->framenr == sc->user.framenr) + if (marker->framenr == start_frame) curindex = b; add_v2_v2v2(path[b++], marker->pos, track->offset); @@ -428,14 +456,17 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT if ((marker->flag & MARKER_DISABLED) == 0) { float pos[2]; - rctf r; + float p[2]; - BLI_init_rctf(&r, track->pat_min[0], track->pat_max[0], track->pat_min[1], track->pat_max[1]); add_v2_v2v2(pos, marker->pos, track->offset); ED_clip_point_undistorted_pos(sc, pos, pos); - if (BLI_in_rctf(&r, pos[0] - marker_pos[0], pos[1] - marker_pos[1])) { + sub_v2_v2v2(p, pos, marker_pos); + + if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1], + marker->pattern_corners[2], marker->pattern_corners[3])) + { if (tiny) glPointSize(3.0f); else glPointSize(4.0f); glBegin(GL_POINTS); @@ -471,10 +502,10 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT if (sc->flag & SC_SHOW_MARKER_PATTERN) { glBegin(GL_LINE_LOOP); - glVertex2f(track->pat_min[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_max[1]); - glVertex2f(track->pat_min[0], track->pat_max[1]); + glVertex2fv(marker->pattern_corners[0]); + glVertex2fv(marker->pattern_corners[1]); + glVertex2fv(marker->pattern_corners[2]); + glVertex2fv(marker->pattern_corners[3]); glEnd(); } @@ -482,10 +513,10 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0); if (sc->flag & SC_SHOW_MARKER_SEARCH && show_search) { glBegin(GL_LINE_LOOP); - glVertex2f(track->search_min[0], track->search_min[1]); - glVertex2f(track->search_max[0], track->search_min[1]); - glVertex2f(track->search_max[0], track->search_max[1]); - glVertex2f(track->search_min[0], track->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_max[1]); glEnd(); } glPopMatrix(); @@ -528,8 +559,7 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra /* marker position and offset position */ if ((track->flag & SELECT) == sel && (marker->flag & MARKER_DISABLED) == 0) { - float pos[2]; - rctf r; + float pos[2], p[2]; if (track->flag & TRACK_LOCKED) { if (act) @@ -546,11 +576,14 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra glColor3fv(col); } - BLI_init_rctf(&r, track->pat_min[0], track->pat_max[0], track->pat_min[1], track->pat_max[1]); add_v2_v2v2(pos, marker->pos, track->offset); ED_clip_point_undistorted_pos(sc, pos, pos); - if (BLI_in_rctf(&r, pos[0] - marker_pos[0], pos[1] - marker_pos[1])) { + sub_v2_v2v2(p, pos, marker_pos); + + if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1], + marker->pattern_corners[2], marker->pattern_corners[3])) + { if (!tiny) glPointSize(2.0f); @@ -623,10 +656,10 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra } glBegin(GL_LINE_LOOP); - glVertex2f(track->pat_min[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_max[1]); - glVertex2f(track->pat_min[0], track->pat_max[1]); + glVertex2fv(marker->pattern_corners[0]); + glVertex2fv(marker->pattern_corners[1]); + glVertex2fv(marker->pattern_corners[2]); + glVertex2fv(marker->pattern_corners[3]); glEnd(); } @@ -656,70 +689,82 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra } glBegin(GL_LINE_LOOP); - glVertex2f(track->search_min[0], track->search_min[1]); - glVertex2f(track->search_max[0], track->search_min[1]); - glVertex2f(track->search_max[0], track->search_max[1]); - glVertex2f(track->search_min[0], track->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_max[1]); glEnd(); } - /* pyramid */ - if (sel && TRACK_VIEW_SELECTED(sc, track) && - (track->tracker == TRACKER_KLT) && - (marker->flag & MARKER_DISABLED) == 0) - { - if (track->flag & TRACK_LOCKED) { - if (act) - UI_ThemeColor(TH_ACT_MARKER); - else if (track->pat_flag & SELECT) - UI_ThemeColorShade(TH_LOCK_MARKER, 64); - else UI_ThemeColor(TH_LOCK_MARKER); - } - else if (marker->flag & MARKER_DISABLED) { - if (act) - UI_ThemeColor(TH_ACT_MARKER); - else if (track->pat_flag & SELECT) - UI_ThemeColorShade(TH_DIS_MARKER, 128); - else UI_ThemeColor(TH_DIS_MARKER); - } - else { - if (track->pat_flag & SELECT) - glColor3fv(scol); - else - glColor3fv(col); - } - - { - int i = 0; - glPushMatrix(); - glEnable(GL_LINE_STIPPLE); - for (i = 1; i < track->pyramid_levels; ++i) { - glScalef(2.0f, 2.0f, 1.0); - } - /* only draw a pattern for the coarsest level */ - glBegin(GL_LINE_LOOP); - glVertex2f(track->pat_min[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_max[1]); - glVertex2f(track->pat_min[0], track->pat_max[1]); - glEnd(); - glDisable(GL_LINE_STIPPLE); - glPopMatrix(); - } - } - if (tiny) glDisable(GL_LINE_STIPPLE); glPopMatrix(); } +static float get_shortest_pattern_side(MovieTrackingMarker *marker) +{ + int i, next; + float len = FLT_MAX; + + for (i = 0; i < 4; i++) { + float cur_len; + + next = (i + 1) % 4; + + cur_len = len_v2v2(marker->pattern_corners[i], marker->pattern_corners[next]); + + len = MIN2(cur_len, len); + } + + return len; +} + +static void draw_marker_slide_square(float x, float y, float dx, float dy, int outline, float px[2]) +{ + float tdx, tdy; + + tdx = dx; + tdy = dy; + + if (outline) { + tdx += px[0]; + tdy += px[1]; + } + + glBegin(GL_QUADS); + glVertex3f(x - tdx, y + tdy, 0.0f); + glVertex3f(x + tdx, y + tdy, 0.0f); + glVertex3f(x + tdx, y - tdy, 0.0f); + glVertex3f(x - tdx, y - tdy, 0.0f); + glEnd(); +} + +static void draw_marker_slide_triangle(float x, float y, float dx, float dy, int outline, float px[2]) +{ + float tdx, tdy; + + tdx = dx * 2.0f; + tdy = dy * 2.0f; + + if (outline) { + tdx += px[0]; + tdy += px[1]; + } + + glBegin(GL_TRIANGLES); + glVertex3f(x, y, 0.0f); + glVertex3f(x - tdx, y, 0.0f); + glVertex3f(x, y + tdy, 0.0f); + glEnd(); +} + static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, float marker_pos[2], int outline, int sel, int act, int width, int height) { - float x, y, dx, dy, patdx, patdy, searchdx, searchdy, tdx, tdy; + float dx, dy, patdx, patdy, searchdx, searchdy; int tiny = sc->flag & SC_SHOW_TINY_MARKER; - float col[3], scol[3], px[2]; + float col[3], scol[3], px[2], side; if ((tiny && outline) || (marker->flag & MARKER_DISABLED)) return; @@ -740,11 +785,12 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo dx = 6.0f / width / sc->zoom; dy = 6.0f / height / sc->zoom; - patdx = MIN2(dx * 2.0f / 3.0f, (track->pat_max[0] - track->pat_min[0]) / 6.0f); - patdy = MIN2(dy * 2.0f / 3.0f, (track->pat_max[1] - track->pat_min[1]) / 6.0f); + side = get_shortest_pattern_side(marker); + patdx = MIN2(dx * 2.0f / 3.0f, side / 6.0f); + patdy = MIN2(dy * 2.0f / 3.0f, side * width / height / 6.0f); - searchdx = MIN2(dx, (track->search_max[0] - track->search_min[0]) / 6.0f); - searchdy = MIN2(dy, (track->search_max[1] - track->search_min[1]) / 6.0f); + searchdx = MIN2(dx, (marker->search_max[0] - marker->search_min[0]) / 6.0f); + searchdy = MIN2(dy, (marker->search_max[1] - marker->search_min[1]) / 6.0f); px[0] = 1.0f / sc->zoom / width / sc->scale; px[1] = 1.0f / sc->zoom / height / sc->scale; @@ -758,41 +804,10 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo } /* search offset square */ - x = track->search_min[0]; - y = track->search_max[1]; - - tdx = searchdx; - tdy = searchdy; - - if (outline) { - tdx += px[0]; - tdy += px[1]; - } - - glBegin(GL_QUADS); - glVertex3f(x - tdx, y + tdy, 0); - glVertex3f(x + tdx, y + tdy, 0); - glVertex3f(x + tdx, y - tdy, 0); - glVertex3f(x - tdx, y - tdy, 0); - glEnd(); + draw_marker_slide_square(marker->search_min[0], marker->search_max[1], searchdx, searchdy, outline, px); /* search re-sizing triangle */ - x = track->search_max[0]; - y = track->search_min[1]; - - tdx = searchdx * 2.0f; - tdy = searchdy * 2.0f; - - if (outline) { - tdx += px[0]; - tdy += px[1]; - } - - glBegin(GL_TRIANGLES); - glVertex3f(x, y, 0); - glVertex3f(x - tdx, y, 0); - glVertex3f(x, y + tdy, 0); - glEnd(); + draw_marker_slide_triangle(marker->search_max[0], marker->search_min[1], searchdx, searchdy, outline, px); } if ((sc->flag & SC_SHOW_MARKER_PATTERN) && ((track->pat_flag & SELECT) == sel || outline)) { @@ -803,42 +818,26 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo glColor3fv(col); } - /* pattern offset square */ - x = track->pat_min[0]; - y = track->pat_max[1]; + /* XXX: need to be real check if affine tracking is enabled, but for now not + * sure how to do this, so assume affine tracker is always enabled */ + if (TRUE) { + int i; - tdx = patdx; - tdy = patdy; - - if (outline) { - tdx += px[0]; - tdy += px[1]; + /* pattern's corners sliding squares */ + for (i = 0; i < 4; i++) { + draw_marker_slide_square(marker->pattern_corners[i][0], marker->pattern_corners[i][1], + patdx / 1.5f, patdy / 1.5f, outline, px); + } } + else { + /* pattern offset square */ + draw_marker_slide_square(marker->pattern_corners[3][0], marker->pattern_corners[3][1], + patdx, patdy, outline, px); - glBegin(GL_QUADS); - glVertex3f(x - tdx, y + tdy, 0); - glVertex3f(x + tdx, y + tdy, 0); - glVertex3f(x + tdx, y - tdy, 0); - glVertex3f(x - tdx, y - tdy, 0); - glEnd(); - - /* pattern re-sizing triangle */ - x = track->pat_max[0]; - y = track->pat_min[1]; - - tdx = patdx*2.0f; - tdy = patdy*2.0f; - - if (outline) { - tdx += px[0]; - tdy += px[1]; + /* pattern re-sizing triangle */ + draw_marker_slide_triangle(marker->pattern_corners[1][0], marker->pattern_corners[1][1], + patdx, patdy, outline, px); } - - glBegin(GL_TRIANGLES); - glVertex3f(x, y, 0); - glVertex3f(x - tdx, y, 0); - glVertex3f(x, y + tdy, 0); - glEnd(); } glPopMatrix(); @@ -877,12 +876,15 @@ static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTra if ((sc->flag & SC_SHOW_MARKER_SEARCH) && ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) { - dx = track->search_min[0]; - dy = track->search_min[1]; + dx = marker->search_min[0]; + dy = marker->search_min[1]; } else if (sc->flag & SC_SHOW_MARKER_PATTERN) { - dx = track->pat_min[0]; - dy = track->pat_min[1]; + float pat_min[2], pat_max[2]; + + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + dx = pat_min[0]; + dy = pat_min[1]; } pos[0] = (marker_pos[0] + dx) * width; @@ -896,7 +898,7 @@ static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTra if (marker->flag & MARKER_DISABLED) strcpy(state, "disabled"); - else if (marker->framenr != sc->user.framenr) + else if (marker->framenr != ED_space_clip_clip_framenr(sc)) strcpy(state, "estimated"); else if (marker->flag & MARKER_TRACKED) strcpy(state, "tracked"); @@ -944,7 +946,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, ListBase *tracksbase = BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track, *act_track; MovieTrackingMarker *marker; - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); int undistort = sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT; float *marker_pos = NULL, *fp, *active_pos = NULL, cur_pos[2]; @@ -1175,8 +1177,10 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, int i, j, a; float pos[2], tpos[2], grid[11][11][2]; MovieTracking *tracking = &clip->tracking; + bGPdata *gpd = NULL; float aspy = 1.0f / tracking->camera.pixel_aspect; float dx = (float)width / n, dy = (float)height / n * aspy; + float offsx = 0.0f, offsy = 0.0f; if (sc->mode != SC_MODE_DISTORTION) return; @@ -1284,8 +1288,26 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, } } - if (sc->flag & SC_MANUAL_CALIBRATION && clip->gpd) { - bGPDlayer *layer = clip->gpd->layers.first; + if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { + MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking); + + if (track) { + int framenr = sc->user.framenr; + MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); + + offsx = marker->pos[0]; + offsy = marker->pos[1]; + + gpd = track->gpd; + } + + } + else { + gpd = clip->gpd; + } + + if (sc->flag & SC_MANUAL_CALIBRATION && gpd) { + bGPDlayer *layer = gpd->layers.first; while (layer) { bGPDframe *frame = layer->frames.first; @@ -1310,11 +1332,11 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, float npos[2], dpos[2], len; int steps; - pos[0] = stroke->points[i].x * width; - pos[1] = stroke->points[i].y * height * aspy; + pos[0] = (stroke->points[i].x + offsx) * width; + pos[1] = (stroke->points[i].y + offsy) * height * aspy; - npos[0] = stroke->points[i + 1].x * width; - npos[1] = stroke->points[i + 1].y * height * aspy; + npos[0] = (stroke->points[i + 1].x + offsx) * width; + npos[1] = (stroke->points[i + 1].y + offsy) * height * aspy; len = len_v2v2(pos, npos); steps = ceil(len / 5.0f); @@ -1339,7 +1361,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, } else if (stroke->totpoints == 1) { glBegin(GL_POINTS); - glVertex2f(stroke->points[0].x, stroke->points[0].y); + glVertex2f(stroke->points[0].x + offsx, stroke->points[0].y + offsy); glEnd(); } } @@ -1429,7 +1451,6 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); - ImBuf *ibuf; if (!clip) return; @@ -1438,16 +1459,23 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d) /* if manual calibration is used then grease pencil data is already * drawed in draw_distortion */ if ((sc->flag & SC_MANUAL_CALIBRATION) == 0 || sc->mode != SC_MODE_DISTORTION) { - ibuf = ED_space_clip_get_buffer(sc); + glPushMatrix(); + glMultMatrixf(sc->unistabmat); - if (ibuf) { - glPushMatrix(); - glMultMatrixf(sc->unistabmat); - draw_gpencil_2dimage(C, ibuf); + if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { + MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking); - IMB_freeImBuf(ibuf); - glPopMatrix(); + if (track) { + int framenr = sc->user.framenr; + MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); + + glTranslatef(marker->pos[0], marker->pos[1], 0.0f); + } } + + draw_gpencil_2dimage(C); + + glPopMatrix(); } } else { diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index a477a7435fd..504d96df072 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -34,10 +34,12 @@ #include "MEM_guardedalloc.h" #include "BKE_main.h" +#include "BKE_mask.h" #include "BKE_movieclip.h" #include "BKE_context.h" #include "BKE_tracking.h" +#include "DNA_mask_types.h" #include "DNA_object_types.h" /* SELECT */ #include "BLI_utildefines.h" @@ -94,33 +96,26 @@ int ED_space_clip_tracking_poll(bContext *C) return FALSE; } -int ED_space_clip_tracking_size_poll(bContext *C) +int ED_space_clip_maskedit_poll(bContext *C) { - if (ED_space_clip_tracking_poll(C)) { - MovieClip *clip = CTX_data_edit_movieclip(C); - - if (clip) { - SpaceClip *sc = CTX_wm_space_clip(C); - int width, height; - - BKE_movieclip_get_size(clip, &sc->user, &width, &height); + SpaceClip *sc = CTX_wm_space_clip(C); - return width > 0 && height > 0; - } + if (sc && sc->clip) { + return ED_space_clip_show_maskedit(sc); } return FALSE; } -int ED_space_clip_tracking_frame_poll(bContext *C) +int ED_space_clip_maskedit_mask_poll(bContext *C) { - if (ED_space_clip_tracking_poll(C)) { + if (ED_space_clip_maskedit_poll(C)) { MovieClip *clip = CTX_data_edit_movieclip(C); if (clip) { - SpaceClip *sc = CTX_wm_space_clip(C); + SpaceClip *sc= CTX_wm_space_clip(C); - return BKE_movieclip_has_frame(clip, &sc->user); + return sc->mask != NULL; } } @@ -170,6 +165,11 @@ MovieClip *ED_space_clip(SpaceClip *sc) return sc->clip; } +Mask *ED_space_clip_mask(SpaceClip *sc) +{ + return sc->mask; +} + ImBuf *ED_space_clip_get_buffer(SpaceClip *sc) { if (sc->clip) { @@ -214,6 +214,51 @@ void ED_space_clip_size(SpaceClip *sc, int *width, int *height) } } +void ED_space_clip_mask_size(SpaceClip *sc, int *width, int *height) +{ + /* quite the same as ED_space_clip_size, but it also runs aspect correction on output resolution + * this is needed because mask should be rasterized with exactly the same resolution as + * currently displaying frame and it doesn't have access to aspect correction currently + * used for display. (sergey) + */ + + if (!sc->mask) { + *width = 0; + *height = 0; + } else { + float aspx, aspy; + + ED_space_clip_size(sc, width, height); + ED_space_clip_aspect(sc, &aspx, &aspy); + + *width *= aspx; + *height *= aspy; + } +} + +void ED_space_clip_mask_aspect(SpaceClip *sc, float *aspx, float *aspy) +{ + int w, h; + + ED_space_clip_aspect(sc, aspx, aspy); + ED_space_clip_size(sc, &w, &h); + + /* now this is not accounted for! */ +#if 0 + *aspx *= (float)w; + *aspy *= (float)h; +#endif + + if (*aspx < *aspy) { + *aspy= *aspy / *aspx; + *aspx= 1.0f; + } + else { + *aspx= *aspx / *aspy; + *aspy= 1.0f; + } +} + void ED_space_clip_zoom(SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy) { int width, height; @@ -234,6 +279,33 @@ void ED_space_clip_aspect(SpaceClip *sc, float *aspx, float *aspy) *aspx = *aspy = 1.0f; } +void ED_space_clip_aspect_dimension_aware(SpaceClip *sc, float *aspx, float *aspy) +{ + int w, h; + + /* most of tools does not require aspect to be returned with dimensions correction + * due to they're invariant to this stuff, but some transformation tools like rotation + * should be aware of aspect correction caused by different resolution in different + * directions. + * mainly this is sued for transformation stuff + */ + + ED_space_clip_aspect(sc, aspx, aspy); + ED_space_clip_size(sc, &w, &h); + + *aspx *= (float)w; + *aspy *= (float)h; + + if (*aspx < *aspy) { + *aspy= *aspy / *aspx; + *aspx= 1.0f; + } + else { + *aspx= *aspx / *aspy; + *aspy= 1.0f; + } +} + void ED_clip_update_frame(const Main *mainp, int cfra) { wmWindowManager *wm; @@ -257,6 +329,14 @@ void ED_clip_update_frame(const Main *mainp, int cfra) } } +/* return current frame number in clip space */ +int ED_space_clip_clip_framenr(SpaceClip *sc) +{ + MovieClip *clip = ED_space_clip(sc); + + return BKE_movieclip_remap_scene_to_clip_frame(clip, sc->user.framenr); +} + static int selected_boundbox(SpaceClip *sc, float min[2], float max[2]) { MovieClip *clip = ED_space_clip(sc); @@ -439,7 +519,10 @@ typedef struct SpaceClipDrawContext { struct ImBuf *texture_ibuf; /* image buffer for which texture was created */ int image_width, image_height; /* image width and height for which texture was created */ unsigned last_texture; /* ID of previously used texture, so it'll be restored after clip drawing */ - int framenr; + + /* fields to check if cache is still valid */ + int framenr, start_frame; + short render_size, render_flag; } SpaceClipDrawContext; int ED_space_clip_texture_buffer_supported(SpaceClip *sc) @@ -477,6 +560,9 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf) * so not changed image buffer pointer means unchanged image content */ need_rebind |= context->texture_ibuf != ibuf; need_rebind |= context->framenr != sc->user.framenr; + need_rebind |= context->render_size != sc->user.render_size; + need_rebind |= context->render_flag != sc->user.render_flag; + need_rebind |= context->start_frame != clip->start_frame; if (need_rebind) { int width = ibuf->x, height = ibuf->y; @@ -531,6 +617,9 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf) context->image_width = ibuf->x; context->image_height = ibuf->y; context->framenr = sc->user.framenr; + context->render_size = sc->user.render_size; + context->render_flag = sc->user.render_flag; + context->start_frame = clip->start_frame; } else { /* displaying exactly the same image which was loaded t oa texture, @@ -562,6 +651,8 @@ void ED_space_clip_free_texture_buffer(SpaceClip *sc) } } +/* ******** masking editing related functions ******** */ + int ED_space_clip_show_trackedit(SpaceClip *sc) { if (sc) { @@ -570,3 +661,25 @@ int ED_space_clip_show_trackedit(SpaceClip *sc) return FALSE; } + +int ED_space_clip_show_maskedit(SpaceClip *sc) +{ + if (sc) { + return sc->mode == SC_MODE_MASKEDIT; + } + + return FALSE; +} + +void ED_space_clip_set_mask(bContext *C, SpaceClip *sc, Mask *mask) +{ + sc->mask = mask; + + if (sc->mask && sc->mask->id.us==0) { + sc->clip->id.us = 1; + } + + if (C) { + WM_event_add_notifier(C, NC_MASK|NA_SELECTED, mask); + } +} diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c index 853a7d7cad1..8d30242c128 100644 --- a/source/blender/editors/space_clip/clip_graph_draw.c +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -88,9 +88,9 @@ static void draw_curve_knot(float x, float y, float xscale, float yscale, float } static void tracking_segment_point_cb(void *UNUSED(userdata), MovieTrackingTrack *UNUSED(track), - MovieTrackingMarker *marker, int UNUSED(coord), float val) + MovieTrackingMarker *UNUSED(marker), int UNUSED(coord), int scene_framenr, float val) { - glVertex2f(marker->framenr, val); + glVertex2f(scene_framenr, val); } void tracking_segment_start_cb(void *userdata, MovieTrackingTrack *track, int coord) @@ -123,7 +123,7 @@ void tracking_segment_end_cb(void *UNUSED(userdata)) } static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track, - MovieTrackingMarker *marker, int coord, float val) + MovieTrackingMarker *marker, int coord, int scene_framenr, float val) { struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } *data = userdata; int sel = 0, sel_flag; @@ -140,7 +140,7 @@ static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track, else UI_ThemeColor(TH_HANDLE_VERTEX); - draw_curve_knot(marker->framenr, val, data->xscale, data->yscale, data->hsize); + draw_curve_knot(scene_framenr, val, data->xscale, data->yscale, data->hsize); } } diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c index 10692ada5d9..79e199a8f06 100644 --- a/source/blender/editors/space_clip/clip_graph_ops.c +++ b/source/blender/editors/space_clip/clip_graph_ops.c @@ -109,10 +109,11 @@ typedef struct { } MouseSelectUserData; static void find_nearest_tracking_segment_cb(void *userdata, MovieTrackingTrack *track, - MovieTrackingMarker *marker, int coord, float val) + MovieTrackingMarker *UNUSED(marker), + int coord, int scene_framenr, float val) { MouseSelectUserData *data = userdata; - float co[2] = {marker->framenr, val}; + float co[2] = {scene_framenr, val}; if (data->has_prev) { float d = dist_to_line_segment_v2(data->mouse_co, data->prev_co, co); @@ -137,14 +138,14 @@ void find_nearest_tracking_segment_end_cb(void *userdata) } static void find_nearest_tracking_knot_cb(void *userdata, MovieTrackingTrack *track, - MovieTrackingMarker *marker, int coord, float val) + MovieTrackingMarker *marker, int coord, int scene_framenr, float val) { MouseSelectUserData *data = userdata; - float dx = marker->framenr - data->mouse_co[0], dy = val - data->mouse_co[1]; + float dx = scene_framenr - data->mouse_co[0], dy = val - data->mouse_co[1]; float d = dx * dx + dy * dy; if (data->marker == NULL || d < data->min_dist) { - float co[2] = {marker->framenr, val}; + float co[2] = {scene_framenr, val}; data->track = track; data->marker = marker; @@ -308,11 +309,11 @@ typedef struct BorderSelectuserData { } BorderSelectuserData; static void border_select_cb(void *userdata, MovieTrackingTrack *UNUSED(track), - MovieTrackingMarker *marker, int coord, float val) + MovieTrackingMarker *marker, int coord, int scene_framenr, float val) { BorderSelectuserData *data = (BorderSelectuserData *) userdata; - if (BLI_in_rctf(&data->rect, marker->framenr, val)) { + if (BLI_in_rctf(&data->rect, scene_framenr, val)) { int flag = 0; if (coord == 0) @@ -532,7 +533,7 @@ typedef struct { } ViewAllUserData; static void view_all_cb(void *userdata, MovieTrackingTrack *UNUSED(track), MovieTrackingMarker *UNUSED(marker), - int UNUSED(coord), float val) + int UNUSED(coord), int UNUSED(scene_framenr), float val) { ViewAllUserData *data = (ViewAllUserData *) userdata; diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h index 00105fb8561..6908e488157 100644 --- a/source/blender/editors/space_clip/clip_intern.h +++ b/source/blender/editors/space_clip/clip_intern.h @@ -110,12 +110,12 @@ void ED_clip_tool_props_register(struct ARegionType *art); /* clip_utils.c */ void clip_graph_tracking_values_iterate_track(struct SpaceClip *sc, struct MovieTrackingTrack *track, void *userdata, - void (*func) (void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, float val), + void (*func) (void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start) (void *userdata, struct MovieTrackingTrack *track, int coord), void (*segment_end) (void *userdata)); void clip_graph_tracking_values_iterate(struct SpaceClip *sc, void *userdata, - void (*func) (void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, float val), + void (*func) (void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start) (void *userdata, struct MovieTrackingTrack *track, int coord), void (*segment_end) (void *userdata)); diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index 4142c30d825..6b69f316880 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -64,7 +64,7 @@ #include "clip_intern.h" // own include void clip_graph_tracking_values_iterate_track(SpaceClip *sc, MovieTrackingTrack *track, void *userdata, - void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, float val), + void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start) (void *userdata, MovieTrackingTrack *track, int coord), void (*segment_end) (void *userdata)) { @@ -104,8 +104,11 @@ void clip_graph_tracking_values_iterate_track(SpaceClip *sc, MovieTrackingTrack val = (marker->pos[coord] - prevval) * ((coord == 0) ? (width) : (height)); val /= marker->framenr - prevfra; - if (func) - func(userdata, track, marker, coord, val); + if (func) { + int scene_framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr); + + func(userdata, track, marker, coord, scene_framenr, val); + } prevval = marker->pos[coord]; prevfra = marker->framenr; @@ -119,7 +122,7 @@ void clip_graph_tracking_values_iterate_track(SpaceClip *sc, MovieTrackingTrack } void clip_graph_tracking_values_iterate(SpaceClip *sc, void *userdata, - void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, float val), + void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start) (void *userdata, MovieTrackingTrack *track, int coord), void (*segment_end) (void *userdata)) { diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index a6fda200ff4..54724881e37 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -33,7 +33,9 @@ #include <stdio.h> #include "DNA_scene_types.h" +#include "DNA_mask_types.h" #include "DNA_movieclip_types.h" +#include "DNA_view3d_types.h" /* for pivot point */ #include "MEM_guardedalloc.h" @@ -49,6 +51,8 @@ #include "IMB_imbuf_types.h" +#include "ED_mask.h" +#include "ED_space_api.h" #include "ED_screen.h" #include "ED_clip.h" #include "ED_transform.h" @@ -237,6 +241,7 @@ static SpaceLink *clip_new(const bContext *C) sc->zoom = 1.0f; sc->path_length = 20; sc->scopes.track_preview_height = 120; + sc->around = V3D_LOCAL; /* header */ ar = MEM_callocN(sizeof(ARegion), "header for clip"); @@ -301,6 +306,9 @@ static void clip_free(SpaceLink *sl) if (sc->scopes.track_preview) IMB_freeImBuf(sc->scopes.track_preview); + if (sc->scopes.track_search) + IMB_freeImBuf(sc->scopes.track_search); + ED_space_clip_free_texture_buffer(sc); } @@ -318,6 +326,7 @@ static SpaceLink *clip_duplicate(SpaceLink *sl) SpaceClip *scn = MEM_dupallocN(sl); /* clear or remove stuff from old */ + scn->scopes.track_search = NULL; scn->scopes.track_preview = NULL; scn->scopes.ok = FALSE; scn->draw_context = NULL; @@ -361,6 +370,24 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn) break; } break; + case NC_MASK: + switch (wmn->data) { + case ND_SELECT: + case ND_DATA: + case ND_DRAW: + ED_area_tag_redraw(sa); + break; + } + switch (wmn->action) { + case NA_SELECTED: + clip_scopes_tag_refresh(sa); + ED_area_tag_redraw(sa); + break; + case NA_EDITED: + ED_area_tag_redraw(sa); + break; + } + break; case NC_GEOM: switch (wmn->data) { case ND_SELECT: @@ -369,9 +396,12 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn) break; } break; - case NC_SCREEN: - if (wmn->data == ND_ANIMPLAY) { - ED_area_tag_redraw(sa); + case NC_SCREEN: + switch (wmn->data) { + case ND_ANIMPLAY: + case ND_GPENCIL: + ED_area_tag_redraw(sa); + break; } break; case NC_SPACE: @@ -532,7 +562,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf) /* ******** Hotkeys avalaible for main region only ******** */ keymap = WM_keymap_find(keyconf, "Clip Editor", SPACE_CLIP, 0); - +// keymap->poll = ED_space_clip_tracking_poll; /* ** View/navigation ** */ WM_keymap_add_item(keymap, "CLIP_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0); @@ -715,7 +745,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf) RNA_boolean_set(kmi->ptr, "extend", TRUE); /* toggle */ } -const char *clip_context_dir[] = {"edit_movieclip", NULL}; +const char *clip_context_dir[] = {"edit_movieclip", "edit_mask", NULL}; static int clip_context(const bContext *C, const char *member, bContextDataResult *result) { @@ -729,7 +759,11 @@ static int clip_context(const bContext *C, const char *member, bContextDataResul else if (CTX_data_equals(member, "edit_movieclip")) { if (sc->clip) CTX_data_id_pointer_set(result, &sc->clip->id); - + return TRUE; + } + else if (CTX_data_equals(member, "edit_mask")) { + if (sc->mask) + CTX_data_id_pointer_set(result, &sc->mask->id); return TRUE; } @@ -1020,6 +1054,9 @@ static void clip_main_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy); /* own keymap */ + keymap = WM_keymap_find(wm->defaultconf, "Mask Editing", 0, 0); + WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); + keymap = WM_keymap_find(wm->defaultconf, "Clip", SPACE_CLIP, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); @@ -1067,6 +1104,49 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar) /* Grease Pencil */ clip_draw_grease_pencil((bContext *)C, 1); + if (sc->mode == SC_MODE_MASKEDIT) { + int x, y; + int width, height; + float zoomx, zoomy, aspx, aspy; + + /* frame image */ + float maxdim; + float xofs, yofs; + + /* find window pixel coordinates of origin */ + UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y); + + ED_space_clip_size(sc, &width, &height); + ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); + ED_space_clip_aspect(sc, &aspx, &aspy); + + /* frame the image */ + maxdim = maxf(width, height); + if (width == height) { + xofs = yofs = 0; + } + else if (width < height) { + xofs = ((height - width) / -2.0f) * zoomx; + yofs = 0.0f; + } + else { /* (width > height) */ + xofs = 0.0f; + yofs = ((width - height) / -2.0f) * zoomy; + } + + /* apply transformation so mask editing tools will assume drawing from the origin in normalized space */ + glPushMatrix(); + glTranslatef(x + xofs, y + yofs, 0); + glScalef(maxdim * zoomx, maxdim * zoomy, 0); + glMultMatrixf(sc->stabmat); + + ED_mask_draw((bContext *)C, sc->mask_draw_flag, sc->mask_draw_type); + + ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); + + glPopMatrix(); + } + /* reset view matrix */ UI_view2d_view_restore(C); @@ -1241,6 +1321,26 @@ static void clip_header_area_draw(const bContext *C, ARegion *ar) ED_region_header(C, ar); } +static void clip_header_area_listener(ARegion *ar, wmNotifier *wmn) +{ + /* context changes */ + switch (wmn->category) { + case NC_SCENE: + switch (wmn->data) { + /* for proportional editmode only */ + case ND_TOOLSETTINGS: + /* TODO - should do this when in mask mode only but no datas available */ + // if (sc->mode == SC_MODE_MASKEDIT) + { + ED_region_tag_redraw(ar); + } + break; + } + break; + } +} + + /****************** tools region ******************/ /* add handlers, stuff you only do once or on area/region changes */ @@ -1402,6 +1502,7 @@ void ED_spacetype_clip(void) art->init = clip_header_area_init; art->draw = clip_header_area_draw; + art->listener = clip_header_area_listener; BLI_addhead(&st->regiontypes, art); diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index f6dbae596b8..f6e9622f0a5 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -79,6 +79,8 @@ #include "clip_intern.h" // own include +static float dist_to_crns(float co[2], float pos[2], float crns[4][2]); + /********************** add marker operator *********************/ static void add_marker(SpaceClip *sc, float x, float y) @@ -88,10 +90,11 @@ static void add_marker(SpaceClip *sc, float x, float y) ListBase *tracksbase = BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track; int width, height; + int framenr = ED_space_clip_clip_framenr(sc); ED_space_clip_size(sc, &width, &height); - track = BKE_tracking_add_track(tracking, tracksbase, x, y, sc->user.framenr, width, height); + track = BKE_tracking_add_track(tracking, tracksbase, x, y, framenr, width, height); BKE_tracking_select_track(tracksbase, track, TRACK_AREA_ALL, 0); @@ -106,6 +109,7 @@ static int add_marker_exec(bContext *C, wmOperator *op) int width, height; ED_space_clip_size(sc, &width, &height); + if (!width || !height) return OPERATOR_CANCELLED; @@ -143,7 +147,7 @@ void CLIP_OT_add_marker(wmOperatorType *ot) /* api callbacks */ ot->invoke = add_marker_invoke; ot->exec = add_marker_exec; - ot->poll = ED_space_clip_tracking_size_poll; + ot->poll = ED_space_clip_tracking_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -202,7 +206,7 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op)) MovieClip *clip = ED_space_clip(sc); ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track = tracksbase->first, *next; - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); int has_selection = 0; while (track) { @@ -258,19 +262,21 @@ typedef struct { int mval[2]; int width, height; - float *min, *max, *pos, *offset; - float smin[2], smax[2], spos[2], soff[2]; + float *min, *max, *pos, *offset, (*corners)[2]; + float smin[2], smax[2], spos[2], soff[2], scorners[4][2]; float (*smarkers)[2]; - int lock, accurate; + int lock, accurate, scale; } SlideMarkerData; static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTrack *track, - MovieTrackingMarker *marker, wmEvent *event, int area, int action, int width, int height) + MovieTrackingMarker *marker, wmEvent *event, + int area, int corner, int action, int width, int height) { SlideMarkerData *data = MEM_callocN(sizeof(SlideMarkerData), "slide marker data"); + int framenr = ED_space_clip_clip_framenr(sc); - marker = BKE_tracking_ensure_marker(track, sc->user.framenr); + marker = BKE_tracking_ensure_marker(track, framenr); data->area = area; data->action = action; @@ -285,10 +291,9 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra } else if (area == TRACK_AREA_PAT) { if (action == SLIDE_ACTION_SIZE) { - data->min = track->pat_min; - data->max = track->pat_max; + data->corners = marker->pattern_corners; } - else { + else if (action == SLIDE_ACTION_OFFSET) { int a; data->pos = marker->pos; @@ -300,15 +305,28 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra for (a = 0; a < track->markersnr; a++) copy_v2_v2(data->smarkers[a], track->markers[a].pos); } + else if (action == SLIDE_ACTION_POS) { + data->corners = marker->pattern_corners; + data->pos = marker->pattern_corners[corner]; + + copy_v2_v2(data->spos, data->pos); + } } else if (area == TRACK_AREA_SEARCH) { - data->min = track->search_min; - data->max = track->search_max; + data->min = marker->search_min; + data->max = marker->search_max; } - if (area == TRACK_AREA_SEARCH || (area == TRACK_AREA_PAT && action != SLIDE_ACTION_OFFSET)) { - copy_v2_v2(data->smin, data->min); - copy_v2_v2(data->smax, data->max); + if ((area == TRACK_AREA_SEARCH) || + (area == TRACK_AREA_PAT && action != SLIDE_ACTION_OFFSET)) + { + if (data->corners) { + memcpy(data->scorners, data->corners, sizeof(data->scorners)); + } + else { + copy_v2_v2(data->smin, data->min); + copy_v2_v2(data->smax, data->max); + } } data->mval[0] = event->mval[0]; @@ -323,9 +341,7 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra return data; } -/* corner = 0: right-bottom corner, - * corner = 1: left-top corner */ -static int mouse_on_corner(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, +static int mouse_on_corner(SpaceClip *sc, MovieTrackingMarker *marker, int area, float co[2], int corner, int width, int height) { int inside = 0; @@ -334,12 +350,11 @@ static int mouse_on_corner(SpaceClip *sc, MovieTrackingTrack *track, MovieTracki float crn[2], dx, dy, tdx, tdy; if (area == TRACK_AREA_SEARCH) { - copy_v2_v2(min, track->search_min); - copy_v2_v2(max, track->search_max); + copy_v2_v2(min, marker->search_min); + copy_v2_v2(max, marker->search_max); } else { - copy_v2_v2(min, track->pat_min); - copy_v2_v2(max, track->pat_max); + BKE_tracking_marker_pattern_minmax(marker, min, max); } dx = size / width / sc->zoom; @@ -367,22 +382,95 @@ static int mouse_on_corner(SpaceClip *sc, MovieTrackingTrack *track, MovieTracki return inside; } +static int get_mouse_pattern_corner(SpaceClip *sc, MovieTrackingMarker *marker, float co[2], int width, int height) +{ + int i, next; + float len = FLT_MAX, dx, dy; + + for (i = 0; i < 4; i++) { + float cur_len; + + next = (i + 1) % 4; + + cur_len = len_v2v2(marker->pattern_corners[i], marker->pattern_corners[next]); + + len = MIN2(cur_len, len); + } + + dx = 6.0f / width / sc->zoom; + dy = 6.0f / height / sc->zoom; + + dx = MIN2(dx * 2.0f / 3.0f, len / 6.0f); + dy = MIN2(dy * 2.0f / 3.0f, len * width / height / 6.0f); + + for (i = 0; i < 4; i++) { + float crn[2]; + int inside; + + add_v2_v2v2(crn, marker->pattern_corners[i], marker->pos); + + inside = IN_RANGE_INCL(co[0], crn[0] - dx, crn[0] + dx) && + IN_RANGE_INCL(co[1], crn[1] - dy, crn[1] + dy); + + if (inside) + return i; + } + + return -1; +} + static int mouse_on_offset(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, - float co[2], int width, int height) + float co[2], int width, int height) { float pos[2], dx, dy; + float pat_min[2], pat_max[2]; + + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); add_v2_v2v2(pos, marker->pos, track->offset); dx = 12.0f / width / sc->zoom; dy = 12.0f / height / sc->zoom; - dx = MIN2(dx, (track->pat_max[0] - track->pat_min[0]) / 2.0f); - dy = MIN2(dy, (track->pat_max[1] - track->pat_min[1]) / 2.0f); + dx = MIN2(dx, (pat_max[0] - pat_min[0]) / 2.0f); + dy = MIN2(dy, (pat_max[1] - pat_min[1]) / 2.0f); return co[0] >= pos[0] - dx && co[0] <= pos[0] + dx && co[1] >= pos[1] - dy && co[1] <= pos[1] + dy; } +static int slide_check_corners(float (*corners)[2]) +{ + int i, next, prev; + float cross = 0.0f; + float p[2] = {0.0f, 0.0f}; + + if (!isect_point_quad_v2(p, corners[0], corners[1], corners[2], corners[3])) + return FALSE; + + for (i = 0; i < 4; i++) { + float v1[2], v2[2], cur_cross; + + next = (i + 1) % 4; + prev = (4 + i - 1) % 4; + + sub_v2_v2v2(v1, corners[i], corners[prev]); + sub_v2_v2v2(v2, corners[next], corners[i]); + + cur_cross = cross_v2v2(v1, v2); + + if (fabsf(cur_cross) > FLT_EPSILON) { + if (cross == 0.0f) { + cross = cur_cross; + } + else if (cross * cur_cross < 0.0f) { + return FALSE; + } + } + } + + return TRUE; +} + static void hide_cursor(bContext *C) { wmWindow *win = CTX_wm_window(C); @@ -406,6 +494,7 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event) float co[2]; void *customdata = NULL; ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + int framenr = ED_space_clip_clip_framenr(sc); ED_space_clip_size(sc, &width, &height); @@ -417,31 +506,48 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event) track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); if ((marker->flag & MARKER_DISABLED) == 0) { - if (!customdata) + if (!customdata) { if (mouse_on_offset(sc, track, marker, co, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_POINT, + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_POINT, 0, SLIDE_ACTION_POS, width, height); + } if (sc->flag & SC_SHOW_MARKER_SEARCH) { - if (mouse_on_corner(sc, track, marker, TRACK_AREA_SEARCH, co, 1, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, + if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 1, width, height)) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, 0, SLIDE_ACTION_OFFSET, width, height); - else if (mouse_on_corner(sc, track, marker, TRACK_AREA_SEARCH, co, 0, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, + } + else if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 0, width, height)) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, 0, SLIDE_ACTION_SIZE, width, height); + } } if (!customdata && (sc->flag & SC_SHOW_MARKER_PATTERN)) { - if (mouse_on_corner(sc, track, marker, TRACK_AREA_PAT, co, 1, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, - SLIDE_ACTION_OFFSET, width, height); - - if (!customdata && mouse_on_corner(sc, track, marker, TRACK_AREA_PAT, co, 0, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, - SLIDE_ACTION_SIZE, width, height); + /* XXX: need to be real check if affine tracking is enabled, but for now not + * sure how to do this, so assume affine tracker is always enabled */ + if (TRUE) { + int corner = get_mouse_pattern_corner(sc, marker, co, width, height); + + if (corner != -1) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, corner, + SLIDE_ACTION_POS, width, height); + } + } + else { + if (mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 1, width, height)) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, 0, + SLIDE_ACTION_OFFSET, width, height); + } + + if (!customdata && mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 0, width, height)) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, 0, + SLIDE_ACTION_SIZE, width, height); + } + } } if (customdata) @@ -489,9 +595,16 @@ static void cancel_mouse_slide(SlideMarkerData *data) copy_v2_v2(data->pos, data->spos); } else { - if (data->action == SLIDE_ACTION_SIZE) { - copy_v2_v2(data->min, data->smin); - copy_v2_v2(data->max, data->smax); + if ((data->action == SLIDE_ACTION_SIZE) || + (data->action == SLIDE_ACTION_POS && data->area == TRACK_AREA_PAT)) + { + if (data->corners) { + memcpy(data->corners, data->scorners, sizeof(data->scorners)); + } + else { + copy_v2_v2(data->min, data->smin); + copy_v2_v2(data->max, data->smax); + } } else { int a; @@ -527,6 +640,10 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) data->lock = event->val == KM_RELEASE; + if (data->action == SLIDE_ACTION_POS) + if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) + data->scale = event->val == KM_PRESS; + if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) data->accurate = event->val == KM_PRESS; @@ -556,8 +673,6 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) else { data->pos[0] = data->spos[0] + dx; data->pos[1] = data->spos[1] + dy; - - data->marker->flag &= ~MARKER_TRACKED; } WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); @@ -565,18 +680,33 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) } else { if (data->action == SLIDE_ACTION_SIZE) { - data->min[0] = data->smin[0] - dx; - data->max[0] = data->smax[0] + dx; + if (data->corners) { + data->corners[0][0] = data->scorners[0][0] - dx; + data->corners[0][1] = data->scorners[0][1] + dy; - data->min[1] = data->smin[1] + dy; - data->max[1] = data->smax[1] - dy; + data->corners[1][0] = data->scorners[1][0] + dx; + data->corners[1][1] = data->scorners[1][1] + dy; + + data->corners[2][0] = data->scorners[2][0] + dx; + data->corners[2][1] = data->scorners[2][1] - dy; + + data->corners[3][0] = data->scorners[3][0] - dx; + data->corners[3][1] = data->scorners[3][1] - dy; + } + else { + data->min[0] = data->smin[0] - dx; + data->max[0] = data->smax[0] + dx; + + data->min[1] = data->smin[1] + dy; + data->max[1] = data->smax[1] - dy; + } if (data->area == TRACK_AREA_SEARCH) - BKE_tracking_clamp_track(data->track, CLAMP_SEARCH_DIM); + BKE_tracking_clamp_marker(data->marker, CLAMP_SEARCH_DIM); else - BKE_tracking_clamp_track(data->track, CLAMP_PAT_DIM); + BKE_tracking_clamp_marker(data->marker, CLAMP_PAT_DIM); } - else { + else if (data->action == SLIDE_ACTION_OFFSET) { float d[2] = {dx, dy}; if (data->area == TRACK_AREA_SEARCH) { @@ -593,10 +723,43 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) } if (data->area == TRACK_AREA_SEARCH) - BKE_tracking_clamp_track(data->track, CLAMP_SEARCH_POS); + BKE_tracking_clamp_marker(data->marker, CLAMP_SEARCH_POS); + } + else if (data->action == SLIDE_ACTION_POS) { + if (data->scale) { + float scale = 1.0f + 10.0f * (dx - dy); + + if (scale > 0.0f) { + int a; + + for (a = 0; a < 4; a++) { + mul_v2_v2fl(data->corners[a], data->scorners[a], scale); + } + } + } + else { + float spos[2]; + + copy_v2_v2(spos, data->pos); + + /* corners might've been scaled before, restore their original position */ + memcpy(data->corners, data->scorners, sizeof(data->scorners)); + + data->pos[0] = data->spos[0] + dx; + data->pos[1] = data->spos[1] + dy; + + if (!slide_check_corners(data->corners)) { + copy_v2_v2(data->pos, spos); + } + } + + /* currently only patterns are allowed to have such combination of event and data */ + BKE_tracking_clamp_marker(data->marker, CLAMP_PAT_DIM); } } + data->marker->flag &= ~MARKER_TRACKED; + WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, NULL); break; @@ -635,7 +798,7 @@ void CLIP_OT_slide_marker(wmOperatorType *ot) ot->idname = "CLIP_OT_slide_marker"; /* api callbacks */ - ot->poll = ED_space_clip_tracking_size_poll; + ot->poll = ED_space_clip_tracking_poll; ot->invoke = slide_marker_invoke; ot->modal = slide_marker_modal; @@ -669,30 +832,41 @@ static int mouse_on_rect(float co[2], float pos[2], float min[2], float max[2], mouse_on_side(co, pos[0] + max[0], pos[1] + min[1], pos[0] + max[0], pos[1] + max[1], epsx, epsy); } +static int mouse_on_crns(float co[2], float pos[2], float crns[4][2], float epsx, float epsy) +{ + float dist = dist_to_crns(co, pos, crns); + + return dist < MAX2(epsx, epsy); +} + static int track_mouse_area(SpaceClip *sc, float co[2], MovieTrackingTrack *track) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + int framenr = ED_space_clip_clip_framenr(sc); + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); + float pat_min[2], pat_max[2]; float epsx, epsy; int width, height; ED_space_clip_size(sc, &width, &height); - epsx = MIN4(track->pat_min[0] - track->search_min[0], track->search_max[0] - track->pat_max[0], - fabsf(track->pat_min[0]), fabsf(track->pat_max[0])) / 2; - epsy = MIN4(track->pat_min[1] - track->search_min[1], track->search_max[1] - track->pat_max[1], - fabsf(track->pat_min[1]), fabsf(track->pat_max[1])) / 2; + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + + epsx = MIN4(pat_min[0] - marker->search_min[0], marker->search_max[0] - pat_max[0], + fabsf(pat_min[0]), fabsf(pat_max[0])) / 2; + epsy = MIN4(pat_min[1] - marker->search_min[1], marker->search_max[1] - pat_max[1], + fabsf(pat_min[1]), fabsf(pat_max[1])) / 2; epsx = MAX2(epsx, 2.0f / width); epsy = MAX2(epsy, 2.0f / height); if (sc->flag & SC_SHOW_MARKER_SEARCH) { - if (mouse_on_rect(co, marker->pos, track->search_min, track->search_max, epsx, epsy)) + if (mouse_on_rect(co, marker->pos, marker->search_min, marker->search_max, epsx, epsy)) return TRACK_AREA_SEARCH; } if ((marker->flag & MARKER_DISABLED) == 0) { if (sc->flag & SC_SHOW_MARKER_PATTERN) - if (mouse_on_rect(co, marker->pos, track->pat_min, track->pat_max, epsx, epsy)) + if (mouse_on_crns(co, marker->pos, marker->pattern_corners, epsx, epsy)) return TRACK_AREA_PAT; epsx = 12.0f / width; @@ -723,29 +897,45 @@ static float dist_to_rect(float co[2], float pos[2], float min[2], float max[2]) return MIN4(d1, d2, d3, d4); } +static float dist_to_crns(float co[2], float pos[2], float crns[4][2]) +{ + float d1, d2, d3, d4; + float p[2] = {co[0] - pos[0], co[1] - pos[1]}; + float *v1 = crns[0], *v2 = crns[1], + *v3 = crns[2], *v4 = crns[3]; + + d1 = dist_to_line_segment_v2(p, v1, v2); + d2 = dist_to_line_segment_v2(p, v2, v3); + d3 = dist_to_line_segment_v2(p, v3, v4); + d4 = dist_to_line_segment_v2(p, v4, v1); + + return MIN4(d1, d2, d3, d4); +} + static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbase, float co[2]) { MovieTrackingTrack *track = NULL, *cur; float mindist = 0.0f; + int framenr = ED_space_clip_clip_framenr(sc); cur = tracksbase->first; while (cur) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(cur, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_get_marker(cur, framenr); if (((cur->flag & TRACK_HIDDEN) == 0) && MARKER_VISIBLE(sc, cur, marker)) { float dist, d1, d2 = FLT_MAX, d3 = FLT_MAX; /* distance to marker point */ d1 = sqrtf((co[0] - marker->pos[0] - cur->offset[0]) * (co[0] - marker->pos[0] - cur->offset[0]) + - (co[1] - marker->pos[1] - cur->offset[1]) * (co[1] - marker->pos[1] - cur->offset[1])); + (co[1] - marker->pos[1] - cur->offset[1]) * (co[1] - marker->pos[1] - cur->offset[1])); /* distance to pattern boundbox */ if (sc->flag & SC_SHOW_MARKER_PATTERN) - d2 = dist_to_rect(co, marker->pos, cur->pat_min, cur->pat_max); + d2 = dist_to_crns(co, marker->pos, marker->pattern_corners); /* distance to search boundbox */ if (sc->flag & SC_SHOW_MARKER_SEARCH && TRACK_VIEW_SELECTED(sc, cur)) - d3 = dist_to_rect(co, marker->pos, cur->search_min, cur->search_max); + d3 = dist_to_rect(co, marker->pos, marker->search_min, marker->search_max); /* choose minimal distance. useful for cases of overlapped markers. */ dist = MIN3(d1, d2, d3); @@ -855,7 +1045,8 @@ void CLIP_OT_select(wmOperatorType *ot) /* api callbacks */ ot->exec = select_exec; ot->invoke = select_invoke; - ot->poll = ED_space_clip_tracking_poll; + //ot->poll = ED_space_clip_tracking_poll; // so mask view can Ctrl+RMB markers + ot->poll = ED_space_clip_view_clip_poll; /* flags */ ot->flag = OPTYPE_UNDO; @@ -879,6 +1070,7 @@ static int border_select_exec(bContext *C, wmOperator *op) rcti rect; rctf rectf; int change = FALSE, mode, extend; + int framenr = ED_space_clip_clip_framenr(sc); /* get rectangle from operator */ rect.xmin = RNA_int_get(op->ptr, "xmin"); @@ -896,7 +1088,7 @@ static int border_select_exec(bContext *C, wmOperator *op) track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { if (BLI_in_rctf(&rectf, marker->pos[0], marker->pos[1])) { @@ -955,6 +1147,7 @@ static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, sho ListBase *tracksbase = BKE_tracking_get_tracks(tracking); rcti rect; int change = FALSE; + int framenr = ED_space_clip_clip_framenr(sc); /* get rectangle from operator */ BLI_lasso_boundbox(&rect, mcords, moves); @@ -963,7 +1156,7 @@ static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, sho track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { float screen_co[2]; @@ -1057,6 +1250,7 @@ static int circle_select_exec(bContext *C, wmOperator *op) ListBase *tracksbase = BKE_tracking_get_tracks(tracking); int x, y, radius, width, height, mode, change = FALSE; float zoomx, zoomy, offset[2], ellipse[2]; + int framenr = ED_space_clip_clip_framenr(sc); /* get operator properties */ x = RNA_int_get(op->ptr, "x"); @@ -1078,7 +1272,7 @@ static int circle_select_exec(bContext *C, wmOperator *op) track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); if (MARKER_VISIBLE(sc, track, marker) && marker_inside_ellipse(marker, offset, ellipse)) { BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, mode != GESTURE_MODAL_SELECT); @@ -1135,7 +1329,7 @@ static int select_all_exec(bContext *C, wmOperator *op) MovieTrackingMarker *marker; ListBase *tracksbase = BKE_tracking_get_tracks(tracking); int action = RNA_enum_get(op->ptr, "action"); - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); int has_selection = FALSE; if (action == SEL_TOGGLE) { @@ -1225,21 +1419,22 @@ static int select_groped_exec(bContext *C, wmOperator *op) MovieTracking *tracking = &clip->tracking; ListBase *tracksbase = BKE_tracking_get_tracks(tracking); int group = RNA_enum_get(op->ptr, "group"); + int framenr = ED_space_clip_clip_framenr(sc); track = tracksbase->first; while (track) { int ok = FALSE; - marker = BKE_tracking_get_marker(track, sc->user.framenr); + marker = BKE_tracking_get_marker(track, framenr); if (group == 0) { /* Keyframed */ - ok = marker->framenr == sc->user.framenr && (marker->flag & MARKER_TRACKED) == 0; + ok = marker->framenr == framenr && (marker->flag & MARKER_TRACKED) == 0; } else if (group == 1) { /* Estimated */ - ok = marker->framenr != sc->user.framenr; + ok = marker->framenr != framenr; } else if (group == 2) { /* tracked */ - ok = marker->framenr == sc->user.framenr && (marker->flag & MARKER_TRACKED); + ok = marker->framenr == framenr && (marker->flag & MARKER_TRACKED); } else if (group == 3) { /* locked */ ok = track->flag & TRACK_LOCKED; @@ -1299,7 +1494,7 @@ void CLIP_OT_select_grouped(wmOperatorType *ot) /* api callbacks */ ot->exec = select_groped_exec; - ot->poll = ED_space_clip_tracking_size_poll; + ot->poll = ED_space_clip_tracking_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1332,7 +1527,7 @@ static int track_count_markers(SpaceClip *sc, MovieClip *clip) int tot = 0; ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track; - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); track = tracksbase->first; while (track) { @@ -1376,7 +1571,7 @@ static void track_init_markers(SpaceClip *sc, MovieClip *clip, int *frames_limit { ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track; - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); int frames_limit = 0; clear_invisible_track_selection(sc, clip); @@ -1426,7 +1621,7 @@ static int track_markers_initjob(bContext *C, TrackMarkersJob *tmj, int backward track_init_markers(sc, clip, &frames_limit); - tmj->sfra = sc->user.framenr; + tmj->sfra = ED_space_clip_clip_framenr(sc); tmj->clip = clip; tmj->backwards = backwards; @@ -1443,6 +1638,8 @@ static int track_markers_initjob(bContext *C, TrackMarkersJob *tmj, int backward tmj->efra = MIN2(tmj->efra, tmj->sfra + frames_limit); } + tmj->efra = BKE_movieclip_remap_scene_to_clip_frame(clip, tmj->efra); + if (settings->speed != TRACKING_SPEED_FASTEST) { tmj->delay = 1.0f / scene->r.frs_sec * 1000.0f; @@ -1527,7 +1724,7 @@ static void track_markers_freejob(void *tmv) TrackMarkersJob *tmj = (TrackMarkersJob *)tmv; tmj->clip->tracking_context = NULL; - tmj->scene->r.cfra = tmj->lastfra; + tmj->scene->r.cfra = BKE_movieclip_remap_clip_to_scene_frame(tmj->clip, tmj->lastfra); ED_update_for_newframe(tmj->main, tmj->scene, 0); BKE_tracking_sync(tmj->context); @@ -1544,7 +1741,7 @@ static int track_markers_exec(bContext *C, wmOperator *op) MovieClip *clip = ED_space_clip(sc); Scene *scene = CTX_data_scene(C); struct MovieTrackingContext *context; - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); int sfra = framenr, efra; int backwards = RNA_boolean_get(op->ptr, "backwards"); int sequence = RNA_boolean_get(op->ptr, "sequence"); @@ -1568,6 +1765,8 @@ static int track_markers_exec(bContext *C, wmOperator *op) efra = MIN2(efra, sfra + frames_limit); } + efra = BKE_movieclip_remap_scene_to_clip_frame(clip, efra); + if (!track_markers_check_direction(backwards, framenr, efra)) return OPERATOR_CANCELLED; @@ -1589,7 +1788,7 @@ static int track_markers_exec(bContext *C, wmOperator *op) BKE_tracking_context_free(context); /* update scene current frame to the lastes tracked frame */ - scene->r.cfra = framenr; + scene->r.cfra = BKE_movieclip_remap_clip_to_scene_frame(clip, framenr); WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); @@ -1680,7 +1879,7 @@ void CLIP_OT_track_markers(wmOperatorType *ot) /* api callbacks */ ot->exec = track_markers_exec; ot->invoke = track_markers_invoke; - ot->poll = ED_space_clip_tracking_frame_poll; + ot->poll = ED_space_clip_tracking_poll; ot->modal = track_markers_modal; /* flags */ @@ -1967,16 +2166,17 @@ static int clear_track_path_exec(bContext *C, wmOperator *op) ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); int action = RNA_enum_get(op->ptr, "action"); int clear_active = RNA_boolean_get(op->ptr, "clear_active"); + int framenr = ED_space_clip_clip_framenr(sc); if (clear_active) { track = BKE_tracking_active_track(&clip->tracking); - BKE_tracking_clear_path(track, sc->user.framenr, action); + BKE_tracking_clear_path(track, framenr, action); } else { track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track)) - BKE_tracking_clear_path(track, sc->user.framenr, action); + BKE_tracking_clear_path(track, framenr, action); track = track->next; } @@ -2023,10 +2223,11 @@ static int disable_markers_exec(bContext *C, wmOperator *op) ListBase *tracksbase = BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track = tracksbase->first; int action = RNA_enum_get(op->ptr, "action"); + int framenr = ED_space_clip_clip_framenr(sc); while (track) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { - MovieTrackingMarker *marker = BKE_tracking_ensure_marker(track, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_ensure_marker(track, framenr); if (action == 0) marker->flag |= MARKER_DISABLED; @@ -2119,18 +2320,22 @@ static Object *get_orientation_object(bContext *C) static int set_orientation_poll(bContext *C) { - if (ED_space_clip_tracking_size_poll(C)) { + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { Scene *scene = CTX_data_scene(C); - SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object = BKE_tracking_active_object(tracking); - if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { - return TRUE; - } - else { - return OBACT != NULL; + if (clip) { + MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *tracking_object = BKE_tracking_active_object(tracking); + + if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { + return TRUE; + } + else { + return OBACT != NULL; + } } } @@ -2729,16 +2934,20 @@ void CLIP_OT_set_scale(wmOperatorType *ot) static int set_solution_scale_poll(bContext *C) { - if (ED_space_clip_tracking_size_poll(C)) { - SpaceClip *sc = CTX_wm_space_clip(C); + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { MovieClip *clip = ED_space_clip(sc); - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object = BKE_tracking_active_object(tracking); - return (tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0; + if (clip) { + MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *tracking_object = BKE_tracking_active_object(tracking); + + return (tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0; + } } - return 0; + return FALSE; } static int set_solution_scale_exec(bContext *C, wmOperator *op) @@ -2945,8 +3154,14 @@ static int detect_features_exec(bContext *C, wmOperator *op) int min_trackability = RNA_int_get(op->ptr, "min_trackability"); int min_distance = RNA_int_get(op->ptr, "min_distance"); int place_outside_layer = 0; + int framenr = ED_space_clip_clip_framenr(sc); bGPDlayer *layer = NULL; + if (!ibuf) { + BKE_report(op->reports, RPT_ERROR, "Feature detection requires valid clip frame"); + return OPERATOR_CANCELLED; + } + if (placement != 0) { layer = detect_get_layer(clip); place_outside_layer = placement == 2; @@ -2961,7 +3176,7 @@ static int detect_features_exec(bContext *C, wmOperator *op) track = track->next; } - BKE_tracking_detect_fast(tracking, tracksbase, ibuf, sc->user.framenr, margin, + BKE_tracking_detect_fast(tracking, tracksbase, ibuf, framenr, margin, min_trackability, min_distance, layer, place_outside_layer); IMB_freeImBuf(ibuf); @@ -2987,7 +3202,7 @@ void CLIP_OT_detect_features(wmOperatorType *ot) /* api callbacks */ ot->exec = detect_features_exec; - ot->poll = ED_space_clip_tracking_frame_poll; + ot->poll = ED_space_clip_tracking_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -3019,7 +3234,8 @@ static int frame_jump_exec(bContext *C, wmOperator *op) delta = pos == 1 ? 1 : -1; while (sc->user.framenr + delta >= SFRA && sc->user.framenr + delta <= EFRA) { - MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, sc->user.framenr + delta); + int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, sc->user.framenr + delta); + MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); if (!marker || marker->flag & MARKER_DISABLED) break; @@ -3029,7 +3245,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op) } else { /* to to failed frame */ if (clip->tracking.reconstruction.flag & TRACKING_RECONSTRUCTED) { - int a = sc->user.framenr; + int a = ED_space_clip_clip_framenr(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingObject *object = BKE_tracking_active_object(tracking); @@ -3043,7 +3259,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op) cam = BKE_tracking_get_reconstructed_camera(tracking, object, a); if (!cam) { - sc->user.framenr = a; + sc->user.framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, a); break; } @@ -3139,7 +3355,7 @@ void CLIP_OT_join_tracks(wmOperatorType *ot) /* api callbacks */ ot->exec = join_tracks_exec; - ot->poll = ED_space_clip_tracking_size_poll; + ot->poll = ED_space_clip_tracking_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/space_console/console_intern.h b/source/blender/editors/space_console/console_intern.h index c0abd094e62..3d30dcad710 100644 --- a/source/blender/editors/space_console/console_intern.h +++ b/source/blender/editors/space_console/console_intern.h @@ -54,6 +54,9 @@ void CONSOLE_OT_move(struct wmOperatorType *ot); void CONSOLE_OT_delete(struct wmOperatorType *ot); void CONSOLE_OT_insert(struct wmOperatorType *ot); +void CONSOLE_OT_indent(struct wmOperatorType *ot); +void CONSOLE_OT_unindent(struct wmOperatorType *ot); + void CONSOLE_OT_history_append(struct wmOperatorType *ot); void CONSOLE_OT_scrollback_append(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index 5ed384d22af..7efcbcceb3c 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -364,9 +364,8 @@ static int console_insert_exec(bContext *C, wmOperator *op) char *str = RNA_string_get_alloc(op->ptr, "text", NULL, 0); int len; - // XXX, alligned tab key hack if (str[0] == '\t' && str[1] == '\0') { - len = TAB_LENGTH - (ci->cursor % TAB_LENGTH); + len = TAB_LENGTH; MEM_freeN(str); str = MEM_mallocN(len + 1, "insert_exec"); memset(str, ' ', len); @@ -430,6 +429,95 @@ void CONSOLE_OT_insert(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } +static int console_indent_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceConsole *sc = CTX_wm_space_console(C); + ARegion *ar = CTX_wm_region(C); + ConsoleLine *ci = console_history_verify(C); + int spaces; + int len; + + for (spaces = 0; spaces < ci->len; spaces++) { + if (ci->line[spaces] != ' ') + break; + } + + len = TAB_LENGTH - spaces % TAB_LENGTH; + + console_line_verify_length(ci, ci->len + len); + + memmove(ci->line + len, ci->line, ci->len); + memset(ci->line, ' ', len); + ci->len += len; + console_line_cursor_set(ci, ci->cursor + len); + + console_textview_update_rect(sc, ar); + ED_area_tag_redraw(CTX_wm_area(C)); + + console_scroll_bottom(ar); + + return OPERATOR_FINISHED; +} + +void CONSOLE_OT_indent(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Indent"; + ot->description = "Add 4 spaces at line beginning"; + ot->idname = "CONSOLE_OT_indent"; + + /* api callbacks */ + ot->exec = console_indent_exec; + ot->poll = ED_operator_console_active; +} + +static int console_unindent_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceConsole *sc = CTX_wm_space_console(C); + ARegion *ar = CTX_wm_region(C); + ConsoleLine *ci = console_history_verify(C); + int spaces; + int len; + + for (spaces = 0; spaces < ci->len; spaces++) { + if (ci->line[spaces] != ' ') + break; + } + + if (spaces == 0) + return OPERATOR_CANCELLED; + + len = spaces % TAB_LENGTH; + if (len == 0) + len = TAB_LENGTH; + + console_line_verify_length(ci, ci->len - len); + + memmove(ci->line, ci->line + len, (ci->len - len) + 1); + ci->len -= len; + console_line_cursor_set(ci, ci->cursor - len); + + //console_select_offset(sc, -4); + + console_textview_update_rect(sc, ar); + ED_area_tag_redraw(CTX_wm_area(C)); + + console_scroll_bottom(ar); + + return OPERATOR_FINISHED; +} + +void CONSOLE_OT_unindent(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Unindent"; + ot->description = "Delete 4 spaces from line beginning"; + ot->idname = "CONSOLE_OT_unindent"; + + /* api callbacks */ + ot->exec = console_unindent_exec; + ot->poll = ED_operator_console_active; +} static EnumPropertyItem console_delete_type_items[] = { {DEL_NEXT_CHAR, "NEXT_CHARACTER", 0, "Next Character", ""}, @@ -757,7 +845,8 @@ void CONSOLE_OT_scrollback_append(wmOperatorType *ot) {CONSOLE_LINE_INPUT, "INPUT", 0, "Input", ""}, {CONSOLE_LINE_INFO, "INFO", 0, "Information", ""}, {CONSOLE_LINE_ERROR, "ERROR", 0, "Error", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; /* identifiers */ ot->name = "Scrollback Append"; diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index a25606db2b3..460b31d69bd 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -246,6 +246,9 @@ static void console_operatortypes(void) WM_operatortype_append(CONSOLE_OT_move); WM_operatortype_append(CONSOLE_OT_delete); WM_operatortype_append(CONSOLE_OT_insert); + + WM_operatortype_append(CONSOLE_OT_indent); + WM_operatortype_append(CONSOLE_OT_unindent); /* for use by python only */ WM_operatortype_append(CONSOLE_OT_history_append); @@ -332,7 +335,11 @@ static void console_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "CONSOLE_OT_select_set", LEFTMOUSE, KM_PRESS, 0, 0); - RNA_string_set(WM_keymap_add_item(keymap, "CONSOLE_OT_insert", TABKEY, KM_PRESS, 0, 0)->ptr, "text", "\t"); /* fake tabs */ + RNA_string_set(WM_keymap_add_item(keymap, "CONSOLE_OT_insert", TABKEY, KM_PRESS, KM_CTRL, 0)->ptr, "text", "\t"); /* fake tabs */ + + WM_keymap_add_item(keymap, "CONSOLE_OT_indent", TABKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "CONSOLE_OT_unindent", TABKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "CONSOLE_OT_insert", KM_TEXTINPUT, KM_ANY, KM_ANY, 0); // last! } diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 27f8ae59919..afd04697e5e 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -102,8 +102,7 @@ typedef struct ThumbnailJob { ReportList reports; } ThumbnailJob; -typedef struct FileList -{ +typedef struct FileList { struct direntry *filelist; int *fidx; int numfiles; @@ -124,8 +123,7 @@ typedef struct FileList } FileList; -typedef struct FolderList -{ +typedef struct FolderList { struct FolderList *next, *prev; char *foldername; } FolderList; diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index fac6a387b9f..7a37c5fb3c5 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -53,8 +53,7 @@ typedef enum FileSelType { FILE_SEL_TOGGLE = 2 } FileSelType; -typedef enum FileCheckType -{ +typedef enum FileCheckType { CHECK_DIRS = 1, CHECK_FILES = 2, CHECK_ALL = 3 diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 6e52056ff2b..332a2ecada4 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -637,6 +637,8 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char ima = imaptr.data; iuser = userptr->data; + BKE_image_user_check_frame_calc(iuser, (int)scene->r.cfra, 0); + cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb"); cb->ptr = *ptr; cb->prop = prop; diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index aab628180c8..998ebac1cb9 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -564,16 +564,9 @@ void draw_image_grease_pencil(bContext *C, short onlyv2d) { /* draw in View2D space? */ if (onlyv2d) { - /* assume that UI_view2d_ortho(C) has been called... */ - SpaceImage *sima = (SpaceImage *)CTX_wm_space_data(C); - void *lock; - ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &lock); - /* draw grease-pencil ('image' strokes) */ //if (sima->flag & SI_DISPGP) - draw_gpencil_2dimage(C, ibuf); - - ED_space_image_release_buffer(sima, lock); + draw_gpencil_2dimage(C); } else { /* assume that UI_view2d_restore(C) has been called... */ @@ -585,6 +578,28 @@ void draw_image_grease_pencil(bContext *C, short onlyv2d) } } +void draw_image_sample_line(SpaceImage *sima) +{ + if (sima->sample_line_hist.flag & HISTO_FLAG_SAMPLELINE) { + Histogram *hist = &sima->sample_line_hist; + + glBegin(GL_LINES); + glColor3ub(0, 0, 0); + glVertex2fv(hist->co[0]); + glVertex2fv(hist->co[1]); + glEnd(); + + setlinestyle(1); + glBegin(GL_LINES); + glColor3ub(255, 255, 255); + glVertex2fv(hist->co[0]); + glVertex2fv(hist->co[1]); + glEnd(); + setlinestyle(0); + + } +} + /* XXX becomes WM paint cursor */ #if 0 static void draw_image_view_tool(Scene *scene) diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h index 121130ec536..0d3a7614f10 100644 --- a/source/blender/editors/space_image/image_intern.h +++ b/source/blender/editors/space_image/image_intern.h @@ -54,6 +54,7 @@ extern const char *image_context_dir[]; /* doc access */ /* image_draw.c */ void draw_image_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene); void draw_image_grease_pencil(struct bContext *C, short onlyv2d); +void draw_image_sample_line(struct SpaceImage *sima); /* image_ops.c */ int space_image_main_area_poll(struct bContext *C); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 2cb36841082..97f3bd744dc 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -2137,13 +2137,20 @@ static int image_sample_line_exec(bContext *C, wmOperator *op) hist->x_resolution = 256; hist->xmax = 1.0f; hist->ymax = 1.0f; - + + /* persistent draw */ + hist->co[0][0] = x1f; + hist->co[0][1] = y1f; + hist->co[1][0] = x2f; + hist->co[1][1] = y2f; + hist->flag |= HISTO_FLAG_SAMPLELINE; /* keep drawing the flag after */ + for (i = 0; i < 256; i++) { x = (int)(0.5f + x1 + (float)i * (x2 - x1) / 255.0f); y = (int)(0.5f + y1 + (float)i * (y2 - y1) / 255.0f); if (x < 0 || y < 0 || x >= ibuf->x || y >= ibuf->y) { - hist->data_luma[i] = hist->data_r[i] = hist->data_g[i] = hist->data_b[i] = 0.0f; + hist->data_luma[i] = hist->data_r[i] = hist->data_g[i] = hist->data_b[i] = hist->data_a[i] = 0.0f; } else { if (ibuf->rect_float) { @@ -2154,17 +2161,19 @@ static int image_sample_line_exec(bContext *C, wmOperator *op) else copy_v3_v3(rgb, fp); - hist->data_r[i] = rgb[0]; - hist->data_g[i] = rgb[1]; - hist->data_b[i] = rgb[2]; - hist->data_luma[i] = rgb_to_luma(rgb); + hist->data_luma[i] = rgb_to_luma(rgb); + hist->data_r[i] = rgb[0]; + hist->data_g[i] = rgb[1]; + hist->data_b[i] = rgb[2]; + hist->data_a[i] = fp[3]; } else if (ibuf->rect) { cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x); - hist->data_r[i] = (float)cp[0] / 255.0f; - hist->data_g[i] = (float)cp[1] / 255.0f; - hist->data_b[i] = (float)cp[2] / 255.0f; - hist->data_luma[i] = (float)rgb_to_luma_byte(cp) / 255.0f; + hist->data_luma[i] = (float)rgb_to_luma_byte(cp) / 255.0f; + hist->data_r[i] = (float)cp[0] / 255.0f; + hist->data_g[i] = (float)cp[1] / 255.0f; + hist->data_b[i] = (float)cp[2] / 255.0f; + hist->data_a[i] = (float)cp[3] / 255.0f; } } } @@ -2179,7 +2188,10 @@ static int image_sample_line_exec(bContext *C, wmOperator *op) static int image_sample_line_invoke(bContext *C, wmOperator *op, wmEvent *event) { SpaceImage *sima = CTX_wm_space_image(C); - + + Histogram *hist = &sima->sample_line_hist; + hist->flag &= ~HISTO_FLAG_SAMPLELINE; + if (!ED_space_image_has_buffer(sima)) return OPERATOR_CANCELLED; @@ -2443,56 +2455,15 @@ void IMAGE_OT_cycle_render_slot(wmOperatorType *ot) /* goes over all ImageUsers, and sets frame numbers if auto-refresh is set */ +static void image_update_frame(struct Image *UNUSED(ima), struct ImageUser *iuser, void *customdata) +{ + int cfra = *(int*)customdata; + + BKE_image_user_check_frame_calc(iuser, cfra, 0); +} + void ED_image_update_frame(const Main *mainp, int cfra) { - wmWindowManager *wm; - wmWindow *win; - Tex *tex; - - /* texture users */ - for (tex = mainp->tex.first; tex; tex = tex->id.next) { - if (tex->type == TEX_IMAGE && tex->ima) { - if (ELEM(tex->ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { - if (tex->iuser.flag & IMA_ANIM_ALWAYS) - BKE_image_user_frame_calc(&tex->iuser, cfra, 0); - } - } - } - - /* image window, compo node users */ - for (wm = mainp->wm.first; wm; wm = wm->id.next) { /* only 1 wm */ - for (win = wm->windows.first; win; win = win->next) { - ScrArea *sa; - for (sa = win->screen->areabase.first; sa; sa = sa->next) { - if (sa->spacetype == SPACE_VIEW3D) { - View3D *v3d = sa->spacedata.first; - BGpic *bgpic; - for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) - if (bgpic->iuser.flag & IMA_ANIM_ALWAYS) - BKE_image_user_frame_calc(&bgpic->iuser, cfra, 0); - } - else if (sa->spacetype == SPACE_IMAGE) { - SpaceImage *sima = sa->spacedata.first; - if (sima->iuser.flag & IMA_ANIM_ALWAYS) - BKE_image_user_frame_calc(&sima->iuser, cfra, 0); - } - else if (sa->spacetype == SPACE_NODE) { - SpaceNode *snode = sa->spacedata.first; - if ((snode->treetype == NTREE_COMPOSIT) && (snode->nodetree)) { - bNode *node; - for (node = snode->nodetree->nodes.first; node; node = node->next) { - if (node->id && node->type == CMP_NODE_IMAGE) { - Image *ima = (Image *)node->id; - ImageUser *iuser = node->storage; - if (ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) - if (iuser->flag & IMA_ANIM_ALWAYS) - BKE_image_user_frame_calc(iuser, cfra, 0); - } - } - } - } - } - } - } + BKE_image_walk_all_users(mainp, &cfra, image_update_frame); } diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index a8d83500cc1..6652a7470c2 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -590,8 +590,7 @@ static void image_refresh(const bContext *C, ScrArea *UNUSED(sa)) ima = ED_space_image(sima); - if (sima->iuser.flag & IMA_ANIM_ALWAYS) - BKE_image_user_frame_calc(&sima->iuser, scene->r.cfra, 0); + BKE_image_user_check_frame_calc(&sima->iuser, scene->r.cfra, 0); /* check if we have to set the image from the editmesh */ if (ima && (ima->source == IMA_SRC_VIEWER || sima->pin)) ; @@ -825,15 +824,18 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) draw_uvedit_main(sima, ar, scene, obedit, obact); ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); - + /* Grease Pencil too (in addition to UV's) */ draw_image_grease_pencil((bContext *)C, 1); + /* sample line */ + draw_image_sample_line(sima); + UI_view2d_view_restore(C); /* draw Grease Pencil - screen space only */ draw_image_grease_pencil((bContext *)C, 0); - + /* scrollers? */ #if 0 scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_UNIT_VALUES, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY); diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index dd21fca93ce..0eec61f599e 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -1151,155 +1151,155 @@ static short draw_sensorbuttons(Object *ob, bSensor *sens, uiBlock *block, short uiBut *but; short ysize; const char *str; - + /* yco is at the top of the rect, draw downwards */ - + set_col_sensor(sens->type, 0); - + switch (sens->type) { - case SENS_ALWAYS: + case SENS_ALWAYS: { ysize= 24; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + draw_default_sensor_header(sens, block, xco, yco, width); - + yco-= ysize; - + break; } - case SENS_TOUCH: + case SENS_TOUCH: { - ysize= 48; - - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + ysize= 48; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + draw_default_sensor_header(sens, block, xco, yco, width); - - ts= sens->data; - + + ts= sens->data; + // uiDefBut(block, TEX, 1, "Property:", xco, yco-22, width, 19, &ts->name, 0, MAX_NAME, 0, 0, "Only look for Objects with this property"); uiDefIDPoinBut(block, test_matpoin_but, ID_MA, 1, "MA:", (short)(xco + 10), (short)(yco-44), (short)(width - 20), 19, &ts->ma, "Only look for floors with this Material"); // uiDefButF(block, NUM, 1, "Margin:", xco+width/2, yco-44, width/2, 19, &ts->dist, 0.0, 10.0, 100, 0, "Extra margin (distance) for larger sensitivity"); - yco-= ysize; - break; + yco-= ysize; + break; } - case SENS_COLLISION: + case SENS_COLLISION: { ysize= 48; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + draw_default_sensor_header(sens, block, xco, yco, width); cs= sens->data; - + /* The collision sensor will become a generic collision (i.e. it */ /* absorb the old touch sensor). */ uiDefButBitS(block, TOG, SENS_COLLISION_PULSE, B_REDR, "Pulse", (short)(xco + 10), (short)(yco - 44), - (short)(0.20 * (width-20)), 19, &cs->mode, 0.0, 0.0, 0, 0, - "Changes to the set of colliding objects generated pulses"); - + (short)(0.20 * (width-20)), 19, &cs->mode, 0.0, 0.0, 0, 0, + "Changes to the set of colliding objects generated pulses"); + uiDefButBitS(block, TOG, SENS_COLLISION_MATERIAL, B_REDR, "M/P", (short)(xco + 10 + (0.20 * (width-20))), (short)(yco - 44), - (short)(0.20 * (width-20)), 19, &cs->mode, 0.0, 0.0, 0, 0, - "Toggle collision on material or property"); - + (short)(0.20 * (width-20)), 19, &cs->mode, 0.0, 0.0, 0, 0, + "Toggle collision on material or property"); + if (cs->mode & SENS_COLLISION_MATERIAL) { uiDefBut(block, TEX, 1, "Material:", (short)(xco + 10 + 0.40 * (width-20)), - (short)(yco-44), (short)(0.6*(width-20)), 19, &cs->materialName, 0, MAX_NAME, 0, 0, - "Only look for Objects with this material"); + (short)(yco-44), (short)(0.6*(width-20)), 19, &cs->materialName, 0, MAX_NAME, 0, 0, + "Only look for Objects with this material"); } else { uiDefBut(block, TEX, 1, "Property:", (short)(xco + 10 + 0.40 * (width-20)), (short)(yco-44), - (short)(0.6*(width-20)), 19, &cs->name, 0, MAX_NAME, 0, 0, - "Only look for Objects with this property"); + (short)(0.6*(width-20)), 19, &cs->name, 0, MAX_NAME, 0, 0, + "Only look for Objects with this property"); } - + /* uiDefButS(block, NUM, 1, "Damp:", xco+10+width-90, yco-24, 70, 19, &cs->damp, 0, 250, 0, 0, "For 'damp' time don't detect another collision"); */ - + yco-= ysize; break; } - case SENS_NEAR: + case SENS_NEAR: { ysize= 72; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + draw_default_sensor_header(sens, block, xco, yco, width); ns= sens->data; - + uiDefBut(block, TEX, 1, "Property:", (short)(10+xco), (short)(yco-44), (short)(width-20), 19, - &ns->name, 0, MAX_NAME, 0, 0, "Only look for Objects with this property"); + &ns->name, 0, MAX_NAME, 0, 0, "Only look for Objects with this property"); uiDefButF(block, NUM, 1, "Dist", (short)(10+xco), (short)(yco-68), (short)((width-22)/2), 19, - &ns->dist, 0.0, 1000.0, 1000, 0, "Trigger distance"); + &ns->dist, 0.0, 1000.0, 1000, 0, "Trigger distance"); uiDefButF(block, NUM, 1, "Reset", (short)(10+xco+(width-22)/2), (short)(yco-68), (short)((width-22)/2), 19, - &ns->resetdist, 0.0, 1000.0, 1000, 0, "Reset distance"); + &ns->resetdist, 0.0, 1000.0, 1000, 0, "Reset distance"); yco-= ysize; break; } - case SENS_RADAR: + case SENS_RADAR: { - ysize= 72; - + ysize= 72; + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + draw_default_sensor_header(sens, block, xco, yco, width); - + rs= sens->data; - + uiDefBut(block, TEX, 1, "Prop:", - (short)(10+xco), (short)(yco-44), (short)(0.7 * (width-20)), 19, - &rs->name, 0, MAX_NAME, 0, 0, - "Only look for Objects with this property"); + (short)(10+xco), (short)(yco-44), (short)(0.7 * (width-20)), 19, + &rs->name, 0, MAX_NAME, 0, 0, + "Only look for Objects with this property"); - str = "Type %t|+X axis %x0|+Y axis %x1|+Z axis %x2|-X axis %x3|-Y axis %x4|-Z axis %x5"; + str = "Type %t|+X axis %x0|+Y axis %x1|+Z axis %x2|-X axis %x3|-Y axis %x4|-Z axis %x5"; uiDefButS(block, MENU, B_REDR, str, - (short)(10+xco+0.7 * (width-20)), (short)(yco-44), (short)(0.3 * (width-22)), 19, - &rs->axis, 2.0, 31, 0, 0, - "Specify along which axis the radar cone is cast"); - + (short)(10+xco+0.7 * (width-20)), (short)(yco-44), (short)(0.3 * (width-22)), 19, + &rs->axis, 2.0, 31, 0, 0, + "Specify along which axis the radar cone is cast"); + uiDefButF(block, NUM, 1, "Ang:", - (short)(10+xco), (short)(yco-68), (short)((width-20)/2), 19, - &rs->angle, 0.0, 179.9, 10, 0, - "Opening angle of the radar cone"); + (short)(10+xco), (short)(yco-68), (short)((width-20)/2), 19, + &rs->angle, 0.0, 179.9, 10, 0, + "Opening angle of the radar cone"); uiDefButF(block, NUM, 1, "Dist:", - (short)(xco+10 + (width-20)/2), (short)(yco-68), (short)((width-20)/2), 19, - &rs->range, 0.01, 10000.0, 100, 0, - "Depth of the radar cone"); + (short)(xco+10 + (width-20)/2), (short)(yco-68), (short)((width-20)/2), 19, + &rs->range, 0.01, 10000.0, 100, 0, + "Depth of the radar cone"); yco-= ysize; break; } - case SENS_KEYBOARD: + case SENS_KEYBOARD: { ks= sens->data; - + /* 5 lines: 120 height */ ysize= (ks->type&1) ? 96:120; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + /* header line */ draw_default_sensor_header(sens, block, xco, yco, width); - + /* part of line 1 */ uiDefBut(block, LABEL, 0, "Key", xco, yco-44, 40, 19, NULL, 0, 0, 0, 0, ""); uiDefButBitS(block, TOG, 1, B_REDR, "All keys", xco+40+(width/2), yco-44, (width/2)-50, 19, - &ks->type, 0, 0, 0, 0, ""); - - + &ks->type, 0, 0, 0, 0, ""); + + if ((ks->type&1)==0) { /* is All Keys option off? */ /* line 2: hotkey and allkeys toggle */ but = uiDefKeyevtButS(block, 0, "", xco+40, yco-44, (width)/2, 19, &ks->key, "Key code"); uiButSetFunc(but, test_keyboard_event, ks, NULL); - + /* line 3: two key modifyers (qual1, qual2) */ uiDefBut(block, LABEL, 0, "Hold", xco, yco-68, 40, 19, NULL, 0, 0, 0, 0, ""); but = uiDefKeyevtButS(block, 0, "", xco+40, yco-68, (width-50)/2, 19, &ks->qual, "Modifier key code"); @@ -1307,50 +1307,50 @@ static short draw_sensorbuttons(Object *ob, bSensor *sens, uiBlock *block, short but = uiDefKeyevtButS(block, 0, "", xco+40+(width-50)/2, yco-68, (width-50)/2, 19, &ks->qual2, "Second Modifier key code"); uiButSetFunc(but, test_keyboard_event, ks, NULL); } - + /* line 4: toggle property for string logging mode */ uiDefBut(block, TEX, 1, "LogToggle: ", - xco+10, yco-((ks->type&1) ? 68:92), (width-20), 19, - ks->toggleName, 0, MAX_NAME, 0, 0, - "Property that indicates whether to log " - "keystrokes as a string"); - + xco+10, yco-((ks->type&1) ? 68:92), (width-20), 19, + ks->toggleName, 0, MAX_NAME, 0, 0, + "Property that indicates whether to log " + "keystrokes as a string"); + /* line 5: target property for string logging mode */ uiDefBut(block, TEX, 1, "Target: ", - xco+10, yco-((ks->type&1) ? 92:116), (width-20), 19, - ks->targetName, 0, MAX_NAME, 0, 0, - "Property that receives the keystrokes in case " - "a string is logged"); - + xco+10, yco-((ks->type&1) ? 92:116), (width-20), 19, + ks->targetName, 0, MAX_NAME, 0, 0, + "Property that receives the keystrokes in case " + "a string is logged"); + yco-= ysize; break; } - case SENS_PROPERTY: + case SENS_PROPERTY: { ysize= 96; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, - (float)xco+width, (float)yco, 1); - + (float)xco+width, (float)yco, 1); + draw_default_sensor_header(sens, block, xco, yco, width); ps= sens->data; - - str= "Type %t|Equal %x0|Not Equal %x1|Interval %x2|Changed %x3"; + + str= "Type %t|Equal %x0|Not Equal %x1|Interval %x2|Changed %x3"; /* str= "Type %t|Equal %x0|Not Equal %x1"; */ uiDefButI(block, MENU, B_REDR, str, xco+30, yco-44, width-60, 19, - &ps->type, 0, 31, 0, 0, "Type"); - + &ps->type, 0, 31, 0, 0, "Type"); + if (ps->type != SENS_PROP_EXPRESSION) { uiDefBut(block, TEX, 1, "Prop: ", xco+30, yco-68, width-60, 19, - ps->name, 0, MAX_NAME, 0, 0, "Property name"); + ps->name, 0, MAX_NAME, 0, 0, "Property name"); } - + if (ps->type == SENS_PROP_INTERVAL) { uiDefBut(block, TEX, 1, "Min: ", xco, yco-92, width/2, 19, - ps->value, 0, MAX_NAME, 0, 0, "check for min value"); + ps->value, 0, MAX_NAME, 0, 0, "check for min value"); uiDefBut(block, TEX, 1, "Max: ", xco+width/2, yco-92, width/2, 19, - ps->maxvalue, 0, MAX_NAME, 0, 0, "check for max value"); + ps->maxvalue, 0, MAX_NAME, 0, 0, "check for max value"); } else if (ps->type == SENS_PROP_CHANGED) { /* pass */ @@ -1359,199 +1359,199 @@ static short draw_sensorbuttons(Object *ob, bSensor *sens, uiBlock *block, short uiDefBut(block, TEX, 1, "Value: ", xco+30, yco-92, width-60, 19, ps->value, 0, MAX_NAME, 0, 0, "check for value"); } - + yco-= ysize; break; } - case SENS_ARMATURE: + case SENS_ARMATURE: { ysize= 70; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, - (float)xco+width, (float)yco, 1); - + (float)xco+width, (float)yco, 1); + draw_default_sensor_header(sens, block, xco, yco, width); arm= sens->data; if (ob->type == OB_ARMATURE) { uiBlockBeginAlign(block); but = uiDefBut(block, TEX, 1, "Bone: ", - (xco+10), (yco-44), (width-20)/2, 19, - arm->posechannel, 0, MAX_NAME, 0, 0, - "Bone on which you want to check a constraint"); + (xco+10), (yco-44), (width-20)/2, 19, + arm->posechannel, 0, MAX_NAME, 0, 0, + "Bone on which you want to check a constraint"); uiButSetFunc(but, check_armature_sensor, but, arm); but = uiDefBut(block, TEX, 1, "Cons: ", - (xco+10)+(width-20)/2, (yco-44), (width-20)/2, 19, - arm->constraint, 0, MAX_NAME, 0, 0, - "Name of the constraint you want to control"); + (xco+10)+(width-20)/2, (yco-44), (width-20)/2, 19, + arm->constraint, 0, MAX_NAME, 0, 0, + "Name of the constraint you want to control"); uiButSetFunc(but, check_armature_sensor, but, arm); uiBlockEndAlign(block); - str= "Type %t|State changed %x0|Lin error below %x1|Lin error above %x2|Rot error below %x3|Rot error above %x4"; + str= "Type %t|State changed %x0|Lin error below %x1|Lin error above %x2|Rot error below %x3|Rot error above %x4"; uiDefButI(block, MENU, B_REDR, str, xco+10, yco-66, 0.4*(width-20), 19, - &arm->type, 0, 31, 0, 0, "Type"); - + &arm->type, 0, 31, 0, 0, "Type"); + if (arm->type != SENS_ARM_STATE_CHANGED) { uiDefButF(block, NUM, 1, "Value: ", xco+10+0.4*(width-20), yco-66, 0.6*(width-20), 19, - &arm->value, -10000.0, 10000.0, 100, 0, "Test the error against this value"); + &arm->value, -10000.0, 10000.0, 100, 0, "Test the error against this value"); } } yco-= ysize; break; } - case SENS_ACTUATOR: + case SENS_ACTUATOR: { ysize= 48; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, - (float)xco+width, (float)yco, 1); - + (float)xco+width, (float)yco, 1); + draw_default_sensor_header(sens, block, xco, yco, width); as= sens->data; - + uiDefBut(block, TEX, 1, "Act: ", xco+30, yco-44, width-60, 19, - as->name, 0, MAX_NAME, 0, 0, "Actuator name, actuator active state modifications will be detected"); + as->name, 0, MAX_NAME, 0, 0, "Actuator name, actuator active state modifications will be detected"); yco-= ysize; break; } - case SENS_DELAY: + case SENS_DELAY: { ysize= 48; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, - (float)xco+width, (float)yco, 1); - + (float)xco+width, (float)yco, 1); + draw_default_sensor_header(sens, block, xco, yco, width); ds = sens->data; - + uiDefButS(block, NUM, 0, "Delay", (short)(10+xco), (short)(yco-44), (short)((width-22)*0.4+10), 19, - &ds->delay, 0.0, 5000.0, 0, 0, "Delay in number of logic tics before the positive trigger (default 60 per second)"); + &ds->delay, 0.0, 5000.0, 0, 0, "Delay in number of logic tics before the positive trigger (default 60 per second)"); uiDefButS(block, NUM, 0, "Dur", (short)(10+xco+(width-22)*0.4+10), (short)(yco-44), (short)((width-22)*0.4-10), 19, - &ds->duration, 0.0, 5000.0, 0, 0, "If >0, delay in number of logic tics before the negative trigger following the positive trigger"); + &ds->duration, 0.0, 5000.0, 0, 0, "If >0, delay in number of logic tics before the negative trigger following the positive trigger"); uiDefButBitS(block, TOG, SENS_DELAY_REPEAT, 0, "REP", (short)(xco + 10 + (width-22)*0.8), (short)(yco - 44), - (short)(0.20 * (width-22)), 19, &ds->flag, 0.0, 0.0, 0, 0, - "Toggle repeat option. If selected, the sensor restarts after Delay+Dur logic tics"); + (short)(0.20 * (width-22)), 19, &ds->flag, 0.0, 0.0, 0, 0, + "Toggle repeat option. If selected, the sensor restarts after Delay+Dur logic tics"); yco-= ysize; break; } - case SENS_MOUSE: + case SENS_MOUSE: { ms= sens->data; /* Two lines: 48 pixels high. */ ysize = 48; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + /* line 1: header */ draw_default_sensor_header(sens, block, xco, yco, width); - + /* Line 2: type selection. The number are a bit mangled to get * proper compatibility with older .blend files. */ /* Any sensor type default is 0 but the ms enum starts in 1. * Therefore the mouse sensor is initialized to 1 in sca.c */ str= "Type %t|Left button %x1|Middle button %x2|" - "Right button %x4|Wheel Up %x5|Wheel Down %x6|Movement %x8|Mouse over %x16|Mouse over any%x32"; + "Right button %x4|Wheel Up %x5|Wheel Down %x6|Movement %x8|Mouse over %x16|Mouse over any%x32"; uiDefButS(block, MENU, B_REDR, str, xco+10, yco-44, (width*0.8f)-20, 19, - &ms->type, 0, 31, 0, 0, - "Specify the type of event this mouse sensor should trigger on"); - + &ms->type, 0, 31, 0, 0, + "Specify the type of event this mouse sensor should trigger on"); + if (ms->type==32) { uiDefButBitS(block, TOG, SENS_MOUSE_FOCUS_PULSE, B_REDR, "Pulse", (short)(xco + 10) + (width*0.8f)-20, (short)(yco - 44), - (short)(0.20 * (width-20)), 19, &ms->flag, 0.0, 0.0, 0, 0, - "Moving the mouse over a different object generates a pulse"); + (short)(0.20 * (width-20)), 19, &ms->flag, 0.0, 0.0, 0, 0, + "Moving the mouse over a different object generates a pulse"); } - + yco-= ysize; break; } - case SENS_RANDOM: + case SENS_RANDOM: { ysize = 48; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + draw_default_sensor_header(sens, block, xco, yco, width); randomSensor = sens->data; /* some files were wrongly written, avoid crash now */ if (randomSensor) { uiDefButI(block, NUM, 1, "Seed: ", xco+10, yco-44, (width-20), 19, - &randomSensor->seed, 0, 1000, 0, 0, - "Initial seed of the generator. (Choose 0 for not random)"); + &randomSensor->seed, 0, 1000, 0, 0, + "Initial seed of the generator. (Choose 0 for not random)"); } yco-= ysize; break; } - case SENS_RAY: + case SENS_RAY: { ysize = 72; glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + draw_default_sensor_header(sens, block, xco, yco, width); raySens = sens->data; - + /* 1. property or material */ uiDefButBitS(block, TOG, SENS_COLLISION_MATERIAL, B_REDR, "M/P", - xco + 10, yco - 44, 0.20 * (width-20), 19, - &raySens->mode, 0.0, 0.0, 0, 0, - "Toggle collision on material or property"); - + xco + 10, yco - 44, 0.20 * (width-20), 19, + &raySens->mode, 0.0, 0.0, 0, 0, + "Toggle collision on material or property"); + if (raySens->mode & SENS_COLLISION_MATERIAL) { uiDefBut(block, TEX, 1, "Material:", xco + 10 + 0.20 * (width-20), yco-44, 0.8*(width-20), 19, - &raySens->matname, 0, MAX_NAME, 0, 0, - "Only look for Objects with this material"); + &raySens->matname, 0, MAX_NAME, 0, 0, + "Only look for Objects with this material"); } else { uiDefBut(block, TEX, 1, "Property:", xco + 10 + 0.20 * (width-20), yco-44, 0.8*(width-20), 19, - &raySens->propname, 0, MAX_NAME, 0, 0, - "Only look for Objects with this property"); + &raySens->propname, 0, MAX_NAME, 0, 0, + "Only look for Objects with this property"); } /* X-Ray option */ uiDefButBitS(block, TOG, SENS_RAY_XRAY, 1, "X", - xco + 10, yco - 68, 0.10 * (width-20), 19, - &raySens->mode, 0.0, 0.0, 0, 0, - "Toggle X-Ray option (see through objects that don't have the property)"); + xco + 10, yco - 68, 0.10 * (width-20), 19, + &raySens->mode, 0.0, 0.0, 0, 0, + "Toggle X-Ray option (see through objects that don't have the property)"); /* 2. sensing range */ uiDefButF(block, NUM, 1, "Range", xco+10 + 0.10 * (width-20), yco-68, 0.5 * (width-20), 19, - &raySens->range, 0.01, 10000.0, 100, 0, - "Sense objects no farther than this distance"); - + &raySens->range, 0.01, 10000.0, 100, 0, + "Sense objects no farther than this distance"); + /* 3. axis choice */ - str = "Type %t|+ X axis %x1|+ Y axis %x0|+ Z axis %x2|- X axis %x3|- Y axis %x4|- Z axis %x5"; + str = "Type %t|+ X axis %x1|+ Y axis %x0|+ Z axis %x2|- X axis %x3|- Y axis %x4|- Z axis %x5"; uiDefButI(block, MENU, B_REDR, str, xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19, - &raySens->axisflag, 2.0, 31, 0, 0, - "Specify along which axis the ray is cast"); - - yco-= ysize; + &raySens->axisflag, 2.0, 31, 0, 0, + "Specify along which axis the ray is cast"); + + yco-= ysize; break; } - case SENS_MESSAGE: + case SENS_MESSAGE: { mes = sens->data; ysize = 2 * 24; /* total number of lines * 24 pixels/line */ - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, - (float)xco+width, (float)yco, 1); - + (float)xco+width, (float)yco, 1); + /* line 1: header line */ draw_default_sensor_header(sens, block, xco, yco, width); - + /* line 2: Subject filter */ uiDefBut(block, TEX, 1, "Subject: ", - (xco+10), (yco-44), (width-20), 19, - mes->subject, 0, MAX_NAME, 0, 0, - "Optional subject filter: only accept messages with this subject" - ", or empty for all"); - + (xco+10), (yco-44), (width-20), 19, + mes->subject, 0, MAX_NAME, 0, 0, + "Optional subject filter: only accept messages with this subject" + ", or empty for all"); + yco -= ysize; break; } @@ -1559,96 +1559,96 @@ static short draw_sensorbuttons(Object *ob, bSensor *sens, uiBlock *block, short { ysize = 72; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + /* line 1: header */ draw_default_sensor_header(sens, block, xco, yco, width); joy= sens->data; uiDefButC(block, NUM, 1, "Index:", xco+10, yco-44, 0.33 * (width-20), 19, - &joy->joyindex, 0, SENS_JOY_MAXINDEX-1, 100, 0, - "Specify which joystick to use"); + &joy->joyindex, 0, SENS_JOY_MAXINDEX-1, 100, 0, + "Specify which joystick to use"); - str= "Type %t|Button %x0|Axis %x1|Single Axis %x3|Hat%x2"; + str= "Type %t|Button %x0|Axis %x1|Single Axis %x3|Hat%x2"; uiDefButC(block, MENU, B_REDR, str, xco+87, yco-44, 0.26 * (width-20), 19, - &joy->type, 0, 31, 0, 0, - "The type of event this joystick sensor is triggered on"); - + &joy->type, 0, 31, 0, 0, + "The type of event this joystick sensor is triggered on"); + if (joy->type != SENS_JOY_AXIS_SINGLE) { if (joy->flag & SENS_JOY_ANY_EVENT) { switch (joy->type) { - case SENS_JOY_AXIS: - str = "All Axis Events"; - break; - case SENS_JOY_BUTTON: - str = "All Button Events"; - break; - default: - str = "All Hat Events"; - break; + case SENS_JOY_AXIS: + str = "All Axis Events"; + break; + case SENS_JOY_BUTTON: + str = "All Button Events"; + break; + default: + str = "All Hat Events"; + break; } } else { str = "All"; } - + uiDefButBitS(block, TOG, SENS_JOY_ANY_EVENT, B_REDR, str, - xco+10 + 0.475 * (width-20), yco-68, ((joy->flag & SENS_JOY_ANY_EVENT) ? 0.525 : 0.12) * (width-20), 19, - &joy->flag, 0, 0, 0, 0, - "Triggered by all events on this joysticks current type (axis/button/hat)"); + xco+10 + 0.475 * (width-20), yco-68, ((joy->flag & SENS_JOY_ANY_EVENT) ? 0.525 : 0.12) * (width-20), 19, + &joy->flag, 0, 0, 0, 0, + "Triggered by all events on this joysticks current type (axis/button/hat)"); } if (joy->type == SENS_JOY_BUTTON) { if ((joy->flag & SENS_JOY_ANY_EVENT)==0) { uiDefButI(block, NUM, 1, "Number:", xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19, - &joy->button, 0, 18, 100, 0, - "Specify which button to use"); + &joy->button, 0, 18, 100, 0, + "Specify which button to use"); } } else if (joy->type == SENS_JOY_AXIS) { uiDefButS(block, NUM, 1, "Number:", xco+10, yco-68, 0.46 * (width-20), 19, - &joy->axis, 1, 8.0, 100, 0, - "Specify which axis pair to use, 1 is useually the main direction input"); + &joy->axis, 1, 8.0, 100, 0, + "Specify which axis pair to use, 1 is useually the main direction input"); uiDefButI(block, NUM, 1, "Threshold:", xco+10 + 0.6 * (width-20), yco-44, 0.4 * (width-20), 19, - &joy->precision, 0, 32768.0, 100, 0, - "Specify the precision of the axis"); + &joy->precision, 0, 32768.0, 100, 0, + "Specify the precision of the axis"); if ((joy->flag & SENS_JOY_ANY_EVENT)==0) { - str = "Type %t|Up Axis %x1 |Down Axis %x3|Left Axis %x2|Right Axis %x0"; + str = "Type %t|Up Axis %x1 |Down Axis %x3|Left Axis %x2|Right Axis %x0"; uiDefButI(block, MENU, B_REDR, str, xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19, - &joy->axisf, 2.0, 31, 0, 0, - "The direction of the axis, use 'All Events' to receive events on any direction"); + &joy->axisf, 2.0, 31, 0, 0, + "The direction of the axis, use 'All Events' to receive events on any direction"); } } else if (joy->type == SENS_JOY_HAT) { uiDefButI(block, NUM, 1, "Number:", xco+10, yco-68, 0.46 * (width-20), 19, - &joy->hat, 1, 4.0, 100, 0, - "Specify which hat to use"); - + &joy->hat, 1, 4.0, 100, 0, + "Specify which hat to use"); + if ((joy->flag & SENS_JOY_ANY_EVENT)==0) { - str = "Direction%t|Up%x1|Down%x4|Left%x8|Right%x2|%l|Up/Right%x3|Down/Left%x12|Up/Left%x9|Down/Right%x6"; + str = "Direction%t|Up%x1|Down%x4|Left%x8|Right%x2|%l|Up/Right%x3|Down/Left%x12|Up/Left%x9|Down/Right%x6"; uiDefButI(block, MENU, 0, str, xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19, - &joy->hatf, 2.0, 31, 0, 0, - "The direction of the hat, use 'All Events' to receive events on any direction"); + &joy->hatf, 2.0, 31, 0, 0, + "The direction of the hat, use 'All Events' to receive events on any direction"); } } else { /* (joy->type == SENS_JOY_AXIS_SINGLE)*/ uiDefButS(block, NUM, 1, "Number:", xco+10, yco-68, 0.46 * (width-20), 19, - &joy->axis_single, 1, 16.0, 100, 0, - "Specify a single axis (verticle/horizontal/other) to detect"); - + &joy->axis_single, 1, 16.0, 100, 0, + "Specify a single axis (verticle/horizontal/other) to detect"); + uiDefButI(block, NUM, 1, "Threshold:", xco+10 + 0.6 * (width-20), yco-44, 0.4 * (width-20), 19, - &joy->precision, 0, 32768.0, 100, 0, - "Specify the precision of the axis"); + &joy->precision, 0, 32768.0, 100, 0, + "Specify the precision of the axis"); } yco-= ysize; break; } } - + return yco-4; } @@ -1859,7 +1859,7 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo set_col_actuator(act->type, 0); switch (act->type) { - case ACT_OBJECT: + case ACT_OBJECT: { oa = act->data; wval = (width-100)/3; @@ -1890,7 +1890,7 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo uiDefButBitS(block, TOG, ACT_DLOC_LOCAL, 0, "L", xco+45+3*wval, yco-45, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); uiDefButBitS(block, TOG, ACT_DROT_LOCAL, 0, "L", xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - + if (ob->gameflag & OB_DYNAMIC) { uiDefBut(block, LABEL, 0, "Force", xco, yco-87, 55, 19, NULL, 0, 0, 0, 0, "Sets the force"); uiBlockBeginAlign(block); @@ -1903,7 +1903,7 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo uiBlockBeginAlign(block); uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, ""); uiBlockEndAlign(block); } @@ -1914,14 +1914,14 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo uiDefButF(block, NUM, 0, "", xco+45+wval, yco-129, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-129, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, ""); uiBlockEndAlign(block); - + uiDefBut(block, LABEL, 0, "AngV", xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity"); uiBlockBeginAlign(block); uiDefButF(block, NUM, 0, "", xco+45, yco-148, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45+wval, yco-148, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-148, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, ""); uiBlockEndAlign(block); - + uiDefBut(block, LABEL, 0, "Damp", xco, yco-171, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity"); uiDefButS(block, NUM, 0, "", xco+45, yco-171, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, ""); @@ -1929,9 +1929,9 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo uiDefButBitS(block, TOG, ACT_TORQUE_LOCAL, 0, "L", xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-129, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); uiDefButBitS(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-148, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - + uiDefButBitS(block, TOG, ACT_ADD_LIN_VEL, 0, "use_additive", xco+45+3*wval+15, yco-129, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV"); - } + } } else if (oa->type == ACT_OBJECT_SERVO) { ysize= 195; @@ -1984,8 +1984,8 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo yco-= ysize; break; } - case ACT_ACTION: - case ACT_SHAPEACTION: + case ACT_ACTION: + case ACT_SHAPEACTION: { /* DrawAct */ #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR @@ -2010,7 +2010,7 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, 1, "AC: ", xco+10+ (width/3), yco-24, ((width/3)*2) - (20 + 60), 19, &aa->act, "Action name"); uiDefButBitS(block, TOGN, 1, 0, "Continue", xco+((width/3)*2)+20, yco-24, 60, 19, - &aa->end_reset, 0.0, 0.0, 0, 0, "Restore last frame when switching on/off, otherwise play from the start each time"); + &aa->end_reset, 0.0, 0.0, 0, 0, "Restore last frame when switching on/off, otherwise play from the start each time"); if (aa->type == ACT_ACTION_FROM_PROP) { @@ -2020,7 +2020,7 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo uiDefButF(block, NUM, 0, "Sta: ", xco+10, yco-44, (width-20)/2, 19, &aa->sta, 1.0, MAXFRAMEF, 0, 0, "Start frame"); uiDefButF(block, NUM, 0, "End: ", xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &aa->end, 1.0, MAXFRAMEF, 0, 0, "End frame"); } - + uiDefButS(block, NUM, 0, "Blendin: ", xco+10, yco-64, (width-20)/2, 19, &aa->blendin, 0.0, 32767, 0.0, 0.0, "Number of frames of motion blending"); uiDefButS(block, NUM, 0, "Priority: ", xco+10+(width-20)/2, yco-64, (width-20)/2, 19, &aa->priority, 0.0, 100.0, 0.0, 0.0, "Execution priority - lower numbers will override actions with higher numbers, With 2 or more actions at once, the overriding channels must be lower in the stack"); @@ -2038,7 +2038,7 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo yco-=ysize; break; } - case ACT_IPO: + case ACT_IPO: { ia= act->data; @@ -2051,55 +2051,55 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo uiDefButS(block, MENU, B_REDR, str, xco+10, yco-24, (width-20)/2, 19, &ia->type, 0, 0, 0, 0, ""); - but = uiDefButBitS(block, TOG, ACT_IPOFORCE, ACT_IPOFORCE, - "Force", xco+10+(width-20)/2, yco-24, (width-20)/4-10, 19, - &ia->flag, 0, 0, 0, 0, - "Apply Ipo as a global or local force depending on the local option (dynamic objects only)"); + but = uiDefButBitS(block, TOG, ACT_IPOFORCE, ACT_IPOFORCE, + "Force", xco+10+(width-20)/2, yco-24, (width-20)/4-10, 19, + &ia->flag, 0, 0, 0, 0, + "Apply Ipo as a global or local force depending on the local option (dynamic objects only)"); uiButSetFunc(but, change_ipo_actuator, but, ia); - but = uiDefButBitS(block, TOG, ACT_IPOADD, ACT_IPOADD, - "Add", xco+3*(width-20)/4, yco-24, (width-20)/4-10, 19, - &ia->flag, 0, 0, 0, 0, - "Ipo is added to the current loc/rot/scale in global or local coordinate according to Local flag"); + but = uiDefButBitS(block, TOG, ACT_IPOADD, ACT_IPOADD, + "Add", xco+3*(width-20)/4, yco-24, (width-20)/4-10, 19, + &ia->flag, 0, 0, 0, 0, + "Ipo is added to the current loc/rot/scale in global or local coordinate according to Local flag"); uiButSetFunc(but, change_ipo_actuator, but, ia); /* Only show the do-force-local toggle if force is requested */ if (ia->flag & (ACT_IPOFORCE|ACT_IPOADD)) { - uiDefButBitS(block, TOG, ACT_IPOLOCAL, 0, - "L", xco+width-30, yco-24, 20, 19, - &ia->flag, 0, 0, 0, 0, - "Let the ipo acts in local coordinates, used in Force and Add mode"); + uiDefButBitS(block, TOG, ACT_IPOLOCAL, 0, + "L", xco+width-30, yco-24, 20, 19, + &ia->flag, 0, 0, 0, 0, + "Let the ipo acts in local coordinates, used in Force and Add mode"); } if (ia->type==ACT_IPO_FROM_PROP) { - uiDefBut(block, TEX, 0, - "Prop: ", xco+10, yco-44, width-80, 19, - ia->name, 0.0, MAX_NAME, 0, 0, - "Use this property to define the Ipo position"); + uiDefBut(block, TEX, 0, + "Prop: ", xco+10, yco-44, width-80, 19, + ia->name, 0.0, MAX_NAME, 0, 0, + "Use this property to define the Ipo position"); } else { - uiDefButF(block, NUM, 0, - "Sta", xco+10, yco-44, (width-80)/2, 19, - &ia->sta, 1.0, MAXFRAMEF, 0, 0, - "Start frame"); - uiDefButF(block, NUM, 0, - "End", xco+10+(width-80)/2, yco-44, (width-80)/2, 19, - &ia->end, 1.0, MAXFRAMEF, 0, 0, - "End frame"); + uiDefButF(block, NUM, 0, + "Sta", xco+10, yco-44, (width-80)/2, 19, + &ia->sta, 1.0, MAXFRAMEF, 0, 0, + "Start frame"); + uiDefButF(block, NUM, 0, + "End", xco+10+(width-80)/2, yco-44, (width-80)/2, 19, + &ia->end, 1.0, MAXFRAMEF, 0, 0, + "End frame"); } - uiDefButBitS(block, TOG, ACT_IPOCHILD, B_REDR, - "Child", xco+10+(width-80), yco-44, 60, 19, - &ia->flag, 0, 0, 0, 0, - "Update IPO on all children Objects as well"); - uiDefBut(block, TEX, 0, - "FrameProp: ", xco+10, yco-64, width-20, 19, - ia->frameProp, 0.0, MAX_NAME, 0, 0, - "Assign the action's current frame number to this property"); + uiDefButBitS(block, TOG, ACT_IPOCHILD, B_REDR, + "Child", xco+10+(width-80), yco-44, 60, 19, + &ia->flag, 0, 0, 0, 0, + "Update IPO on all children Objects as well"); + uiDefBut(block, TEX, 0, + "FrameProp: ", xco+10, yco-64, width-20, 19, + ia->frameProp, 0.0, MAX_NAME, 0, 0, + "Assign the action's current frame number to this property"); yco-= ysize; break; } - case ACT_PROPERTY: + case ACT_PROPERTY: { ysize= 68; @@ -2129,7 +2129,7 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo break; } - case ACT_SOUND: + case ACT_SOUND: { sa = act->data; sa->sndnr = 0; @@ -2193,743 +2193,743 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo } } MEM_freeN((void *)str); - } + } else { uiDefButO(block, BUT, "sound.open", 0, "Load Sound", xco+10, yco-22, width-20, 19, "Load a sound file"); } - + yco-= ysize; break; } - case ACT_CAMERA: + case ACT_CAMERA: - ysize= 48; + ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - ca= act->data; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-24, (width-20)/2, 19, &(ca->ob), "Look at this Object"); - uiDefButF(block, NUM, 0, "Height:", xco+10+(width-20)/2, yco-24, (width-20)/2, 19, &ca->height, 0.0, 20.0, 0, 0, ""); - - uiDefButF(block, NUM, 0, "Min:", xco+10, yco-44, (width-60)/2, 19, &ca->min, 0.0, 20.0, 0, 0, ""); - - if (ca->axis==0) ca->axis= 'x'; - uiDefButS(block, ROW, 0, "X", xco+10+(width-60)/2, yco-44, 20, 19, &ca->axis, 4.0, (float)'x', 0, 0, "Camera tries to get behind the X axis"); - uiDefButS(block, ROW, 0, "Y", xco+30+(width-60)/2, yco-44, 20, 19, &ca->axis, 4.0, (float)'y', 0, 0, "Camera tries to get behind the Y axis"); - - uiDefButF(block, NUM, 0, "Max:", xco+20+(width)/2, yco-44, (width-60)/2, 19, &ca->max, 0.0, 20.0, 0, 0, ""); + ca= act->data; - yco-= ysize; + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-24, (width-20)/2, 19, &(ca->ob), "Look at this Object"); + uiDefButF(block, NUM, 0, "Height:", xco+10+(width-20)/2, yco-24, (width-20)/2, 19, &ca->height, 0.0, 20.0, 0, 0, ""); - break; + uiDefButF(block, NUM, 0, "Min:", xco+10, yco-44, (width-60)/2, 19, &ca->min, 0.0, 20.0, 0, 0, ""); - case ACT_EDIT_OBJECT: - - eoa= act->data; + if (ca->axis==0) ca->axis= 'x'; + uiDefButS(block, ROW, 0, "X", xco+10+(width-60)/2, yco-44, 20, 19, &ca->axis, 4.0, (float)'x', 0, 0, "Camera tries to get behind the X axis"); + uiDefButS(block, ROW, 0, "Y", xco+30+(width-60)/2, yco-44, 20, 19, &ca->axis, 4.0, (float)'y', 0, 0, "Camera tries to get behind the Y axis"); - if (eoa->type==ACT_EDOB_ADD_OBJECT) { - ysize = 92; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + uiDefButF(block, NUM, 0, "Max:", xco+20+(width)/2, yco-44, (width-60)/2, 19, &ca->max, 0.0, 20.0, 0, 0, ""); + + yco-= ysize; + + break; + + case ACT_EDIT_OBJECT: + + eoa= act->data; + + if (eoa->type==ACT_EDOB_ADD_OBJECT) { + ysize = 92; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Add this Object and all its children (cant be on an visible layer)"); + uiDefButI(block, NUM, 0, "Time:", xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the new Object lives"); + + wval= (width-60)/3; + uiDefBut(block, LABEL, 0, "linV", xco, yco-68, 45, 19, + NULL, 0, 0, 0, 0, + "Velocity upon creation"); + uiDefButF(block, NUM, 0, "", xco+45, yco-68, wval, 19, + eoa->linVelocity, -100.0, 100.0, 10, 0, + "Velocity upon creation, x component"); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-68, wval, 19, + eoa->linVelocity+1, -100.0, 100.0, 10, 0, + "Velocity upon creation, y component"); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-68, wval, 19, + eoa->linVelocity+2, -100.0, 100.0, 10, 0, + "Velocity upon creation, z component"); + uiDefButBitS(block, TOG, ACT_EDOB_LOCAL_LINV, 0, "L", xco+45+3*wval, yco-68, 15, 19, + &eoa->localflag, 0.0, 0.0, 0, 0, + "Apply the transformation locally"); + + + uiDefBut(block, LABEL, 0, "AngV", xco, yco-90, 45, 19, + NULL, 0, 0, 0, 0, + "Angular velocity upon creation"); + uiDefButF(block, NUM, 0, "", xco+45, yco-90, wval, 19, + eoa->angVelocity, -10000.0, 10000.0, 10, 0, + "Angular velocity upon creation, x component"); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-90, wval, 19, + eoa->angVelocity+1, -10000.0, 10000.0, 10, 0, + "Angular velocity upon creation, y component"); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-90, wval, 19, + eoa->angVelocity+2, -10000.0, 10000.0, 10, 0, + "Angular velocity upon creation, z component"); + uiDefButBitS(block, TOG, ACT_EDOB_LOCAL_ANGV, 0, "L", xco+45+3*wval, yco-90, 15, 19, + &eoa->localflag, 0.0, 0.0, 0, 0, + "Apply the rotation locally"); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Add this Object and all its children (cant be on an visible layer)"); - uiDefButI(block, NUM, 0, "Time:", xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the new Object lives"); - - wval= (width-60)/3; - uiDefBut(block, LABEL, 0, "linV", xco, yco-68, 45, 19, - NULL, 0, 0, 0, 0, - "Velocity upon creation"); - uiDefButF(block, NUM, 0, "", xco+45, yco-68, wval, 19, - eoa->linVelocity, -100.0, 100.0, 10, 0, - "Velocity upon creation, x component"); - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-68, wval, 19, - eoa->linVelocity+1, -100.0, 100.0, 10, 0, - "Velocity upon creation, y component"); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-68, wval, 19, - eoa->linVelocity+2, -100.0, 100.0, 10, 0, - "Velocity upon creation, z component"); - uiDefButBitS(block, TOG, ACT_EDOB_LOCAL_LINV, 0, "L", xco+45+3*wval, yco-68, 15, 19, - &eoa->localflag, 0.0, 0.0, 0, 0, - "Apply the transformation locally"); - - - uiDefBut(block, LABEL, 0, "AngV", xco, yco-90, 45, 19, - NULL, 0, 0, 0, 0, - "Angular velocity upon creation"); - uiDefButF(block, NUM, 0, "", xco+45, yco-90, wval, 19, - eoa->angVelocity, -10000.0, 10000.0, 10, 0, - "Angular velocity upon creation, x component"); - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-90, wval, 19, - eoa->angVelocity+1, -10000.0, 10000.0, 10, 0, - "Angular velocity upon creation, y component"); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-90, wval, 19, - eoa->angVelocity+2, -10000.0, 10000.0, 10, 0, - "Angular velocity upon creation, z component"); - uiDefButBitS(block, TOG, ACT_EDOB_LOCAL_ANGV, 0, "L", xco+45+3*wval, yco-90, 15, 19, - &eoa->localflag, 0.0, 0.0, 0, 0, - "Apply the rotation locally"); - - } - else if (eoa->type==ACT_EDOB_END_OBJECT) { - ysize= 28; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - } - else if (eoa->type==ACT_EDOB_REPLACE_MESH) { - ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - uiDefIDPoinBut(block, test_meshpoin_but, ID_ME, 1, "ME:", xco+40, yco-44, (width-80)/2, 19, &(eoa->me), "replace the existing, when left blank 'Phys' will remake the existing physics mesh"); - - uiDefButBitS(block, TOGN, ACT_EDOB_REPLACE_MESH_NOGFX, 0, "Gfx", xco+40 + (width-80)/2, yco-44, (width-80)/4, 19, &eoa->flag, 0, 0, 0, 0, "Replace the display mesh"); - uiDefButBitS(block, TOG, ACT_EDOB_REPLACE_MESH_PHYS, 0, "Phys", xco+40 + (width-80)/2 +(width-80)/4, yco-44, (width-80)/4, 19, &eoa->flag, 0, 0, 0, 0, "Replace the physics mesh (triangle bounds only. compound shapes not supported)"); - } - else if (eoa->type==ACT_EDOB_TRACK_TO) { - ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Track to this Object"); - uiDefButI(block, NUM, 0, "Time:", xco+10+(width-20)/2, yco-44, (width-20)/2-40, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the tracking takes"); - uiDefButS(block, TOG, 0, "3D", xco+width-50, yco-44, 40, 19, &eoa->flag, 0.0, 0.0, 0, 0, "Enable 3D tracking"); - } - else if (eoa->type==ACT_EDOB_DYNAMICS) { - ysize= 69; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - str= "Dynamic Operation %t|Restore Dynamics %x0|Suspend Dynamics %x1|Enable Rigid Body %x2|Disable Rigid Body %x3|Set Mass %x4"; - uiDefButS(block, MENU, B_REDR, str, xco+40, yco-44, (width-80), 19, &(eoa->dyn_operation), 0.0, 0.0, 0, 0, ""); - if (eoa->dyn_operation==4) { - uiDefButF(block, NUM, 0, "", xco+40, yco-63, width-80, 19, - &eoa->mass, 0.0, 10000.0, 10, 0, - "Mass for object"); } - } - str= "Edit Object %t|Add Object %x0|End Object %x1|Replace Mesh %x2|Track to %x3|Dynamics %x4"; - uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &eoa->type, 0.0, 0.0, 0, 0, ""); + else if (eoa->type==ACT_EDOB_END_OBJECT) { + ysize= 28; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + } + else if (eoa->type==ACT_EDOB_REPLACE_MESH) { + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - yco-= ysize; + uiDefIDPoinBut(block, test_meshpoin_but, ID_ME, 1, "ME:", xco+40, yco-44, (width-80)/2, 19, &(eoa->me), "replace the existing, when left blank 'Phys' will remake the existing physics mesh"); - break; + uiDefButBitS(block, TOGN, ACT_EDOB_REPLACE_MESH_NOGFX, 0, "Gfx", xco+40 + (width-80)/2, yco-44, (width-80)/4, 19, &eoa->flag, 0, 0, 0, 0, "Replace the display mesh"); + uiDefButBitS(block, TOG, ACT_EDOB_REPLACE_MESH_PHYS, 0, "Phys", xco+40 + (width-80)/2 +(width-80)/4, yco-44, (width-80)/4, 19, &eoa->flag, 0, 0, 0, 0, "Replace the physics mesh (triangle bounds only. compound shapes not supported)"); + } + else if (eoa->type==ACT_EDOB_TRACK_TO) { + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - case ACT_CONSTRAINT: - coa= act->data; - - if (coa->type == ACT_CONST_TYPE_LOC) { - ysize= 69; + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Track to this Object"); + uiDefButI(block, NUM, 0, "Time:", xco+10+(width-20)/2, yco-44, (width-20)/2-40, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the tracking takes"); + uiDefButS(block, TOG, 0, "3D", xco+width-50, yco-44, 40, 19, &eoa->flag, 0.0, 0.0, 0, 0, "Enable 3D tracking"); + } + else if (eoa->type==ACT_EDOB_DYNAMICS) { + ysize= 69; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - /* str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4|Rot X %x8|Rot Y %x16|Rot Z %x32"; */ - /* coa->flag &= ~(63); */ - str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4"; - coa->flag &= 7; - coa->time = 0; - uiDefButS(block, MENU, 1, str, xco+10, yco-65, 70, 19, &coa->flag, 0.0, 0.0, 0, 0, ""); - - uiDefButS(block, NUM, 0, "damp", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter"); - uiDefBut(block, LABEL, 0, "Min", xco+80, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, ""); - uiDefBut(block, LABEL, 0, "Max", xco+80+(width-90)/2, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, ""); - - if (coa->flag & ACT_CONST_LOCX) fp= coa->minloc; - else if (coa->flag & ACT_CONST_LOCY) fp= coa->minloc+1; - else if (coa->flag & ACT_CONST_LOCZ) fp= coa->minloc+2; - else if (coa->flag & ACT_CONST_ROTX) fp= coa->minrot; - else if (coa->flag & ACT_CONST_ROTY) fp= coa->minrot+1; - else fp= coa->minrot+2; - - uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-90)/2, 19, fp, -2000.0, 2000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+80+(width-90)/2, yco-65, (width-90)/2, 19, fp+3, -2000.0, 2000.0, 10, 0, ""); - } - else if (coa->type == ACT_CONST_TYPE_DIST) { - ysize= 106; + str= "Dynamic Operation %t|Restore Dynamics %x0|Suspend Dynamics %x1|Enable Rigid Body %x2|Disable Rigid Body %x3|Set Mass %x4"; + uiDefButS(block, MENU, B_REDR, str, xco+40, yco-44, (width-80), 19, &(eoa->dyn_operation), 0.0, 0.0, 0, 0, ""); + if (eoa->dyn_operation==4) { + uiDefButF(block, NUM, 0, "", xco+40, yco-63, width-80, 19, + &eoa->mass, 0.0, 10000.0, 10, 0, + "Mass for object"); + } + } + str= "Edit Object %t|Add Object %x0|End Object %x1|Replace Mesh %x2|Track to %x3|Dynamics %x4"; + uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &eoa->type, 0.0, 0.0, 0, 0, ""); - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4|-X axis %x8|-Y axis %x16|-Z axis %x32"; - uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Set the direction of the ray"); - - uiDefButS(block, NUM, 0, "damp", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter"); - uiDefBut(block, LABEL, 0, "Range", xco+80, yco-45, (width-115)/2, 19, NULL, 0.0, 0.0, 0, 0, "Set the maximum length of ray"); - uiDefButBitS(block, TOG, ACT_CONST_DISTANCE, B_REDR, "Dist", xco+80+(width-115)/2, yco-45, (width-115)/2, 19, &coa->flag, 0.0, 0.0, 0, 0, "Force distance of object to point of impact of ray"); - uiDefButBitS(block, TOG, ACT_CONST_LOCAL, 0, "L", xco+80+(width-115), yco-45, 25, 19, - &coa->flag, 0.0, 0.0, 0, 0, "Set ray along object's axis or global axis"); - - if (coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRNX)) fp= coa->minloc; - else if (coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRNY)) fp= coa->minloc+1; - else fp= coa->minloc+2; - - uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-115)/2, 19, fp+3, 0.0, 2000.0, 10, 0, "Maximum length of ray"); - if (coa->flag & ACT_CONST_DISTANCE) - uiDefButF(block, NUM, 0, "", xco+80+(width-115)/2, yco-65, (width-115)/2, 19, fp, -2000.0, 2000.0, 10, 0, "Keep this distance to target"); - uiDefButBitS(block, TOG, ACT_CONST_NORMAL, 0, "N", xco+80+(width-115), yco-65, 25, 19, - &coa->flag, 0.0, 0.0, 0, 0, "Set object axis along (local axis) or parallel (global axis) to the normal at hit position"); - uiDefButBitS(block, TOG, ACT_CONST_MATERIAL, B_REDR, "M/P", xco+10, yco-84, 40, 19, - &coa->flag, 0.0, 0.0, 0, 0, "Detect material instead of property"); - if (coa->flag & ACT_CONST_MATERIAL) { - uiDefBut(block, TEX, 1, "Material:", xco + 50, yco-84, (width-60), 19, - coa->matprop, 0, MAX_NAME, 0, 0, - "Ray detects only Objects with this material"); + yco-= ysize; + + break; + + case ACT_CONSTRAINT: + coa= act->data; + + if (coa->type == ACT_CONST_TYPE_LOC) { + ysize= 69; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + /* str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4|Rot X %x8|Rot Y %x16|Rot Z %x32"; */ + /* coa->flag &= ~(63); */ + str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4"; + coa->flag &= 7; + coa->time = 0; + uiDefButS(block, MENU, 1, str, xco+10, yco-65, 70, 19, &coa->flag, 0.0, 0.0, 0, 0, ""); + + uiDefButS(block, NUM, 0, "damp", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter"); + uiDefBut(block, LABEL, 0, "Min", xco+80, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Max", xco+80+(width-90)/2, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, ""); + + if (coa->flag & ACT_CONST_LOCX) fp= coa->minloc; + else if (coa->flag & ACT_CONST_LOCY) fp= coa->minloc+1; + else if (coa->flag & ACT_CONST_LOCZ) fp= coa->minloc+2; + else if (coa->flag & ACT_CONST_ROTX) fp= coa->minrot; + else if (coa->flag & ACT_CONST_ROTY) fp= coa->minrot+1; + else fp= coa->minrot+2; + + uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-90)/2, 19, fp, -2000.0, 2000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+80+(width-90)/2, yco-65, (width-90)/2, 19, fp+3, -2000.0, 2000.0, 10, 0, ""); } - else { - uiDefBut(block, TEX, 1, "Property:", xco + 50, yco-84, (width-60), 19, - coa->matprop, 0, MAX_NAME, 0, 0, - "Ray detect only Objects with this property"); + else if (coa->type == ACT_CONST_TYPE_DIST) { + ysize= 106; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4|-X axis %x8|-Y axis %x16|-Z axis %x32"; + uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Set the direction of the ray"); + + uiDefButS(block, NUM, 0, "damp", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter"); + uiDefBut(block, LABEL, 0, "Range", xco+80, yco-45, (width-115)/2, 19, NULL, 0.0, 0.0, 0, 0, "Set the maximum length of ray"); + uiDefButBitS(block, TOG, ACT_CONST_DISTANCE, B_REDR, "Dist", xco+80+(width-115)/2, yco-45, (width-115)/2, 19, &coa->flag, 0.0, 0.0, 0, 0, "Force distance of object to point of impact of ray"); + uiDefButBitS(block, TOG, ACT_CONST_LOCAL, 0, "L", xco+80+(width-115), yco-45, 25, 19, + &coa->flag, 0.0, 0.0, 0, 0, "Set ray along object's axis or global axis"); + + if (coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRNX)) fp= coa->minloc; + else if (coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRNY)) fp= coa->minloc+1; + else fp= coa->minloc+2; + + uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-115)/2, 19, fp+3, 0.0, 2000.0, 10, 0, "Maximum length of ray"); + if (coa->flag & ACT_CONST_DISTANCE) + uiDefButF(block, NUM, 0, "", xco+80+(width-115)/2, yco-65, (width-115)/2, 19, fp, -2000.0, 2000.0, 10, 0, "Keep this distance to target"); + uiDefButBitS(block, TOG, ACT_CONST_NORMAL, 0, "N", xco+80+(width-115), yco-65, 25, 19, + &coa->flag, 0.0, 0.0, 0, 0, "Set object axis along (local axis) or parallel (global axis) to the normal at hit position"); + uiDefButBitS(block, TOG, ACT_CONST_MATERIAL, B_REDR, "M/P", xco+10, yco-84, 40, 19, + &coa->flag, 0.0, 0.0, 0, 0, "Detect material instead of property"); + if (coa->flag & ACT_CONST_MATERIAL) { + uiDefBut(block, TEX, 1, "Material:", xco + 50, yco-84, (width-60), 19, + coa->matprop, 0, MAX_NAME, 0, 0, + "Ray detects only Objects with this material"); + } + else { + uiDefBut(block, TEX, 1, "Property:", xco + 50, yco-84, (width-60), 19, + coa->matprop, 0, MAX_NAME, 0, 0, + "Ray detect only Objects with this property"); + } + uiDefButBitS(block, TOG, ACT_CONST_PERMANENT, 0, "PER", xco+10, yco-103, 40, 19, + &coa->flag, 0.0, 0.0, 0, 0, "Persistent actuator: stays active even if ray does not reach target"); + uiDefButS(block, NUM, 0, "time", xco+50, yco-103, (width-60)/2, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited"); + uiDefButS(block, NUM, 0, "rotDamp", xco+50+(width-60)/2, yco-103, (width-60)/2, 19, &(coa->rotdamp), 0.0, 100.0, 0, 0, "Use a different damping for orientation"); } - uiDefButBitS(block, TOG, ACT_CONST_PERMANENT, 0, "PER", xco+10, yco-103, 40, 19, - &coa->flag, 0.0, 0.0, 0, 0, "Persistent actuator: stays active even if ray does not reach target"); - uiDefButS(block, NUM, 0, "time", xco+50, yco-103, (width-60)/2, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited"); - uiDefButS(block, NUM, 0, "rotDamp", xco+50+(width-60)/2, yco-103, (width-60)/2, 19, &(coa->rotdamp), 0.0, 100.0, 0, 0, "Use a different damping for orientation"); - } - else if (coa->type == ACT_CONST_TYPE_ORI) { - ysize= 87; + else if (coa->type == ACT_CONST_TYPE_ORI) { + ysize= 87; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4"; - uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Select the axis to be aligned along the reference direction"); - - uiDefButS(block, NUM, 0, "damp", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter"); - uiDefBut(block, LABEL, 0, "X", xco+80, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, ""); - uiDefBut(block, LABEL, 0, "Y", xco+80+(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, ""); - uiDefBut(block, LABEL, 0, "Z", xco+80+2*(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, ""); - - uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-115)/3, 19, &coa->maxrot[0], -2000.0, 2000.0, 10, 0, "X component of reference direction"); - uiDefButF(block, NUM, 0, "", xco+80+(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[1], -2000.0, 2000.0, 10, 0, "Y component of reference direction"); - uiDefButF(block, NUM, 0, "", xco+80+2*(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[2], -2000.0, 2000.0, 10, 0, "Z component of reference direction"); - - uiDefButS(block, NUM, 0, "time", xco+10, yco-84, 70, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited"); - uiDefButF(block, NUM, 0, "min", xco+80, yco-84, (width-115)/2, 19, &(coa->minloc[0]), 0.0, 180.0, 10, 1, "Minimum angle (in degree) to maintain with target direction. No correction is done if angle with target direction is between min and max"); - uiDefButF(block, NUM, 0, "max", xco+80+(width-115)/2, yco-84, (width-115)/2, 19, &(coa->maxloc[0]), 0.0, 180.0, 10, 1, "Maximum angle (in degree) allowed with target direction. No correction is done if angle with target direction is between min and max"); - } - else if (coa->type == ACT_CONST_TYPE_FH) { - ysize= 106; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4|-X axis %x8|-Y axis %x16|-Z axis %x32"; - uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Set the direction of the ray (in world coordinate)"); - - if (coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRNX)) fp= coa->minloc; - else if (coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRNY)) fp= coa->minloc+1; - else fp= coa->minloc+2; - - uiDefButF(block, NUM, 0, "damp", xco+10, yco-45, (width-70)/2, 19, &coa->maxrot[0], 0.0, 1.0, 1, 0, "Damping factor of the Fh spring force"); - uiDefButF(block, NUM, 0, "dist", xco+10+(width-70)/2, yco-45, (width-70)/2, 19, fp, 0.010, 2000.0, 10, 0, "Height of the Fh area"); - uiDefButBitS(block, TOG, ACT_CONST_DOROTFH, 0, "Rot Fh", xco+10+(width-70), yco-45, 50, 19, &coa->flag, 0.0, 0.0, 0, 0, "Keep object axis parallel to normal"); - - uiDefButF(block, NUMSLI, 0, "Fh ", xco+80, yco-65, (width-115), 19, fp+3, 0.0, 1.0, 0, 0, "Spring force within the Fh area"); - uiDefButBitS(block, TOG, ACT_CONST_NORMAL, 0, "N", xco+80+(width-115), yco-65, 25, 19, - &coa->flag, 0.0, 0.0, 0, 0, "Add a horizontal spring force on slopes"); - uiDefButBitS(block, TOG, ACT_CONST_MATERIAL, B_REDR, "M/P", xco+10, yco-84, 40, 19, - &coa->flag, 0.0, 0.0, 0, 0, "Detect material instead of property"); - if (coa->flag & ACT_CONST_MATERIAL) { - uiDefBut(block, TEX, 1, "Material:", xco + 50, yco-84, (width-60), 19, - coa->matprop, 0, MAX_NAME, 0, 0, - "Ray detects only Objects with this material"); + str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4"; + uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Select the axis to be aligned along the reference direction"); + + uiDefButS(block, NUM, 0, "damp", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter"); + uiDefBut(block, LABEL, 0, "X", xco+80, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Y", xco+80+(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Z", xco+80+2*(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, ""); + + uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-115)/3, 19, &coa->maxrot[0], -2000.0, 2000.0, 10, 0, "X component of reference direction"); + uiDefButF(block, NUM, 0, "", xco+80+(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[1], -2000.0, 2000.0, 10, 0, "Y component of reference direction"); + uiDefButF(block, NUM, 0, "", xco+80+2*(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[2], -2000.0, 2000.0, 10, 0, "Z component of reference direction"); + + uiDefButS(block, NUM, 0, "time", xco+10, yco-84, 70, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited"); + uiDefButF(block, NUM, 0, "min", xco+80, yco-84, (width-115)/2, 19, &(coa->minloc[0]), 0.0, 180.0, 10, 1, "Minimum angle (in degree) to maintain with target direction. No correction is done if angle with target direction is between min and max"); + uiDefButF(block, NUM, 0, "max", xco+80+(width-115)/2, yco-84, (width-115)/2, 19, &(coa->maxloc[0]), 0.0, 180.0, 10, 1, "Maximum angle (in degree) allowed with target direction. No correction is done if angle with target direction is between min and max"); } - else { - uiDefBut(block, TEX, 1, "Property:", xco + 50, yco-84, (width-60), 19, - coa->matprop, 0, MAX_NAME, 0, 0, - "Ray detect only Objects with this property"); + else if (coa->type == ACT_CONST_TYPE_FH) { + ysize= 106; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4|-X axis %x8|-Y axis %x16|-Z axis %x32"; + uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Set the direction of the ray (in world coordinate)"); + + if (coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRNX)) fp= coa->minloc; + else if (coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRNY)) fp= coa->minloc+1; + else fp= coa->minloc+2; + + uiDefButF(block, NUM, 0, "damp", xco+10, yco-45, (width-70)/2, 19, &coa->maxrot[0], 0.0, 1.0, 1, 0, "Damping factor of the Fh spring force"); + uiDefButF(block, NUM, 0, "dist", xco+10+(width-70)/2, yco-45, (width-70)/2, 19, fp, 0.010, 2000.0, 10, 0, "Height of the Fh area"); + uiDefButBitS(block, TOG, ACT_CONST_DOROTFH, 0, "Rot Fh", xco+10+(width-70), yco-45, 50, 19, &coa->flag, 0.0, 0.0, 0, 0, "Keep object axis parallel to normal"); + + uiDefButF(block, NUMSLI, 0, "Fh ", xco+80, yco-65, (width-115), 19, fp+3, 0.0, 1.0, 0, 0, "Spring force within the Fh area"); + uiDefButBitS(block, TOG, ACT_CONST_NORMAL, 0, "N", xco+80+(width-115), yco-65, 25, 19, + &coa->flag, 0.0, 0.0, 0, 0, "Add a horizontal spring force on slopes"); + uiDefButBitS(block, TOG, ACT_CONST_MATERIAL, B_REDR, "M/P", xco+10, yco-84, 40, 19, + &coa->flag, 0.0, 0.0, 0, 0, "Detect material instead of property"); + if (coa->flag & ACT_CONST_MATERIAL) { + uiDefBut(block, TEX, 1, "Material:", xco + 50, yco-84, (width-60), 19, + coa->matprop, 0, MAX_NAME, 0, 0, + "Ray detects only Objects with this material"); + } + else { + uiDefBut(block, TEX, 1, "Property:", xco + 50, yco-84, (width-60), 19, + coa->matprop, 0, MAX_NAME, 0, 0, + "Ray detect only Objects with this property"); + } + uiDefButBitS(block, TOG, ACT_CONST_PERMANENT, 0, "PER", xco+10, yco-103, 40, 19, + &coa->flag, 0.0, 0.0, 0, 0, "Persistent actuator: stays active even if ray does not reach target"); + uiDefButS(block, NUM, 0, "time", xco+50, yco-103, 90, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited"); + uiDefButF(block, NUM, 0, "rotDamp", xco+140, yco-103, (width-150), 19, &coa->maxrot[1], 0.0, 1.0, 1, 0, "Use a different damping for rotation"); } - uiDefButBitS(block, TOG, ACT_CONST_PERMANENT, 0, "PER", xco+10, yco-103, 40, 19, - &coa->flag, 0.0, 0.0, 0, 0, "Persistent actuator: stays active even if ray does not reach target"); - uiDefButS(block, NUM, 0, "time", xco+50, yco-103, 90, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited"); - uiDefButF(block, NUM, 0, "rotDamp", xco+140, yco-103, (width-150), 19, &coa->maxrot[1], 0.0, 1.0, 1, 0, "Use a different damping for rotation"); - } - str= "Constraint Type %t|Location %x0|Distance %x1|Orientation %x2|Force field %x3"; - but = uiDefButS(block, MENU, B_REDR, str, xco+40, yco-23, (width-80), 19, &coa->type, 0.0, 0.0, 0, 0, ""); - yco-= ysize; - break; + str= "Constraint Type %t|Location %x0|Distance %x1|Orientation %x2|Force field %x3"; + but = uiDefButS(block, MENU, B_REDR, str, xco+40, yco-23, (width-80), 19, &coa->type, 0.0, 0.0, 0, 0, ""); + yco-= ysize; + break; - case ACT_SCENE: - sca= act->data; - - if (sca->type==ACT_SCENE_RESTART) { - ysize= 28; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - } - else if (sca->type==ACT_SCENE_CAMERA) { + case ACT_SCENE: + sca= act->data; - ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + if (sca->type==ACT_SCENE_RESTART) { + ysize= 28; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + } + else if (sca->type==ACT_SCENE_CAMERA) { - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+40, yco-44, (width-80), 19, &(sca->camera), "Set this Camera. Leave empty to refer to self object"); - } - else if (sca->type==ACT_SCENE_SET) { - - ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Set this Scene"); - } - else if (sca->type==ACT_SCENE_ADD_FRONT) { - - ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+40, yco-44, (width-80), 19, &(sca->camera), "Set this Camera. Leave empty to refer to self object"); + } + else if (sca->type==ACT_SCENE_SET) { - uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Add an Overlay Scene"); - } - else if (sca->type==ACT_SCENE_ADD_BACK) { - - ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Add a Background Scene"); - } - else if (sca->type==ACT_SCENE_REMOVE) { - - ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Set this Scene"); + } + else if (sca->type==ACT_SCENE_ADD_FRONT) { - uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Remove a Scene"); - } - else if (sca->type==ACT_SCENE_SUSPEND) { - - ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Pause a Scene"); - } - else if (sca->type==ACT_SCENE_RESUME) { - - ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Add an Overlay Scene"); + } + else if (sca->type==ACT_SCENE_ADD_BACK) { - uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Unpause a Scene"); - } + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - str= "Scene %t|Restart %x0|Set Scene %x1|Set Camera %x2|Add OverlayScene %x3|Add BackgroundScene %x4|Remove Scene %x5|Suspend Scene %x6|Resume Scene %x7"; - uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &sca->type, 0.0, 0.0, 0, 0, ""); + uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Add a Background Scene"); + } + else if (sca->type==ACT_SCENE_REMOVE) { - yco-= ysize; - break; - case ACT_GAME: + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Remove a Scene"); + } + else if (sca->type==ACT_SCENE_SUSPEND) { + + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Pause a Scene"); + } + else if (sca->type==ACT_SCENE_RESUME) { + + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Unpause a Scene"); + } + + str= "Scene %t|Restart %x0|Set Scene %x1|Set Camera %x2|Add OverlayScene %x3|Add BackgroundScene %x4|Remove Scene %x5|Suspend Scene %x6|Resume Scene %x7"; + uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &sca->type, 0.0, 0.0, 0, 0, ""); + + yco-= ysize; + break; + case ACT_GAME: { gma = act->data; if (gma->type == ACT_GAME_LOAD) { //ysize = 68; ysize = 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44, width-20, 19, &(gma->filename), 0, sizeof(gma->filename), 0, 0, "Load this blend file, use the \"//\" prefix for a path relative to the current blend file"); -// uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64, width-20, 19, &(gma->loadaniname), 0, sizeof(gma->loadaniname), 0, 0, "Use this loadinganimation"); + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44, width-20, 19, &(gma->filename), 0, sizeof(gma->filename), 0, 0, "Load this blend file, use the \"//\" prefix for a path relative to the current blend file"); + // uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64, width-20, 19, &(gma->loadaniname), 0, sizeof(gma->loadaniname), 0, 0, "Use this loadinganimation"); } #if 0 else if (gma->type == ACT_GAME_START) { - ysize = 68; - glRects(xco, yco-ysize, xco+width, yco); + ysize = 68; + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44, width-20, 19, &(gma->filename), 0, sizeof(gma->filename), 0, 0, "Load this file"); + uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44, width-20, 19, &(gma->filename), 0, sizeof(gma->filename), 0, 0, "Load this file"); uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64, width-20, 19, &(gma->loadaniname), 0, sizeof(gma->loadaniname), 0, 0, "Use this loadinganimation"); } #endif else if (ELEM4(gma->type, ACT_GAME_RESTART, ACT_GAME_QUIT, ACT_GAME_SAVECFG, ACT_GAME_LOADCFG)) { - ysize = 28; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + ysize = 28; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); } //str = "Scene %t|Load game%x0|Start loaded game%x1|Restart this game%x2|Quit this game %x3"; str = "Scene %t|Start new game%x0|Restart this game%x2|Quit this game %x3|Save bge.logic.globalDict %x4|Load bge.logic.globalDict %x5"; - uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &gma->type, 0.0, 0.0, 0, 0, ""); + uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &gma->type, 0.0, 0.0, 0, 0, ""); - yco -= ysize; - break; + yco -= ysize; + break; } - case ACT_GROUP: - ga= act->data; + case ACT_GROUP: + ga= act->data; - ysize= 52; + ysize= 52; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - str= "GroupKey types %t|Set Key %x6|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x5"; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefButS(block, MENU, 1, str, xco+20, yco-24, width-40, 19, &ga->type, 0, 0, 0, 0, ""); - if (ga->type==ACT_GROUP_SET) { - uiDefBut(block, TEX, 0, "Key: ", xco+20, yco-44, (width-10)/2, 19, ga->name, 0.0, MAX_NAME, 0, 0, "This name defines groupkey to be set"); - uiDefButI(block, NUM, 0, "Frame:", xco+20+(width-10)/2, yco-44, (width-70)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Set this frame"); - } - else if (ga->type==ACT_GROUP_FROM_PROP) { - uiDefBut(block, TEX, 0, "Prop: ", xco+20, yco-44, width-40, 19, ga->name, 0.0, MAX_NAME, 0, 0, "Use this property to define the Group position"); - } - else { - uiDefButI(block, NUM, 0, "State", xco+20, yco-44, (width-40)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Start frame"); - uiDefButI(block, NUM, 0, "End", xco+20+(width-40)/2, yco-44, (width-40)/2, 19, &ga->end, 0.0, 2500.0, 0, 0, "End frame"); - } - yco-= ysize; - break; + str= "GroupKey types %t|Set Key %x6|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x5"; - case ACT_VISIBILITY: - ysize = 24; + uiDefButS(block, MENU, 1, str, xco+20, yco-24, width-40, 19, &ga->type, 0, 0, 0, 0, ""); + if (ga->type==ACT_GROUP_SET) { + uiDefBut(block, TEX, 0, "Key: ", xco+20, yco-44, (width-10)/2, 19, ga->name, 0.0, MAX_NAME, 0, 0, "This name defines groupkey to be set"); + uiDefButI(block, NUM, 0, "Frame:", xco+20+(width-10)/2, yco-44, (width-70)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Set this frame"); + } + else if (ga->type==ACT_GROUP_FROM_PROP) { + uiDefBut(block, TEX, 0, "Prop: ", xco+20, yco-44, width-40, 19, ga->name, 0.0, MAX_NAME, 0, 0, "Use this property to define the Group position"); + } + else { + uiDefButI(block, NUM, 0, "State", xco+20, yco-44, (width-40)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Start frame"); + uiDefButI(block, NUM, 0, "End", xco+20+(width-40)/2, yco-44, (width-40)/2, 19, &ga->end, 0.0, 2500.0, 0, 0, "End frame"); + } + yco-= ysize; + break; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, - (float)yco-ysize, (float)xco+width, (float)yco, 1); - - visAct = act->data; + case ACT_VISIBILITY: + ysize = 24; - uiBlockBeginAlign(block); - uiDefButBitI(block, TOGN, ACT_VISIBILITY_INVISIBLE, B_REDR, - "Visible", - xco + 10, yco - 20, (width - 20)/3, 19, &visAct->flag, - 0.0, 0.0, 0, 0, - "Set the objects visible. Initialized from the objects render restriction toggle (access in the outliner)"); - uiDefButBitI(block, TOG, ACT_VISIBILITY_OCCLUSION, B_REDR, - "Occlusion", - xco + 10 + ((width - 20)/3), yco - 20, (width - 20)/3, 19, &visAct->flag, - 0.0, 0.0, 0, 0, - "Set the object to occlude objects behind it. Initialized from the object type in physics button"); - uiBlockEndAlign(block); - - uiDefButBitI(block, TOG, ACT_VISIBILITY_RECURSIVE, 0, - "Children", - xco + 10 + (((width - 20)/3)*2)+10, yco - 20, ((width - 20)/3)-10, 19, &visAct->flag, - 0.0, 0.0, 0, 0, - "Sets all the children of this object to the same visibility/occlusion recursively"); + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, + (float)yco-ysize, (float)xco+width, (float)yco, 1); - yco-= ysize; + visAct = act->data; - break; - - case ACT_STATE: - ysize = 34; + uiBlockBeginAlign(block); + uiDefButBitI(block, TOGN, ACT_VISIBILITY_INVISIBLE, B_REDR, + "Visible", + xco + 10, yco - 20, (width - 20)/3, 19, &visAct->flag, + 0.0, 0.0, 0, 0, + "Set the objects visible. Initialized from the objects render restriction toggle (access in the outliner)"); + uiDefButBitI(block, TOG, ACT_VISIBILITY_OCCLUSION, B_REDR, + "Occlusion", + xco + 10 + ((width - 20)/3), yco - 20, (width - 20)/3, 19, &visAct->flag, + 0.0, 0.0, 0, 0, + "Set the object to occlude objects behind it. Initialized from the object type in physics button"); + uiBlockEndAlign(block); - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, - (float)yco-ysize, (float)xco+width, (float)yco, 1); - - staAct = act->data; + uiDefButBitI(block, TOG, ACT_VISIBILITY_RECURSIVE, 0, + "Children", + xco + 10 + (((width - 20)/3)*2)+10, yco - 20, ((width - 20)/3)-10, 19, &visAct->flag, + 0.0, 0.0, 0, 0, + "Sets all the children of this object to the same visibility/occlusion recursively"); - str= "Operation %t|Cpy %x0|Add %x1|Sub %x2|Inv %x3"; + yco-= ysize; - uiDefButI(block, MENU, B_REDR, str, - xco + 10, yco - 24, 65, 19, &staAct->type, - 0.0, 0.0, 0, 0, - "Select the bit operation on object state mask"); + break; - for (wval=0; wval<15; wval+=5) { - uiBlockBeginAlign(block); - for (stbit=0; stbit<5; stbit++) { - but = uiDefButBitI(block, TOG, 1<<(stbit+wval), stbit+wval, "", (short)(xco+85+12*stbit+13*wval), yco-17, 12, 12, (int *)&(staAct->mask), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+wval))); - uiButSetFunc(but, check_state_mask, but, &(staAct->mask)); - } - for (stbit=0; stbit<5; stbit++) { - but = uiDefButBitI(block, TOG, 1<<(stbit+wval+15), stbit+wval+15, "", (short)(xco+85+12*stbit+13*wval), yco-29, 12, 12, (int *)&(staAct->mask), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+wval+15))); - uiButSetFunc(but, check_state_mask, but, &(staAct->mask)); - } - } - uiBlockEndAlign(block); + case ACT_STATE: + ysize = 34; - yco-= ysize; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, + (float)yco-ysize, (float)xco+width, (float)yco, 1); - break; + staAct = act->data; - case ACT_RANDOM: - ysize = 69; + str= "Operation %t|Cpy %x0|Add %x1|Sub %x2|Inv %x3"; + + uiDefButI(block, MENU, B_REDR, str, + xco + 10, yco - 24, 65, 19, &staAct->type, + 0.0, 0.0, 0, 0, + "Select the bit operation on object state mask"); + + for (wval=0; wval<15; wval+=5) { + uiBlockBeginAlign(block); + for (stbit=0; stbit<5; stbit++) { + but = uiDefButBitI(block, TOG, 1<<(stbit+wval), stbit+wval, "", (short)(xco+85+12*stbit+13*wval), yco-17, 12, 12, (int *)&(staAct->mask), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+wval))); + uiButSetFunc(but, check_state_mask, but, &(staAct->mask)); + } + for (stbit=0; stbit<5; stbit++) { + but = uiDefButBitI(block, TOG, 1<<(stbit+wval+15), stbit+wval+15, "", (short)(xco+85+12*stbit+13*wval), yco-29, 12, 12, (int *)&(staAct->mask), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+wval+15))); + uiButSetFunc(but, check_state_mask, but, &(staAct->mask)); + } + } + uiBlockEndAlign(block); + + yco-= ysize; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, - (float)yco-ysize, (float)xco+width, (float)yco, 1); - - randAct = act->data; - - /* 1. seed */ - uiDefButI(block, NUM, 1, "Seed: ", (xco+10), yco-24, 0.4 *(width-20), 19, - &randAct->seed, 0, 1000, 0, 0, - "Initial seed of the random generator. Use Python for more freedom. " - " (Choose 0 for not random)"); - - /* 2. distribution type */ - /* One pick per distribution. These numbers MUST match the #defines */ - /* in game.h !!! */ - str= "Distribution %t|Bool Constant %x0|Bool Uniform %x1" - "|Bool Bernoulli %x2|Int Constant %x3|Int Uniform %x4" - "|Int Poisson %x5|Float Constant %x6|Float Uniform %x7" - "|Float Normal %x8|Float Neg. Exp. %x9"; - uiDefButI(block, MENU, B_REDR, str, (xco+10) + 0.4 * (width-20), yco-24, 0.6 * (width-20), 19, - &randAct->distribution, 0.0, 0.0, 0, 0, - "Choose the type of distribution"); - - /* 3. property */ - uiDefBut(block, TEX, 1, "Property:", (xco+10), yco-44, (width-20), 19, - &randAct->propname, 0, MAX_NAME, 0, 0, - "Assign the random value to this property"); - - /*4. and 5. arguments for the distribution*/ - switch (randAct->distribution) { - case ACT_RANDOM_BOOL_CONST: - uiDefButBitI(block, TOG, 1, 1, "Always true", (xco+10), yco-64, (width-20), 19, - &randAct->int_arg_1, 2.0, 1, 0, 0, - "Always false or always true"); - break; - case ACT_RANDOM_BOOL_UNIFORM: - uiDefBut(block, LABEL, 0, " Do a 50-50 pick", (xco+10), yco-64, (width-20), 19, - NULL, 0, 0, 0, 0, - "Choose between true and false, 50% chance each"); - break; - case ACT_RANDOM_BOOL_BERNOUILLI: - uiDefButF(block, NUM, 1, "Chance", (xco+10), yco-64, (width-20), 19, - &randAct->float_arg_1, 0.0, 1.0, 0, 0, - "Pick a number between 0 and 1. Success if you stay " - "below this value"); - break; - case ACT_RANDOM_INT_CONST: - uiDefButI(block, NUM, 1, "Value: ", (xco+10), yco-64, (width-20), 19, - &randAct->int_arg_1, -1000, 1000, 0, 0, - "Always return this number"); - break; - case ACT_RANDOM_INT_UNIFORM: - uiDefButI(block, NUM, 1, "Min: ", (xco+10), yco-64, (width-20)/2, 19, - &randAct->int_arg_1, -1000, 1000, 0, 0, - "Choose a number from a range. " - "Lower boundary of the range"); - uiDefButI(block, NUM, 1, "Max: ", (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19, - &randAct->int_arg_2, -1000, 1000, 0, 0, - "Choose a number from a range. " - "Upper boundary of the range"); - break; - case ACT_RANDOM_INT_POISSON: - uiDefButF(block, NUM, 1, "Mean: ", (xco+10), yco-64, (width-20), 19, - &randAct->float_arg_1, 0.01, 100.0, 0, 0, - "Expected mean value of the distribution"); - break; - case ACT_RANDOM_FLOAT_CONST: - uiDefButF(block, NUM, 1, "Value: ", (xco+10), yco-64, (width-20), 19, - &randAct->float_arg_1, 0.0, 1.0, 0, 0, - "Always return this number"); - break; - case ACT_RANDOM_FLOAT_UNIFORM: - uiDefButF(block, NUM, 1, "Min: ", (xco+10), yco-64, (width-20)/2, 19, - &randAct->float_arg_1, -10000.0, 10000.0, 0, 0, - "Choose a number from a range" - "Lower boundary of the range"); - uiDefButF(block, NUM, 1, "Max: ", (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19, - &randAct->float_arg_2, -10000.0, 10000.0, 0, 0, - "Choose a number from a range" - "Upper boundary of the range"); - break; - case ACT_RANDOM_FLOAT_NORMAL: - uiDefButF(block, NUM, 1, "Mean: ", (xco+10), yco-64, (width-20)/2, 19, - &randAct->float_arg_1, -10000.0, 10000.0, 0, 0, - "A normal distribution. Mean of the distribution"); - uiDefButF(block, NUM, 1, "SD: ", (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19, - &randAct->float_arg_2, 0.0, 10000.0, 0, 0, - "A normal distribution. Standard deviation of the " - "distribution"); - break; - case ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL: - uiDefButF(block, NUM, 1, "Half-life time: ", (xco+10), yco-64, (width-20), 19, - &randAct->float_arg_1, 0.001, 10000.0, 0, 0, - "Negative exponential dropoff"); break; - default: - ; /* don't know what this distro is... can be useful for testing */ - /* though :) */ - } - yco-= ysize; - break; - case ACT_MESSAGE: - ma = act->data; + case ACT_RANDOM: + ysize = 69; - ysize = 4 + (3 * 24); /* footer + number of lines * 24 pixels/line */ - - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, - (float)xco+width, (float)yco, 1); - - myline=1; - - /* line 1: To */ - uiDefBut(block, TEX, 1, "To: ", - (xco+10), (yco-(myline++*24)), (width-20), 19, - &ma->toPropName, 0, MAX_NAME, 0, 0, - "Optional send message to objects with this name only, or empty to broadcast"); - - /* line 2: Message Subject */ - uiDefBut(block, TEX, 1, "Subject: ", - (xco+10), (yco-(myline++*24)), (width-20), 19, - &ma->subject, 0, MAX_NAME, 0, 0, - "Optional message subject. This is what can be filtered on"); - - /* line 3: Text/Property */ - uiDefButBitS(block, TOG, 1, B_REDR, "T/P", - (xco+10), (yco-(myline*24)), (0.20 * (width-20)), 19, - &ma->bodyType, 0.0, 0.0, 0, 0, - "Toggle message type: either Text or a PropertyName"); - - if (ma->bodyType == ACT_MESG_MESG) { - /* line 3: Message Body */ - uiDefBut(block, TEX, 1, "Body: ", - (xco+10+(0.20*(width-20))), (yco-(myline++*24)), (0.8*(width-20)), 19, - &ma->body, 0, MAX_NAME, 0, 0, - "Optional message body Text"); - } - else { - /* line 3: Property body (set by property) */ - uiDefBut(block, TEX, 1, "Propname: ", - (xco+10+(0.20*(width-20))), (yco-(myline++*24)), (0.8*(width-20)), 19, - &ma->body, 0, MAX_NAME, 0, 0, - "The message body will be set by the Property Value"); - } - - yco -= ysize; - break; - case ACT_2DFILTER: - tdfa = act->data; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, + (float)yco-ysize, (float)xco+width, (float)yco, 1); + + randAct = act->data; + + /* 1. seed */ + uiDefButI(block, NUM, 1, "Seed: ", (xco+10), yco-24, 0.4 *(width-20), 19, + &randAct->seed, 0, 1000, 0, 0, + "Initial seed of the random generator. Use Python for more freedom. " + " (Choose 0 for not random)"); + + /* 2. distribution type */ + /* One pick per distribution. These numbers MUST match the #defines */ + /* in game.h !!! */ + str= "Distribution %t|Bool Constant %x0|Bool Uniform %x1" + "|Bool Bernoulli %x2|Int Constant %x3|Int Uniform %x4" + "|Int Poisson %x5|Float Constant %x6|Float Uniform %x7" + "|Float Normal %x8|Float Neg. Exp. %x9"; + uiDefButI(block, MENU, B_REDR, str, (xco+10) + 0.4 * (width-20), yco-24, 0.6 * (width-20), 19, + &randAct->distribution, 0.0, 0.0, 0, 0, + "Choose the type of distribution"); + + /* 3. property */ + uiDefBut(block, TEX, 1, "Property:", (xco+10), yco-44, (width-20), 19, + &randAct->propname, 0, MAX_NAME, 0, 0, + "Assign the random value to this property"); + + /*4. and 5. arguments for the distribution*/ + switch (randAct->distribution) { + case ACT_RANDOM_BOOL_CONST: + uiDefButBitI(block, TOG, 1, 1, "Always true", (xco+10), yco-64, (width-20), 19, + &randAct->int_arg_1, 2.0, 1, 0, 0, + "Always false or always true"); + break; + case ACT_RANDOM_BOOL_UNIFORM: + uiDefBut(block, LABEL, 0, " Do a 50-50 pick", (xco+10), yco-64, (width-20), 19, + NULL, 0, 0, 0, 0, + "Choose between true and false, 50% chance each"); + break; + case ACT_RANDOM_BOOL_BERNOUILLI: + uiDefButF(block, NUM, 1, "Chance", (xco+10), yco-64, (width-20), 19, + &randAct->float_arg_1, 0.0, 1.0, 0, 0, + "Pick a number between 0 and 1. Success if you stay " + "below this value"); + break; + case ACT_RANDOM_INT_CONST: + uiDefButI(block, NUM, 1, "Value: ", (xco+10), yco-64, (width-20), 19, + &randAct->int_arg_1, -1000, 1000, 0, 0, + "Always return this number"); + break; + case ACT_RANDOM_INT_UNIFORM: + uiDefButI(block, NUM, 1, "Min: ", (xco+10), yco-64, (width-20)/2, 19, + &randAct->int_arg_1, -1000, 1000, 0, 0, + "Choose a number from a range. " + "Lower boundary of the range"); + uiDefButI(block, NUM, 1, "Max: ", (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19, + &randAct->int_arg_2, -1000, 1000, 0, 0, + "Choose a number from a range. " + "Upper boundary of the range"); + break; + case ACT_RANDOM_INT_POISSON: + uiDefButF(block, NUM, 1, "Mean: ", (xco+10), yco-64, (width-20), 19, + &randAct->float_arg_1, 0.01, 100.0, 0, 0, + "Expected mean value of the distribution"); + break; + case ACT_RANDOM_FLOAT_CONST: + uiDefButF(block, NUM, 1, "Value: ", (xco+10), yco-64, (width-20), 19, + &randAct->float_arg_1, 0.0, 1.0, 0, 0, + "Always return this number"); + break; + case ACT_RANDOM_FLOAT_UNIFORM: + uiDefButF(block, NUM, 1, "Min: ", (xco+10), yco-64, (width-20)/2, 19, + &randAct->float_arg_1, -10000.0, 10000.0, 0, 0, + "Choose a number from a range" + "Lower boundary of the range"); + uiDefButF(block, NUM, 1, "Max: ", (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19, + &randAct->float_arg_2, -10000.0, 10000.0, 0, 0, + "Choose a number from a range" + "Upper boundary of the range"); + break; + case ACT_RANDOM_FLOAT_NORMAL: + uiDefButF(block, NUM, 1, "Mean: ", (xco+10), yco-64, (width-20)/2, 19, + &randAct->float_arg_1, -10000.0, 10000.0, 0, 0, + "A normal distribution. Mean of the distribution"); + uiDefButF(block, NUM, 1, "SD: ", (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19, + &randAct->float_arg_2, 0.0, 10000.0, 0, 0, + "A normal distribution. Standard deviation of the " + "distribution"); + break; + case ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL: + uiDefButF(block, NUM, 1, "Half-life time: ", (xco+10), yco-64, (width-20), 19, + &randAct->float_arg_1, 0.001, 10000.0, 0, 0, + "Negative exponential dropoff"); + break; + default: + ; /* don't know what this distro is... can be useful for testing */ + /* though :) */ + } - ysize = 50; - if (tdfa->type == ACT_2DFILTER_CUSTOMFILTER) { - ysize +=20; - } - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + yco-= ysize; + break; + case ACT_MESSAGE: + ma = act->data; - switch (tdfa->type) { - case ACT_2DFILTER_MOTIONBLUR: - if (!tdfa->flag) { - uiDefButS(block, TOG, B_REDR, "D", xco+30, yco-44, 19, 19, &tdfa->flag, 0.0, 0.0, 0.0, 0.0, "Disable Motion Blur"); - uiDefButF(block, NUM, B_REDR, "Value:", xco+52, yco-44, width-82, 19, &tdfa->float_arg, 0.0, 1.0, 0.0, 0.0, "Set motion blur value"); - } - else { - uiDefButS(block, TOG, B_REDR, "Disabled", xco+30, yco-44, width-60, 19, &tdfa->flag, 0.0, 0.0, 0.0, 0.0, "Enable Motion Blur"); - } - break; - case ACT_2DFILTER_BLUR: - case ACT_2DFILTER_SHARPEN: - case ACT_2DFILTER_DILATION: - case ACT_2DFILTER_EROSION: - case ACT_2DFILTER_LAPLACIAN: - case ACT_2DFILTER_SOBEL: - case ACT_2DFILTER_PREWITT: - case ACT_2DFILTER_GRAYSCALE: - case ACT_2DFILTER_SEPIA: - case ACT_2DFILTER_INVERT: - case ACT_2DFILTER_NOFILTER: - case ACT_2DFILTER_DISABLED: - case ACT_2DFILTER_ENABLED: - uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30, yco-44, width-60, 19, &tdfa->int_arg, 0.0, MAX_RENDER_PASS-1, 0.0, 0.0, "Set filter order"); - break; - case ACT_2DFILTER_CUSTOMFILTER: - uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30, yco-44, width-60, 19, &tdfa->int_arg, 0.0, MAX_RENDER_PASS-1, 0.0, 0.0, "Set filter order"); - uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30, yco-64, width-60, 19, &tdfa->text, ""); - break; - } - - str= "2D Filter %t|Motion Blur %x1|Blur %x2|Sharpen %x3|Dilation %x4|Erosion %x5|" - "Laplacian %x6|Sobel %x7|Prewitt %x8|Gray Scale %x9|Sepia %x10|Invert %x11|Custom Filter %x12|" - "Enable Filter %x-2|Disable Filter %x-1|Remove Filter %x0|"; - uiDefButS(block, MENU, B_REDR, str, xco+30, yco-24, width-60, 19, &tdfa->type, 0.0, 0.0, 0.0, 0.0, "2D filter type"); - - yco -= ysize; - break; - case ACT_PARENT: - parAct = act->data; + ysize = 4 + (3 * 24); /* footer + number of lines * 24 pixels/line */ - if (parAct->type==ACT_PARENT_SET) { - - ysize= 48; glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+95, yco-24, (width-100), 19, &(parAct->ob), "Set this object as parent"); - uiBlockBeginAlign(block); - uiDefButBitS(block, TOGN, ACT_PARENT_COMPOUND, B_REDR, - "Compound", - xco + 5, yco - 44, (width - 10)/2, 19, &parAct->flag, - 0.0, 0.0, 0, 0, - "Add this object shape to the parent shape (only if the parent shape is already compound)"); - uiDefButBitS(block, TOGN, ACT_PARENT_GHOST, B_REDR, - "Ghost", - xco + 5 + ((width - 10)/2), yco - 44, (width - 10)/2, 19, &parAct->flag, - 0.0, 0.0, 0, 0, - "Make this object ghost while parented (only if not compound)"); - uiBlockEndAlign(block); - } - else if (parAct->type==ACT_PARENT_REMOVE) { + uiEmboss((float)xco, (float)yco-ysize, + (float)xco+width, (float)yco, 1); + + myline=1; + + /* line 1: To */ + uiDefBut(block, TEX, 1, "To: ", + (xco+10), (yco-(myline++*24)), (width-20), 19, + &ma->toPropName, 0, MAX_NAME, 0, 0, + "Optional send message to objects with this name only, or empty to broadcast"); + + /* line 2: Message Subject */ + uiDefBut(block, TEX, 1, "Subject: ", + (xco+10), (yco-(myline++*24)), (width-20), 19, + &ma->subject, 0, MAX_NAME, 0, 0, + "Optional message subject. This is what can be filtered on"); + + /* line 3: Text/Property */ + uiDefButBitS(block, TOG, 1, B_REDR, "T/P", + (xco+10), (yco-(myline*24)), (0.20 * (width-20)), 19, + &ma->bodyType, 0.0, 0.0, 0, 0, + "Toggle message type: either Text or a PropertyName"); + + if (ma->bodyType == ACT_MESG_MESG) { + /* line 3: Message Body */ + uiDefBut(block, TEX, 1, "Body: ", + (xco+10+(0.20*(width-20))), (yco-(myline++*24)), (0.8*(width-20)), 19, + &ma->body, 0, MAX_NAME, 0, 0, + "Optional message body Text"); + } + else { + /* line 3: Property body (set by property) */ + uiDefBut(block, TEX, 1, "Propname: ", + (xco+10+(0.20*(width-20))), (yco-(myline++*24)), (0.8*(width-20)), 19, + &ma->body, 0, MAX_NAME, 0, 0, + "The message body will be set by the Property Value"); + } - ysize= 28; + yco -= ysize; + break; + case ACT_2DFILTER: + tdfa = act->data; + + ysize = 50; + if (tdfa->type == ACT_2DFILTER_CUSTOMFILTER) { + ysize +=20; + } glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - } - str= "Parent %t|Set Parent %x0|Remove Parent %x1"; - uiDefButI(block, MENU, B_REDR, str, xco+5, yco-24, parAct->type==1?(width-80):90, 19, &parAct->type, 0.0, 0.0, 0, 0, ""); + switch (tdfa->type) { + case ACT_2DFILTER_MOTIONBLUR: + if (!tdfa->flag) { + uiDefButS(block, TOG, B_REDR, "D", xco+30, yco-44, 19, 19, &tdfa->flag, 0.0, 0.0, 0.0, 0.0, "Disable Motion Blur"); + uiDefButF(block, NUM, B_REDR, "Value:", xco+52, yco-44, width-82, 19, &tdfa->float_arg, 0.0, 1.0, 0.0, 0.0, "Set motion blur value"); + } + else { + uiDefButS(block, TOG, B_REDR, "Disabled", xco+30, yco-44, width-60, 19, &tdfa->flag, 0.0, 0.0, 0.0, 0.0, "Enable Motion Blur"); + } + break; + case ACT_2DFILTER_BLUR: + case ACT_2DFILTER_SHARPEN: + case ACT_2DFILTER_DILATION: + case ACT_2DFILTER_EROSION: + case ACT_2DFILTER_LAPLACIAN: + case ACT_2DFILTER_SOBEL: + case ACT_2DFILTER_PREWITT: + case ACT_2DFILTER_GRAYSCALE: + case ACT_2DFILTER_SEPIA: + case ACT_2DFILTER_INVERT: + case ACT_2DFILTER_NOFILTER: + case ACT_2DFILTER_DISABLED: + case ACT_2DFILTER_ENABLED: + uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30, yco-44, width-60, 19, &tdfa->int_arg, 0.0, MAX_RENDER_PASS-1, 0.0, 0.0, "Set filter order"); + break; + case ACT_2DFILTER_CUSTOMFILTER: + uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30, yco-44, width-60, 19, &tdfa->int_arg, 0.0, MAX_RENDER_PASS-1, 0.0, 0.0, "Set filter order"); + uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30, yco-64, width-60, 19, &tdfa->text, ""); + break; + } - yco-= ysize; - break; - case ACT_ARMATURE: - armAct = act->data; + str= "2D Filter %t|Motion Blur %x1|Blur %x2|Sharpen %x3|Dilation %x4|Erosion %x5|" + "Laplacian %x6|Sobel %x7|Prewitt %x8|Gray Scale %x9|Sepia %x10|Invert %x11|Custom Filter %x12|" + "Enable Filter %x-2|Disable Filter %x-1|Remove Filter %x0|"; + uiDefButS(block, MENU, B_REDR, str, xco+30, yco-24, width-60, 19, &tdfa->type, 0.0, 0.0, 0.0, 0.0, "2D filter type"); - if (ob->type == OB_ARMATURE) { - str= "Constraint %t|Run armature %x0|Enable %x1|Disable %x2|Set target %x3|Set weight %x4"; - uiDefButI(block, MENU, B_REDR, str, xco+5, yco-24, (width-10)*0.35, 19, &armAct->type, 0.0, 0.0, 0, 0, ""); + yco -= ysize; + break; + case ACT_PARENT: + parAct = act->data; - switch (armAct->type) { - case ACT_ARM_RUN: - ysize = 28; - break; - default: + if (parAct->type==ACT_PARENT_SET) { + + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+95, yco-24, (width-100), 19, &(parAct->ob), "Set this object as parent"); uiBlockBeginAlign(block); - but = uiDefBut(block, TEX, 1, "Bone: ", - (xco+5), (yco-44), (width-10)/2, 19, - armAct->posechannel, 0, MAX_NAME, 0, 0, - "Bone on which the constraint is defined"); - uiButSetFunc(but, check_armature_actuator, but, armAct); - but = uiDefBut(block, TEX, 1, "Cons: ", - (xco+5)+(width-10)/2, (yco-44), (width-10)/2, 19, - armAct->constraint, 0, MAX_NAME, 0, 0, - "Name of the constraint you want to control"); - uiButSetFunc(but, check_armature_actuator, but, armAct); + uiDefButBitS(block, TOGN, ACT_PARENT_COMPOUND, B_REDR, + "Compound", + xco + 5, yco - 44, (width - 10)/2, 19, &parAct->flag, + 0.0, 0.0, 0, 0, + "Add this object shape to the parent shape (only if the parent shape is already compound)"); + uiDefButBitS(block, TOGN, ACT_PARENT_GHOST, B_REDR, + "Ghost", + xco + 5 + ((width - 10)/2), yco - 44, (width - 10)/2, 19, &parAct->flag, + 0.0, 0.0, 0, 0, + "Make this object ghost while parented (only if not compound)"); uiBlockEndAlign(block); - ysize = 48; + } + else if (parAct->type==ACT_PARENT_REMOVE) { + + ysize= 28; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + } + + str= "Parent %t|Set Parent %x0|Remove Parent %x1"; + uiDefButI(block, MENU, B_REDR, str, xco+5, yco-24, parAct->type==1?(width-80):90, 19, &parAct->type, 0.0, 0.0, 0, 0, ""); + + yco-= ysize; + break; + case ACT_ARMATURE: + armAct = act->data; + + if (ob->type == OB_ARMATURE) { + str= "Constraint %t|Run armature %x0|Enable %x1|Disable %x2|Set target %x3|Set weight %x4"; + uiDefButI(block, MENU, B_REDR, str, xco+5, yco-24, (width-10)*0.35, 19, &armAct->type, 0.0, 0.0, 0, 0, ""); + switch (armAct->type) { - case ACT_ARM_SETTARGET: - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "Target: ", xco+5, yco-64, (width-10), 19, &(armAct->target), "Set this object as the target of the constraint"); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "Secondary Target: ", xco+5, yco-84, (width-10), 19, &(armAct->subtarget), "Set this object as the secondary target of the constraint (only IK polar target at the moment)"); - ysize += 40; - break; - case ACT_ARM_SETWEIGHT: - uiDefButF(block, NUM, B_REDR, "Weight:", xco+5+(width-10)*0.35, yco-24, (width-10)*0.65, 19, &armAct->weight, 0.0, 1.0, 0.0, 0.0, "Set weight of this constraint"); - break; + case ACT_ARM_RUN: + ysize = 28; + break; + default: + uiBlockBeginAlign(block); + but = uiDefBut(block, TEX, 1, "Bone: ", + (xco+5), (yco-44), (width-10)/2, 19, + armAct->posechannel, 0, MAX_NAME, 0, 0, + "Bone on which the constraint is defined"); + uiButSetFunc(but, check_armature_actuator, but, armAct); + but = uiDefBut(block, TEX, 1, "Cons: ", + (xco+5)+(width-10)/2, (yco-44), (width-10)/2, 19, + armAct->constraint, 0, MAX_NAME, 0, 0, + "Name of the constraint you want to control"); + uiButSetFunc(but, check_armature_actuator, but, armAct); + uiBlockEndAlign(block); + ysize = 48; + switch (armAct->type) { + case ACT_ARM_SETTARGET: + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "Target: ", xco+5, yco-64, (width-10), 19, &(armAct->target), "Set this object as the target of the constraint"); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "Secondary Target: ", xco+5, yco-84, (width-10), 19, &(armAct->subtarget), "Set this object as the secondary target of the constraint (only IK polar target at the moment)"); + ysize += 40; + break; + case ACT_ARM_SETWEIGHT: + uiDefButF(block, NUM, B_REDR, "Weight:", xco+5+(width-10)*0.35, yco-24, (width-10)*0.65, 19, &armAct->weight, 0.0, 1.0, 0.0, 0.0, "Set weight of this constraint"); + break; + } } } - } - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - yco-= ysize; - break; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + yco-= ysize; + break; - default: - ysize= 4; + default: + ysize= 4; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - yco-= ysize; - break; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + yco-= ysize; + break; } uiBlockSetEmboss(block, UI_EMBOSS); diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index a6578ffb3f7..7eb0f676707 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -80,26 +80,17 @@ static void nla_action_get_color(AnimData *adt, bAction *act, float color[4]) { if (adt && (adt->flag & ADT_NLA_EDIT_ON)) { - // greenish color (same as tweaking strip) - hardcoded for now - color[0] = 0.30f; - color[1] = 0.95f; - color[2] = 0.10f; - color[3] = 0.30f; + /* greenish color (same as tweaking strip) */ + UI_GetThemeColor4fv(TH_NLA_TWEAK, color); } else { if (act) { - // reddish color - hardcoded for now - color[0] = 0.8f; - color[1] = 0.2f; - color[2] = 0.0f; - color[3] = 0.4f; + /* reddish color - same as dopesheet summary */ + UI_GetThemeColor4fv(TH_ANIM_ACTIVE, color); } else { - // greyish-red color - hardcoded for now - color[0] = 0.6f; - color[1] = 0.5f; - color[2] = 0.5f; - color[3] = 0.3f; + /* greyish-red color */ + UI_GetThemeColor4fv(TH_ANIM_INACTIVE, color); } } @@ -166,17 +157,11 @@ static void nla_strip_get_color_inside(AnimData *adt, NlaStrip *strip, float col /* Transition Clip */ if (strip->flag & NLASTRIP_FLAG_SELECT) { /* selected - use a bright blue color */ - // FIXME: hardcoded temp-hack colors - color[0] = 0.18f; - color[1] = 0.46f; - color[2] = 0.86f; + UI_GetThemeColor3fv(TH_NLA_TRANSITION_SEL, color); } else { /* normal, unselected strip - use (hardly noticeable) blue tinge */ - // FIXME: hardcoded temp-hack colors - color[0] = 0.11f; - color[1] = 0.15f; - color[2] = 0.19f; + UI_GetThemeColor3fv(TH_NLA_TRANSITION, color); } } else if (strip->type == NLASTRIP_TYPE_META) { @@ -184,34 +169,22 @@ static void nla_strip_get_color_inside(AnimData *adt, NlaStrip *strip, float col // TODO: should temporary metas get different colors too? if (strip->flag & NLASTRIP_FLAG_SELECT) { /* selected - use a bold purple color */ - // FIXME: hardcoded temp-hack colors - color[0] = 0.41f; - color[1] = 0.13f; - color[2] = 0.59f; + UI_GetThemeColor3fv(TH_NLA_META_SEL, color); } else { /* normal, unselected strip - use (hardly noticeable) dark purple tinge */ - // FIXME: hardcoded temp-hack colors - color[0] = 0.20f; - color[1] = 0.15f; - color[2] = 0.26f; + UI_GetThemeColor3fv(TH_NLA_META, color); } } else if (strip->type == NLASTRIP_TYPE_SOUND) { /* Sound Clip */ if (strip->flag & NLASTRIP_FLAG_SELECT) { /* selected - use a bright teal color */ - // FIXME: hardcoded temp-hack colors - color[0] = 0.12f; - color[1] = 0.48f; - color[2] = 0.48f; + UI_GetThemeColor3fv(TH_NLA_SOUND_SEL, color); } else { /* normal, unselected strip - use (hardly noticeable) teal tinge */ - // FIXME: hardcoded temp-hack colors - color[0] = 0.17f; - color[1] = 0.24f; - color[2] = 0.24f; + UI_GetThemeColor3fv(TH_NLA_SOUND, color); } } else { @@ -220,19 +193,13 @@ static void nla_strip_get_color_inside(AnimData *adt, NlaStrip *strip, float col /* active strip should be drawn green when it is acting as the tweaking strip. * however, this case should be skipped for when not in EditMode... */ - // FIXME: hardcoded temp-hack colors - color[0] = 0.3f; - color[1] = 0.95f; - color[2] = 0.1f; + UI_GetThemeColor3fv(TH_NLA_TWEAK, color); } else if (strip->flag & NLASTRIP_FLAG_TWEAKUSER) { /* alert user that this strip is also used by the tweaking track (this is set when going into * 'editmode' for that strip), since the edits made here may not be what the user anticipated */ - // FIXME: hardcoded temp-hack colors - color[0] = 0.85f; - color[1] = 0.0f; - color[2] = 0.0f; + UI_GetThemeColor3fv(TH_NLA_TWEAK_DUPLI, color); } else if (strip->flag & NLASTRIP_FLAG_SELECT) { /* selected strip - use theme color for selected */ @@ -792,21 +759,24 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View glEnable(GL_BLEND); /* draw backing strip behind channel name */ + // FIXME: hardcoded colors!!! if (group == 5) { - /* Action Line */ - // TODO: if tweaking some action, use the same color as for the tweaked track (quick hack done for now) + float color[4]; + + /* Action Line + * The alpha values action_get_color returns are only useful for drawing + * strips backgrounds but here we're doing channel list backgrounds instead + * so we ignore that and use our own when needed + */ + nla_action_get_color(adt, (bAction *)ale->data, color); + if (adt && (adt->flag & ADT_NLA_EDIT_ON)) { - // greenish color (same as tweaking strip) - hardcoded for now - glColor3f(0.3f, 0.95f, 0.1f); + /* Yes, the color vector has 4 components, BUT we only want to be using 3 of them! */ + glColor3fv(color); } else { - /* if a track is being solo'd, action is ignored, so draw less boldly (alpha lower) */ - float alpha = (adt && (adt->flag & ADT_NLA_SOLO_TRACK)) ? 0.3f : 1.0f; - - if (ale->data) - glColor4f(0.8f, 0.2f, 0.0f, alpha); // reddish color - hardcoded for now - else - glColor4f(0.6f, 0.5f, 0.5f, alpha); // greyish-red color - hardcoded for now + float alpha = (adt && (adt->flag & ADT_NLA_SOLO_TRACK)) ? 0.3 : 1.0f; + glColor4f(color[0], color[1], color[2], alpha); } offset += 7 * indent; diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 73ca9097610..12c369874fe 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1114,7 +1114,7 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED( glDisable(GL_BLEND); /* outline active and selected emphasis */ - if( node->flag & (NODE_ACTIVE|SELECT) ) { + if (node->flag & (NODE_ACTIVE | SELECT)) { glEnable(GL_BLEND); glEnable( GL_LINE_SMOOTH ); /* using different shades of TH_TEXT_HI for the empasis, like triangle */ @@ -1132,7 +1132,7 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED( /* only draw input socket. as they all are placed on the same position. * highlight also if node itself is selected, since we don't display the node body separately! */ - for(sock= node->inputs.first; sock; sock= sock->next) { + for (sock= node->inputs.first; sock; sock= sock->next) { node_socket_circle_draw(ntree, sock, socket_size, (sock->flag & SELECT) || (node->flag & SELECT)); } @@ -1188,6 +1188,47 @@ static void node_common_set_butfunc(bNodeType *ntype) } /* ****************** BUTTON CALLBACKS FOR SHADER NODES ***************** */ + +static void node_buts_image_user(uiLayout *layout, bContext *C, PointerRNA *imaptr, PointerRNA *iuserptr) +{ + uiLayout *col; + int source; + + if(!imaptr->data) + return; + + col = uiLayoutColumn(layout, 0); + + uiItemR(col, imaptr, "source", 0, "", ICON_NONE); + + source = RNA_enum_get(imaptr, "source"); + + if (source == IMA_SRC_SEQUENCE) { + /* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */ + Scene *scene = CTX_data_scene(C); + ImageUser *iuser = iuserptr->data; + char numstr[32]; + const int framenr = BKE_image_user_frame_get(iuser, CFRA, 0); + BLI_snprintf(numstr, sizeof(numstr), IFACE_("Frame: %d"), framenr); + uiItemL(layout, numstr, ICON_NONE); + } + + if (ELEM(source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) { + col = uiLayoutColumn(layout, 1); + uiItemR(col, iuserptr, "frame_duration", 0, NULL, ICON_NONE); + uiItemR(col, iuserptr, "frame_start", 0, NULL, ICON_NONE); + uiItemR(col, iuserptr, "frame_offset", 0, NULL, ICON_NONE); + uiItemR(col, iuserptr, "use_cyclic", 0, NULL, ICON_NONE); + uiItemR(col, iuserptr, "use_auto_refresh", UI_ITEM_R_ICON_ONLY, NULL, ICON_NONE); + } + + col = uiLayoutColumn(layout, 0); + + if (RNA_enum_get(imaptr, "type") == IMA_TYPE_MULTILAYER) + uiItemR(col, iuserptr, "layer", 0, NULL, ICON_NONE); + +} + static void node_shader_buts_material(uiLayout *layout, bContext *C, PointerRNA *ptr) { bNode *node = ptr->data; @@ -1259,16 +1300,25 @@ static void node_shader_buts_attribute(uiLayout *layout, bContext *UNUSED(C), Po static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA *ptr) { + PointerRNA imaptr = RNA_pointer_get(ptr, "image"); + PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user"); + uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL); uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE); -} + node_buts_image_user(layout, C, &imaptr, &iuserptr); +} static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, PointerRNA *ptr) { + PointerRNA imaptr = RNA_pointer_get(ptr, "image"); + PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user"); + uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL); uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE); uiItemR(layout, ptr, "projection", 0, "", ICON_NONE); + + node_buts_image_user(layout, C, &imaptr, &iuserptr); } static void node_shader_buts_tex_sky(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) @@ -1391,49 +1441,17 @@ static void node_shader_set_butfunc(bNodeType *ntype) static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr) { - uiLayout *col; bNode *node = ptr->data; - PointerRNA imaptr; - PropertyRNA *prop; - int source; + PointerRNA imaptr, iuserptr; uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL); if (!node->id) return; - prop = RNA_struct_find_property(ptr, "image"); - if (!prop || RNA_property_type(prop) != PROP_POINTER) return; - imaptr = RNA_property_pointer_get(ptr, prop); - - col = uiLayoutColumn(layout, 0); + imaptr = RNA_pointer_get(ptr, "image"); + RNA_pointer_create((ID *)ptr->id.data, &RNA_ImageUser, node->storage, &iuserptr); - uiItemR(col, &imaptr, "source", 0, NULL, ICON_NONE); - - source = RNA_enum_get(&imaptr, "source"); - - if (source == IMA_SRC_SEQUENCE) { - /* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */ - Scene *scene = CTX_data_scene(C); - ImageUser *iuser = node->storage; - char numstr[32]; - const int framenr = BKE_image_user_frame_get(iuser, CFRA, 0); - BLI_snprintf(numstr, sizeof(numstr), IFACE_("Frame: %d"), framenr); - uiItemL(layout, numstr, ICON_NONE); - } - - if (ELEM(source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) { - col = uiLayoutColumn(layout, 1); - uiItemR(col, ptr, "frame_duration", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "frame_start", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "frame_offset", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "use_cyclic", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "use_auto_refresh", UI_ITEM_R_ICON_ONLY, NULL, ICON_NONE); - } - - col = uiLayoutColumn(layout, 0); - - if (RNA_enum_get(&imaptr, "type") == IMA_TYPE_MULTILAYER) - uiItemR(col, ptr, "layer", 0, NULL, ICON_NONE); + node_buts_image_user(layout, C, &imaptr, &iuserptr); } static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, PointerRNA *ptr) @@ -2274,7 +2292,7 @@ static void node_composit_buts_bokehimage(uiLayout *layout, bContext *UNUSED(C), void node_composit_backdrop_viewer(SpaceNode *snode, ImBuf *backdrop, bNode *node, int x, int y) { // node_composit_backdrop_canvas(snode, backdrop, node, x, y); - if (node->custom1 == 0) { /// @todo: why did we need this one? + if (node->custom1 == 0) { const float backdropWidth = backdrop->x; const float backdropHeight = backdrop->y; const float cx = x + snode->zoom * backdropWidth * node->custom3; @@ -2400,6 +2418,11 @@ static void node_composit_buts_viewer_but(uiLayout *layout, bContext *UNUSED(C), } } +static void node_composit_buts_mask(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + uiTemplateID(layout, C, ptr, "mask", NULL, NULL, NULL); +} + /* only once called */ static void node_composit_set_butfunc(bNodeType *ntype) { @@ -2589,7 +2612,9 @@ static void node_composit_set_butfunc(bNodeType *ntype) ntype->uifuncbut = node_composit_buts_viewer_but; ntype->uibackdropfunc = node_composit_backdrop_viewer; break; - + case CMP_NODE_MASK: + ntype->uifunc= node_composit_buts_mask; + break; default: ntype->uifunc = NULL; } diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 1b229c78e0f..b4e07546fa9 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -2756,11 +2756,11 @@ static int add_reroute_intersect_check(bNodeLink *link, float mcoords[][2], int float coord_array[LINK_RESOL+1][2]; int i, b; - if(node_link_bezier_points(NULL, NULL, link, coord_array, LINK_RESOL)) { + if (node_link_bezier_points(NULL, NULL, link, coord_array, LINK_RESOL)) { - for(i=0; i<tot-1; i++) - for(b=0; b<LINK_RESOL; b++) - if(isect_line_line_v2(mcoords[i], mcoords[i+1], coord_array[b], coord_array[b+1]) > 0) { + for (i=0; i<tot-1; i++) + for (b=0; b<LINK_RESOL; b++) + if (isect_line_line_v2(mcoords[i], mcoords[i+1], coord_array[b], coord_array[b+1]) > 0) { result[0] = (mcoords[i][0]+mcoords[i+1][0])/2.0f; result[1] = (mcoords[i][1]+mcoords[i+1][1])/2.0f; return 1; @@ -2783,18 +2783,18 @@ static int add_reroute_exec(bContext *C, wmOperator *op) UI_view2d_region_to_view(&ar->v2d, (short)loc[0], (short)loc[1], &mcoords[i][0], &mcoords[i][1]); i++; - if(i>= 256) break; + if (i>= 256) break; } RNA_END; - if(i>1) { + if (i>1) { bNodeLink *link; float insertPoint[2]; ED_preview_kill_jobs(C); - for(link= snode->edittree->links.first; link; link=link->next) { - if(add_reroute_intersect_check(link, mcoords, i, insertPoint)) { + for (link= snode->edittree->links.first; link; link=link->next) { + if (add_reroute_intersect_check(link, mcoords, i, insertPoint)) { bNodeTemplate ntemp; bNode *rerouteNode; diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 35b1583b24e..9e873799f1c 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -50,8 +50,7 @@ struct bNodeLink; struct Main; /* temp data to pass on to modal */ -typedef struct bNodeLinkDrag -{ +typedef struct bNodeLinkDrag { struct bNodeLinkDrag *next, *prev; /* List of links dragged by the operator. diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index 0a3678ca901..e7be750928d 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -76,7 +76,7 @@ static bNode *node_under_mouse_tweak(bNodeTree *ntree, int mx, int my) { bNode *node; - for(node=ntree->nodes.last; node; node=node->prev) { + for (node=ntree->nodes.last; node; node=node->prev) { if (node->typeinfo->tweak_area_func) { if (node->typeinfo->tweak_area_func(node, mx, my)) return node; diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 520a9f1cd22..66919935d48 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -245,6 +245,13 @@ static void node_area_listener(ScrArea *sa, wmNotifier *wmn) break; } break; + case NC_MASK: + if (wmn->action == NA_EDITED) { + if (type==NTREE_COMPOSIT) { + ED_area_tag_refresh(sa); + } + } + break; case NC_IMAGE: if (wmn->action == NA_EDITED) { diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 547e8288d20..f0ecaf3ab2c 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -69,6 +69,9 @@ #include "outliner_intern.h" +/* disable - this is far too slow - campbell */ +// #define USE_GROUP_SELECT + /* ****************************************************** */ /* Tree Size Functions */ @@ -207,6 +210,7 @@ static int group_restrict_flag(Group *gr, int flag) return 1; } +#ifdef USE_GROUP_SELECT static int group_select_flag(Group *gr) { GroupObject *gob; @@ -217,6 +221,7 @@ static int group_select_flag(Group *gr) return 0; } +#endif void restrictbutton_gr_restrict_flag(void *poin, void *poin2, int flag) { @@ -422,16 +427,26 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar gr = (Group *)tselem->id; uiBlockSetEmboss(block, UI_EMBOSSN); - + +#ifndef USE_GROUP_SELECT + restrict_bool = FALSE; +#endif + +#ifdef USE_GROUP_SELECT restrict_bool = group_restrict_flag(gr, OB_RESTRICT_VIEW); +#endif bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, NULL, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); uiButSetFunc(bt, restrictbutton_gr_restrict_view, scene, gr); +#ifdef USE_GROUP_SELECT restrict_bool = group_restrict_flag(gr, OB_RESTRICT_SELECT); +#endif bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, NULL, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); uiButSetFunc(bt, restrictbutton_gr_restrict_select, scene, gr); - + +#ifdef USE_GROUP_SELECT restrict_bool = group_restrict_flag(gr, OB_RESTRICT_RENDER); +#endif bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, NULL, 0, 0, 0, 0, "Restrict/Allow renderability"); uiButSetFunc(bt, restrictbutton_gr_restrict_render, scene, gr); @@ -1042,15 +1057,15 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto case TSE_POSEGRP_BASE: UI_icon_draw(x, y, ICON_GROUP_BONE); break; case TSE_SEQUENCE: - if (te->idcode == SEQ_MOVIE) + if (te->idcode == SEQ_TYPE_MOVIE) UI_icon_draw(x, y, ICON_SEQUENCE); - else if (te->idcode == SEQ_META) + else if (te->idcode == SEQ_TYPE_META) UI_icon_draw(x, y, ICON_DOT); - else if (te->idcode == SEQ_SCENE) + else if (te->idcode == SEQ_TYPE_SCENE) UI_icon_draw(x, y, ICON_SCENE); - else if (te->idcode == SEQ_SOUND) + else if (te->idcode == SEQ_TYPE_SOUND_RAM) UI_icon_draw(x, y, ICON_SOUND); - else if (te->idcode == SEQ_IMAGE) + else if (te->idcode == SEQ_TYPE_IMAGE) UI_icon_draw(x, y, ICON_IMAGE_COL); else UI_icon_draw(x, y, ICON_PARTICLES); @@ -1274,8 +1289,8 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene } } else if (te->idcode == ID_GR) { +#ifdef USE_GROUP_SELECT Group *gr = (Group *)tselem->id; - if (group_select_flag(gr)) { char col[4]; UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col); @@ -1284,6 +1299,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene active = 2; } +#endif } else if (te->idcode == ID_OB) { Object *ob = (Object *)tselem->id; diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index a752a7d71ae..e5f7b8fd76d 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -1503,7 +1503,12 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, wmEvent *event) scene = (Scene *)outliner_search_back(soops, te_found, ID_SCE); if (scene == NULL) { - return OPERATOR_CANCELLED; + /* currently outlier organized in a way, that if there's no parent scene + * element for object it means that all displayed objects belong to + * active scene and parenting them is allowed (sergey) + */ + + scene = CTX_data_scene(C); } if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) { diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index b556fbf5c9d..3d01de1c67a 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -385,6 +385,18 @@ static void group_linkobs2scene_cb(bContext *UNUSED(C), Scene *scene, TreeElemen } } +static void group_instance_cb(bContext *C, Scene *scene, TreeElement *UNUSED(te), + TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) +{ + Group *group = (Group *)tselem->id; + + Object *ob = ED_object_add_type(C, OB_EMPTY, scene->cursor, NULL, FALSE, scene->layact); + rename_id(&ob->id, group->id.name + 2); + ob->dup_group = group; + ob->transflag |= OB_DUPLIGROUP; + id_lib_extern(&group->id); +} + void outliner_do_object_operation(bContext *C, Scene *scene_act, SpaceOops *soops, ListBase *lb, void (*operation_cb)(bContext *C, Scene *scene, TreeElement *, TreeStoreElem *, TreeStoreElem *)) @@ -636,13 +648,14 @@ void OUTLINER_OT_object_operation(wmOperatorType *ot) /* **************************************** */ static EnumPropertyItem prop_group_op_types[] = { - {1, "UNLINK", 0, "Unlink", ""}, - {2, "LOCAL", 0, "Make Local", ""}, - {3, "LINK", 0, "Link Group Objects to Scene", ""}, - {4, "TOGVIS", 0, "Toggle Visible", ""}, - {5, "TOGSEL", 0, "Toggle Selectable", ""}, - {6, "TOGREN", 0, "Toggle Renderable", ""}, - {7, "RENAME", 0, "Rename", ""}, + {0, "UNLINK", 0, "Unlink Group", ""}, + {1, "LOCAL", 0, "Make Local Group", ""}, + {2, "LINK", 0, "Link Group Objects to Scene", ""}, + {3, "INSTANCE", 0, "Instance Groups in Scene", ""}, + {4, "TOGVIS", 0, "Toggle Visible Group", ""}, + {5, "TOGSEL", 0, "Toggle Selectable", ""}, + {6, "TOGREN", 0, "Toggle Renderable", ""}, + {7, "RENAME", 0, "Rename", ""}, {0, NULL, 0, NULL, NULL} }; @@ -651,45 +664,36 @@ static int outliner_group_operation_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); SpaceOops *soops = CTX_wm_space_outliner(C); int event; - const char *str = NULL; /* check for invalid states */ if (soops == NULL) return OPERATOR_CANCELLED; event = RNA_enum_get(op->ptr, "type"); - - if (event == 1) { - outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_group_cb); - str = "Unlink group"; - } - else if (event == 2) { - outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_local_cb); - str = "Localized Data"; - } - else if (event == 3) { - outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_linkobs2scene_cb); - str = "Link Group Objects to Scene"; - } - else if (event == 4) { - outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_visibility_cb); - str = "Toggle Visibility"; - } - else if (event == 5) { - outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_selectability_cb); - str = "Toggle Selectability"; - } - else if (event == 6) { - outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_renderability_cb); - str = "Toggle Renderability"; - } - else if (event == 7) { - outliner_do_libdata_operation(C, scene, soops, &soops->tree, item_rename_cb); - str = "Rename"; + + switch (event) { + case 0: outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_group_cb); break; + case 1: outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_local_cb); break; + case 2: outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_linkobs2scene_cb); break; + case 3: outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_instance_cb); break; + case 4: outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_visibility_cb); break; + case 5: outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_selectability_cb); break; + case 6: outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_renderability_cb); break; + case 7: outliner_do_libdata_operation(C, scene, soops, &soops->tree, item_rename_cb); break; + default: + BLI_assert(0); + return OPERATOR_CANCELLED; } + + if (event == 3) { /* instance */ + Main *bmain = CTX_data_main(C); + + /* works without this except if you try render right after, see: 22027 */ + DAG_scene_sort(bmain, scene); + } - ED_undo_push(C, str); + ED_undo_push(C, prop_group_op_types[event].name); WM_event_add_notifier(C, NC_GROUP, NULL); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index ff3648fc2b8..63907f530eb 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -899,14 +899,14 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i te->directdata = seq; te->name = seq->name + 2; - if (seq->type < SEQ_EFFECT) { + if (seq->type < SEQ_TYPE_EFFECT) { /* * This work like the sequence. * If the sequence have a name (not default name) * show it, in other case put the filename. */ - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { p = seq->seqbase.first; while (p) { outliner_add_element(soops, &te->subtree, (void *)p, te, TSE_SEQUENCE, index); diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index 4d45be561c6..c78be8bd223 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -98,7 +98,16 @@ static int outliner_parent_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) if (te_valid) { /* check that parent/child are both in the same scene */ Scene *scene = (Scene *)outliner_search_back(soops, te_valid, ID_SCE); - if (BKE_scene_base_find(scene, (Object *)id)) { + + if (!scene) { + /* currently outlier organized in a way, that if there's no parent scene + * element for object it means that all displayed objects belong to + * active scene and parenting them is allowed (sergey) + */ + return 1; + } + + if (scene && BKE_scene_base_find(scene, (Object *)id)) { return 1; } } diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 9eb4c62789e..26bedd14d6e 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -46,6 +46,7 @@ #include "BLI_utildefines.h" #include "DNA_scene_types.h" +#include "DNA_mask_types.h" #include "DNA_userdef_types.h" #include "BKE_context.h" @@ -54,6 +55,8 @@ #include "BKE_main.h" #include "BKE_sequencer.h" #include "BKE_movieclip.h" +#include "BKE_sequencer.h" +#include "BKE_mask.h" #include "BKE_report.h" #include "WM_api.h" @@ -228,8 +231,8 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op) } seq = alloc_sequence(ed->seqbasep, start_frame, channel); - seq->type = SEQ_SCENE; - seq->blend_mode = SEQ_CROSS; /* so alpha adjustment fade to the strip below */ + seq->type = SEQ_TYPE_SCENE; + seq->blend_mode = SEQ_TYPE_CROSS; /* so alpha adjustment fade to the strip below */ seq->scene = sce_seq; @@ -327,8 +330,8 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op) } seq = alloc_sequence(ed->seqbasep, start_frame, channel); - seq->type = SEQ_MOVIECLIP; - seq->blend_mode = SEQ_CROSS; + seq->type = SEQ_TYPE_MOVIECLIP; + seq->blend_mode = SEQ_TYPE_CROSS; seq->clip = clip; if (seq->clip->id.us == 0) @@ -360,7 +363,6 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } - static int sequencer_add_movieclip_strip_invoke(bContext *C, wmOperator *op, wmEvent *event) { if (!ED_operator_sequencer_active(C)) { @@ -377,11 +379,10 @@ static int sequencer_add_movieclip_strip_invoke(bContext *C, wmOperator *op, wmE // return WM_menu_invoke(C, op, event); } - void SEQUENCER_OT_movieclip_strip_add(struct wmOperatorType *ot) { PropertyRNA *prop; - + /* identifiers */ ot->name = "Add MovieClip Strip"; ot->idname = "SEQUENCER_OT_movieclip_strip_add"; @@ -392,16 +393,113 @@ void SEQUENCER_OT_movieclip_strip_add(struct wmOperatorType *ot) ot->exec = sequencer_add_movieclip_strip_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); prop = RNA_def_enum(ot->srna, "clip", DummyRNA_NULL_items, 0, "Clip", ""); RNA_def_enum_funcs(prop, RNA_movieclip_itemf); ot->prop = prop; } +static int sequencer_add_mask_strip_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + Editing *ed = BKE_sequencer_editing_get(scene, TRUE); + + Mask *mask; + + Sequence *seq; /* generic strip vars */ + Strip *strip; + + int start_frame, channel; /* operator props */ + + start_frame = RNA_int_get(op->ptr, "frame_start"); + channel = RNA_int_get(op->ptr, "channel"); + + mask = BLI_findlink(&CTX_data_main(C)->mask, RNA_enum_get(op->ptr, "mask")); + + if (mask == NULL) { + BKE_report(op->reports, RPT_ERROR, "Mask not found"); + return OPERATOR_CANCELLED; + } + + seq = alloc_sequence(ed->seqbasep, start_frame, channel); + seq->type = SEQ_TYPE_MASK; + seq->blend_mode = SEQ_TYPE_CROSS; + seq->mask = mask; + + if (seq->mask->id.us == 0) + seq->mask->id.us = 1; + + /* basic defaults */ + seq->strip = strip = MEM_callocN(sizeof(Strip), "strip"); + seq->len = BKE_mask_get_duration(mask); + strip->us = 1; + + BLI_strncpy(seq->name + 2, mask->id.name + 2, sizeof(seq->name) - 2); + seqbase_unique_name_recursive(&ed->seqbase, seq); + + calc_sequence_disp(scene, seq); + BKE_sequencer_sort(scene); + + if (RNA_boolean_get(op->ptr, "replace_sel")) { + ED_sequencer_deselect_all(scene); + BKE_sequencer_active_set(scene, seq); + seq->flag |= SELECT; + } + + if (RNA_boolean_get(op->ptr, "overlap") == FALSE) { + if (seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene); + } + + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + + return OPERATOR_FINISHED; +} + +static int sequencer_add_mask_strip_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (!ED_operator_sequencer_active(C)) { + BKE_report(op->reports, RPT_ERROR, "Sequencer area not active"); + return OPERATOR_CANCELLED; + } + + if (!RNA_struct_property_is_set(op->ptr, "mask")) + return WM_enum_search_invoke(C, op, event); + + sequencer_generic_invoke_xy__internal(C, op, event, 0); + return sequencer_add_mask_strip_exec(C, op); + // needs a menu + // return WM_menu_invoke(C, op, event); +} + + +void SEQUENCER_OT_mask_strip_add(struct wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Add Mask Strip"; + ot->idname = "SEQUENCER_OT_mask_strip_add"; + ot->description = "Add a mask strip to the sequencer"; + + /* api callbacks */ + ot->invoke = sequencer_add_mask_strip_invoke; + ot->exec = sequencer_add_mask_strip_exec; + + ot->poll = ED_operator_scene_editable; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); + prop = RNA_def_enum(ot->srna, "mask", DummyRNA_NULL_items, 0, "Mask", ""); + RNA_def_enum_funcs(prop, RNA_mask_itemf); + ot->prop = prop; +} + static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoadFunc seq_load_func) { @@ -740,14 +838,14 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op) seq->strip = strip = MEM_callocN(sizeof(Strip), "strip"); strip->us = 1; - if (seq->type == SEQ_COLOR) { + if (seq->type == SEQ_TYPE_COLOR) { SolidColorVars *colvars = (SolidColorVars *)seq->effectdata; RNA_float_get_array(op->ptr, "color", colvars->col); - seq->blend_mode = SEQ_CROSS; /* so alpha adjustment fade to the strip below */ + seq->blend_mode = SEQ_TYPE_CROSS; /* so alpha adjustment fade to the strip below */ } - else if (seq->type == SEQ_ADJUSTMENT) { - seq->blend_mode = SEQ_CROSS; + else if (seq->type == SEQ_TYPE_ADJUSTMENT) { + seq->blend_mode = SEQ_TYPE_CROSS; } /* an unset channel is a special case where we automatically go above @@ -832,6 +930,6 @@ void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot) WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_ENDFRAME); - RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_CROSS, "Type", "Sequencer effect type"); + RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_TYPE_CROSS, "Type", "Sequencer effect type"); RNA_def_float_vector(ot->srna, "color", 3, NULL, 0.0f, 1.0f, "Color", "Initialize the strip with this color (only used when type='COLOR')", 0.0f, 1.0f); } diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 236baea01be..b674943b2dc 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -40,6 +40,7 @@ #include "IMB_imbuf_types.h" #include "DNA_scene_types.h" +#include "DNA_mask_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_userdef_types.h" @@ -58,7 +59,9 @@ #include "ED_anim_api.h" #include "ED_markers.h" +#include "ED_mask.h" #include "ED_types.h" +#include "ED_space_api.h" #include "UI_interface.h" #include "UI_resources.h" @@ -82,23 +85,27 @@ static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[ SolidColorVars *colvars = (SolidColorVars *)seq->effectdata; switch (seq->type) { - case SEQ_IMAGE: + case SEQ_TYPE_IMAGE: UI_GetThemeColor3ubv(TH_SEQ_IMAGE, col); break; - case SEQ_META: + case SEQ_TYPE_META: UI_GetThemeColor3ubv(TH_SEQ_META, col); break; - case SEQ_MOVIE: + case SEQ_TYPE_MOVIE: UI_GetThemeColor3ubv(TH_SEQ_MOVIE, col); break; - case SEQ_MOVIECLIP: + case SEQ_TYPE_MOVIECLIP: UI_GetThemeColor3ubv(TH_SEQ_MOVIECLIP, col); break; - - case SEQ_SCENE: + + case SEQ_TYPE_MASK: + UI_GetThemeColor3ubv(TH_SEQ_MASK, col); /* TODO */ + break; + + case SEQ_TYPE_SCENE: UI_GetThemeColor3ubv(TH_SEQ_SCENE, col); if (seq->scene == curscene) { @@ -107,45 +114,45 @@ static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[ break; /* transitions */ - case SEQ_CROSS: - case SEQ_GAMCROSS: - case SEQ_WIPE: + case SEQ_TYPE_CROSS: + case SEQ_TYPE_GAMCROSS: + case SEQ_TYPE_WIPE: UI_GetThemeColor3ubv(TH_SEQ_TRANSITION, col); /* slightly offset hue to distinguish different effects */ - if (seq->type == SEQ_CROSS) rgb_byte_set_hue_float_offset(col, 0.04); - if (seq->type == SEQ_GAMCROSS) rgb_byte_set_hue_float_offset(col, 0.08); - if (seq->type == SEQ_WIPE) rgb_byte_set_hue_float_offset(col, 0.12); + if (seq->type == SEQ_TYPE_CROSS) rgb_byte_set_hue_float_offset(col, 0.04); + if (seq->type == SEQ_TYPE_GAMCROSS) rgb_byte_set_hue_float_offset(col, 0.08); + if (seq->type == SEQ_TYPE_WIPE) rgb_byte_set_hue_float_offset(col, 0.12); break; /* effects */ - case SEQ_TRANSFORM: - case SEQ_SPEED: - case SEQ_ADD: - case SEQ_SUB: - case SEQ_MUL: - case SEQ_ALPHAOVER: - case SEQ_ALPHAUNDER: - case SEQ_OVERDROP: - case SEQ_GLOW: - case SEQ_MULTICAM: - case SEQ_ADJUSTMENT: + case SEQ_TYPE_TRANSFORM: + case SEQ_TYPE_SPEED: + case SEQ_TYPE_ADD: + case SEQ_TYPE_SUB: + case SEQ_TYPE_MUL: + case SEQ_TYPE_ALPHAOVER: + case SEQ_TYPE_ALPHAUNDER: + case SEQ_TYPE_OVERDROP: + case SEQ_TYPE_GLOW: + case SEQ_TYPE_MULTICAM: + case SEQ_TYPE_ADJUSTMENT: UI_GetThemeColor3ubv(TH_SEQ_EFFECT, col); /* slightly offset hue to distinguish different effects */ - if (seq->type == SEQ_ADD) rgb_byte_set_hue_float_offset(col, 0.04); - else if (seq->type == SEQ_SUB) rgb_byte_set_hue_float_offset(col, 0.08); - else if (seq->type == SEQ_MUL) rgb_byte_set_hue_float_offset(col, 0.12); - else if (seq->type == SEQ_ALPHAOVER) rgb_byte_set_hue_float_offset(col, 0.16); - else if (seq->type == SEQ_ALPHAUNDER) rgb_byte_set_hue_float_offset(col, 0.20); - else if (seq->type == SEQ_OVERDROP) rgb_byte_set_hue_float_offset(col, 0.24); - else if (seq->type == SEQ_GLOW) rgb_byte_set_hue_float_offset(col, 0.28); - else if (seq->type == SEQ_TRANSFORM) rgb_byte_set_hue_float_offset(col, 0.36); - else if (seq->type == SEQ_MULTICAM) rgb_byte_set_hue_float_offset(col, 0.32); - else if (seq->type == SEQ_ADJUSTMENT) rgb_byte_set_hue_float_offset(col, 0.40); + if (seq->type == SEQ_TYPE_ADD) rgb_byte_set_hue_float_offset(col, 0.04); + else if (seq->type == SEQ_TYPE_SUB) rgb_byte_set_hue_float_offset(col, 0.08); + else if (seq->type == SEQ_TYPE_MUL) rgb_byte_set_hue_float_offset(col, 0.12); + else if (seq->type == SEQ_TYPE_ALPHAOVER) rgb_byte_set_hue_float_offset(col, 0.16); + else if (seq->type == SEQ_TYPE_ALPHAUNDER) rgb_byte_set_hue_float_offset(col, 0.20); + else if (seq->type == SEQ_TYPE_OVERDROP) rgb_byte_set_hue_float_offset(col, 0.24); + else if (seq->type == SEQ_TYPE_GLOW) rgb_byte_set_hue_float_offset(col, 0.28); + else if (seq->type == SEQ_TYPE_TRANSFORM) rgb_byte_set_hue_float_offset(col, 0.36); + else if (seq->type == SEQ_TYPE_MULTICAM) rgb_byte_set_hue_float_offset(col, 0.32); + else if (seq->type == SEQ_TYPE_ADJUSTMENT) rgb_byte_set_hue_float_offset(col, 0.40); break; - case SEQ_COLOR: + case SEQ_TYPE_COLOR: if (colvars->col) { rgb_float_to_uchar(col, colvars->col); } @@ -154,7 +161,7 @@ static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[ } break; - case SEQ_SOUND: + case SEQ_TYPE_SOUND_RAM: UI_GetThemeColor3ubv(TH_SEQ_AUDIO, col); blendcol[0] = blendcol[1] = blendcol[2] = 128; if (seq->flag & SEQ_MUTE) UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.5, 20); @@ -362,7 +369,7 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, float pixelx, short dire } /* draw! */ - if (seq->type < SEQ_EFFECT || + if (seq->type < SEQ_TYPE_EFFECT || get_sequence_effect_num_inputs(seq->type) == 0) { glEnable(GL_BLEND); @@ -409,7 +416,7 @@ static void draw_seq_extensions(Scene *scene, ARegion *ar, Sequence *seq) unsigned char col[3], blendcol[3]; View2D *v2d = &ar->v2d; - if (seq->type >= SEQ_EFFECT) return; + if (seq->type >= SEQ_TYPE_EFFECT) return; x1 = seq->startdisp; x2 = seq->enddisp; @@ -521,10 +528,10 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float if (name[0] == '\0') name = give_seqname(seq); - if (seq->type == SEQ_META || seq->type == SEQ_ADJUSTMENT) { + if (seq->type == SEQ_TYPE_META || seq->type == SEQ_TYPE_ADJUSTMENT) { BLI_snprintf(str, sizeof(str), "%d | %s", seq->len, name); } - else if (seq->type == SEQ_SCENE) { + else if (seq->type == SEQ_TYPE_SCENE) { if (seq->scene) { if (seq->scene_camera) { BLI_snprintf(str, sizeof(str), "%d | %s: %s (%s)", @@ -540,7 +547,7 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float seq->len, name); } } - else if (seq->type == SEQ_MOVIECLIP) { + else if (seq->type == SEQ_TYPE_MOVIECLIP) { if (seq->clip && strcmp(name, seq->clip->id.name + 2) != 0) { BLI_snprintf(str, sizeof(str), "%d | %s: %s", seq->len, name, seq->clip->id.name + 2); @@ -550,19 +557,29 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float seq->len, name); } } - else if (seq->type == SEQ_MULTICAM) { + else if (seq->type == SEQ_TYPE_MASK) { + if (seq->mask && strcmp(name, seq->mask->id.name + 2) != 0) { + BLI_snprintf(str, sizeof(str), "%d | %s: %s", + seq->len, name, seq->mask->id.name + 2); + } + else { + BLI_snprintf(str, sizeof(str), "%d | %s", + seq->len, name); + } + } + else if (seq->type == SEQ_TYPE_MULTICAM) { BLI_snprintf(str, sizeof(str), "Cam | %s: %d", name, seq->multicam_source); } - else if (seq->type == SEQ_IMAGE) { + else if (seq->type == SEQ_TYPE_IMAGE) { BLI_snprintf(str, sizeof(str), "%d | %s: %s%s", seq->len, name, seq->strip->dir, seq->strip->stripdata->name); } - else if (seq->type & SEQ_EFFECT) { + else if (seq->type & SEQ_TYPE_EFFECT) { BLI_snprintf(str, sizeof(str), "%d | %s", seq->len, name); } - else if (seq->type == SEQ_SOUND) { + else if (seq->type == SEQ_TYPE_SOUND_RAM) { if (seq->sound) BLI_snprintf(str, sizeof(str), "%d | %s: %s", seq->len, name, seq->sound->name); @@ -570,7 +587,7 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float BLI_snprintf(str, sizeof(str), "%d | %s", seq->len, name); } - else if (seq->type == SEQ_MOVIE) { + else if (seq->type == SEQ_TYPE_MOVIE) { BLI_snprintf(str, sizeof(str), "%d | %s: %s%s", seq->len, name, seq->strip->dir, seq->strip->stripdata->name); } @@ -696,7 +713,7 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline x2 = seq->enddisp; /* draw sound wave */ - if (seq->type == SEQ_SOUND) { + if (seq->type == SEQ_TYPE_SOUND_RAM) { drawseqwave(scene, seq, x1, y1, x2, y2, (ar->v2d.cur.xmax - ar->v2d.cur.xmin) / ar->winx); } @@ -743,7 +760,7 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline glDisable(GL_LINE_STIPPLE); } - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { drawmeta_contents(scene, seq, x1, y1, x2, y2); } @@ -969,6 +986,59 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq /* ortho at pixel level */ UI_view2d_view_restore(C); + + //if (sc->mode == SC_MODE_MASKEDIT) { + if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { + Sequence *seq_act = BKE_sequencer_active_get(scene); + + if (seq_act && seq_act->type == SEQ_TYPE_MASK && seq_act->mask) { + int x, y; + int width, height; + float zoomx, zoomy; + + /* frame image */ + float maxdim; + float xofs, yofs; + + /* find window pixel coordinates of origin */ + UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y); + + width = v2d->tot.xmax - v2d->tot.xmin; + height = v2d->tot.ymax - v2d->tot.ymin; + + zoomx = (float)(ar->winrct.xmax - ar->winrct.xmin + 1) / (float)((ar->v2d.cur.xmax - ar->v2d.cur.xmin)); + zoomy = (float)(ar->winrct.ymax - ar->winrct.ymin + 1) / (float)((ar->v2d.cur.ymax - ar->v2d.cur.ymin)); + + x += v2d->tot.xmin * zoomx; + y += v2d->tot.ymin * zoomy; + + /* frame the image */ + maxdim = maxf(width, height); + if (width == height) { + xofs = yofs = 0; + } + else if (width < height) { + xofs = ((height - width) / -2.0f) * zoomx; + yofs = 0.0f; + } + else { /* (width > height) */ + xofs = 0.0f; + yofs = ((width - height) / -2.0f) * zoomy; + } + + /* apply transformation so mask editing tools will assume drawing from the origin in normalized space */ + glPushMatrix(); + glTranslatef(x + xofs, y + yofs, 0); + glScalef(maxdim * zoomx, maxdim * zoomy, 0); + + ED_mask_draw((bContext *)C, 0, 0); // sc->mask_draw_flag, sc->mask_draw_type + + ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); + + glPopMatrix(); + } + } + } #if 0 diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 072cfa00622..c686f8440a9 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -79,21 +79,21 @@ /* XXX */ /* RNA Enums, used in multiple files */ EnumPropertyItem sequencer_prop_effect_types[] = { - {SEQ_CROSS, "CROSS", 0, "Crossfade", "Crossfade effect strip type"}, - {SEQ_ADD, "ADD", 0, "Add", "Add effect strip type"}, - {SEQ_SUB, "SUBTRACT", 0, "Subtract", "Subtract effect strip type"}, - {SEQ_ALPHAOVER, "ALPHA_OVER", 0, "Alpha Over", "Alpha Over effect strip type"}, - {SEQ_ALPHAUNDER, "ALPHA_UNDER", 0, "Alpha Under", "Alpha Under effect strip type"}, - {SEQ_GAMCROSS, "GAMMA_CROSS", 0, "Gamma Cross", "Gamma Cross effect strip type"}, - {SEQ_MUL, "MULTIPLY", 0, "Multiply", "Multiply effect strip type"}, - {SEQ_OVERDROP, "OVER_DROP", 0, "Alpha Over Drop", "Alpha Over Drop effect strip type"}, - {SEQ_WIPE, "WIPE", 0, "Wipe", "Wipe effect strip type"}, - {SEQ_GLOW, "GLOW", 0, "Glow", "Glow effect strip type"}, - {SEQ_TRANSFORM, "TRANSFORM", 0, "Transform", "Transform effect strip type"}, - {SEQ_COLOR, "COLOR", 0, "Color", "Color effect strip type"}, - {SEQ_SPEED, "SPEED", 0, "Speed", "Color effect strip type"}, - {SEQ_MULTICAM, "MULTICAM", 0, "Multicam Selector", ""}, - {SEQ_ADJUSTMENT, "ADJUSTMENT", 0, "Adjustment Layer", ""}, + {SEQ_TYPE_CROSS, "CROSS", 0, "Crossfade", "Crossfade effect strip type"}, + {SEQ_TYPE_ADD, "ADD", 0, "Add", "Add effect strip type"}, + {SEQ_TYPE_SUB, "SUBTRACT", 0, "Subtract", "Subtract effect strip type"}, + {SEQ_TYPE_ALPHAOVER, "ALPHA_OVER", 0, "Alpha Over", "Alpha Over effect strip type"}, + {SEQ_TYPE_ALPHAUNDER, "ALPHA_UNDER", 0, "Alpha Under", "Alpha Under effect strip type"}, + {SEQ_TYPE_GAMCROSS, "GAMMA_CROSS", 0, "Gamma Cross", "Gamma Cross effect strip type"}, + {SEQ_TYPE_MUL, "MULTIPLY", 0, "Multiply", "Multiply effect strip type"}, + {SEQ_TYPE_OVERDROP, "OVER_DROP", 0, "Alpha Over Drop", "Alpha Over Drop effect strip type"}, + {SEQ_TYPE_WIPE, "WIPE", 0, "Wipe", "Wipe effect strip type"}, + {SEQ_TYPE_GLOW, "GLOW", 0, "Glow", "Glow effect strip type"}, + {SEQ_TYPE_TRANSFORM, "TRANSFORM", 0, "Transform", "Transform effect strip type"}, + {SEQ_TYPE_COLOR, "COLOR", 0, "Color", "Color effect strip type"}, + {SEQ_TYPE_SPEED, "SPEED", 0, "Speed", "Color effect strip type"}, + {SEQ_TYPE_MULTICAM, "MULTICAM", 0, "Multicam Selector", ""}, + {SEQ_TYPE_ADJUSTMENT, "ADJUSTMENT", 0, "Adjustment Layer", ""}, {0, NULL, 0, NULL, NULL} }; @@ -478,7 +478,7 @@ int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequen for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->flag & SELECT) { - if (seq->type == SEQ_SOUND && get_sequence_effect_num_inputs(type) != 0) { + if (seq->type == SEQ_TYPE_SOUND_RAM && get_sequence_effect_num_inputs(type) != 0) { *error_str = "Can't apply effects to audio sequence strips"; return 0; } @@ -543,7 +543,7 @@ static Sequence *del_seq_find_replace_recurs(Scene *scene, Sequence *seq) if (!seq) return NULL; - else if (!(seq->type & SEQ_EFFECT)) + else if (!(seq->type & SEQ_TYPE_EFFECT)) return ((seq->flag & SELECT) ? NULL : seq); else if (!(seq->flag & SELECT)) { /* try to find replacement for effect inputs */ @@ -584,7 +584,7 @@ static void recurs_del_seq_flag(Scene *scene, ListBase *lb, short flag, short de if ((seq->flag & flag) || deleteall) { BLI_remlink(lb, seq); if (seq == last_seq) BKE_sequencer_active_set(scene, NULL); - if (seq->type == SEQ_META) recurs_del_seq_flag(scene, &seq->seqbase, flag, 1); + if (seq->type == SEQ_TYPE_META) recurs_del_seq_flag(scene, &seq->seqbase, flag, 1); seq_free_sequence(scene, seq); } seq = seqn; @@ -616,7 +616,7 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe) if ((seq->startstill) && (cutframe < seq->start)) { /* don't do funny things with METAs ... */ - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { skip_dup = TRUE; seq->startstill = seq->start - cutframe; } @@ -637,7 +637,7 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe) else if (((seq->start + seq->len) < cutframe) && (seq->endstill)) { seq->endstill -= seq->enddisp - cutframe; /* don't do funny things with METAs ... */ - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { skip_dup = TRUE; } } @@ -712,7 +712,7 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe) if ((seq->startstill) && (cutframe < seq->start)) { /* don't do funny things with METAs ... */ - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { skip_dup = TRUE; seq->startstill = seq->start - cutframe; } @@ -731,7 +731,7 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe) else if (((seq->start + seq->len) < cutframe) && (seq->endstill)) { seq->endstill -= seq->enddisp - cutframe; /* don't do funny things with METAs ... */ - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { skip_dup = TRUE; } } @@ -855,7 +855,7 @@ static void UNUSED_FUNCTION(touch_seq_files) (Scene * scene) SEQP_BEGIN (ed, seq) { if (seq->flag & SELECT) { - if (seq->type == SEQ_MOVIE) { + if (seq->type == SEQ_TYPE_MOVIE) { if (seq->strip && seq->strip->stripdata) { BLI_make_file_string(G.main->name, str, seq->strip->dir, seq->strip->stripdata->name); BLI_file_touch(seq->name); @@ -883,7 +883,7 @@ static void set_filter_seq(Scene *scene) SEQP_BEGIN (ed, seq) { if (seq->flag & SELECT) { - if (seq->type == SEQ_MOVIE) { + if (seq->type == SEQ_TYPE_MOVIE) { seq->flag |= SEQ_FILTERY; reload_sequence_new_file(scene, seq, FALSE); calc_sequence(scene, seq); @@ -1052,7 +1052,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) shuffle_seq(ed->seqbasep, seq, scene); } } - else if (seq->type & SEQ_EFFECT) { + else if (seq->type & SEQ_TYPE_EFFECT) { if (seq->seq1 && (seq->seq1->flag & SELECT)) calc_sequence(scene, seq); else if (seq->seq2 && (seq->seq2->flag & SELECT)) @@ -1368,7 +1368,7 @@ static int sequencer_effect_poll(bContext *C) if (ed) { Sequence *last_seq = BKE_sequencer_active_get(scene); - if (last_seq && (last_seq->type & SEQ_EFFECT)) { + if (last_seq && (last_seq->type & SEQ_TYPE_EFFECT)) { return 1; } } @@ -1626,7 +1626,7 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op)) /* for effects, try to find a replacement input */ for (seq = ed->seqbasep->first; seq; seq = seq->next) - if ((seq->type & SEQ_EFFECT) && !(seq->flag & SELECT)) + if ((seq->type & SEQ_TYPE_EFFECT) && !(seq->flag & SELECT)) del_seq_find_replace_recurs(scene, seq); /* delete all selected strips */ @@ -1679,7 +1679,7 @@ static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op)) /* for effects, try to find a replacement input */ for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if ((seq->type & SEQ_EFFECT) == 0 && (seq->flag & SELECT)) { + if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) { seq->startofs = seq->endofs = seq->startstill = seq->endstill = 0; } } @@ -1692,7 +1692,7 @@ static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op)) } for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if ((seq->type & SEQ_EFFECT) == 0 && (seq->flag & SELECT)) { + if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) { if (seq_test_overlap(ed->seqbasep, seq)) { shuffle_seq(ed->seqbasep, seq, scene); } @@ -1737,7 +1737,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) seq = ed->seqbasep->first; /* poll checks this is valid */ while (seq) { - if ((seq->flag & SELECT) && (seq->type == SEQ_IMAGE) && (seq->len > 1)) { + if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) && (seq->len > 1)) { /* remove seq so overlap tests don't conflict, * see seq_free_sequence below for the real free'ing */ BLI_remlink(ed->seqbasep, seq); @@ -1755,7 +1755,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) BLI_addtail(ed->seqbasep, seq_new); seq_new->start = start_ofs; - seq_new->type = SEQ_IMAGE; + seq_new->type = SEQ_TYPE_IMAGE; seq_new->len = 1; seq_new->endstill = step - 1; @@ -1826,7 +1826,7 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op)) Sequence *last_seq = BKE_sequencer_active_get(scene); MetaStack *ms; - if (last_seq && last_seq->type == SEQ_META && last_seq->flag & SELECT) { + if (last_seq && last_seq->type == SEQ_TYPE_META && last_seq->flag & SELECT) { /* Enter Metastrip */ ms = MEM_mallocN(sizeof(MetaStack), "metastack"); BLI_addtail(&ed->metastack, ms); @@ -1904,7 +1904,7 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op) seqm = alloc_sequence(ed->seqbasep, 1, 1); /* channel number set later */ strcpy(seqm->name + 2, "MetaStrip"); - seqm->type = SEQ_META; + seqm->type = SEQ_TYPE_META; seqm->flag = SELECT; seq = ed->seqbasep->first; @@ -1970,7 +1970,7 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op)) Sequence *seq, *last_seq = BKE_sequencer_active_get(scene); /* last_seq checks (ed == NULL) */ - if (last_seq == NULL || last_seq->type != SEQ_META) + if (last_seq == NULL || last_seq->type != SEQ_TYPE_META) return OPERATOR_CANCELLED; BLI_movelisttolist(ed->seqbasep, &last_seq->seqbase); @@ -1983,7 +1983,7 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op)) /* emtpy meta strip, delete all effects depending on it */ for (seq = ed->seqbasep->first; seq; seq = seq->next) - if ((seq->type & SEQ_EFFECT) && seq_depends_on_meta(seq, last_seq)) + if ((seq->type & SEQ_TYPE_EFFECT) && seq_depends_on_meta(seq, last_seq)) seq->flag |= SEQ_FLAG_DELETE; recurs_del_seq_flag(scene, ed->seqbasep, SEQ_FLAG_DELETE, 0); @@ -2454,14 +2454,14 @@ static int sequencer_swap_exec(bContext *C, wmOperator *op) // XXX - should be a generic function for (iseq = scene->ed->seqbasep->first; iseq; iseq = iseq->next) { - if ((iseq->type & SEQ_EFFECT) && (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) { + if ((iseq->type & SEQ_TYPE_EFFECT) && (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) { calc_sequence(scene, iseq); } } /* do this in a new loop since both effects need to be calculated first */ for (iseq = scene->ed->seqbasep->first; iseq; iseq = iseq->next) { - if ((iseq->type & SEQ_EFFECT) && (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) { + if ((iseq->type & SEQ_TYPE_EFFECT) && (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) { /* this may now overlap */ if (seq_test_overlap(ed->seqbasep, iseq) ) { shuffle_seq(ed->seqbasep, iseq, scene); @@ -2512,16 +2512,16 @@ static int sequencer_rendersize_exec(bContext *C, wmOperator *UNUSED(op)) if (active_seq->strip) { switch (active_seq->type) { - case SEQ_IMAGE: + case SEQ_TYPE_IMAGE: se = give_stripelem(active_seq, scene->r.cfra); break; - case SEQ_MOVIE: + case SEQ_TYPE_MOVIE: se = active_seq->strip->stripdata; break; - case SEQ_SCENE: - case SEQ_META: - case SEQ_RAM_SOUND: - case SEQ_HD_SOUND: + case SEQ_TYPE_SCENE: + case SEQ_TYPE_META: + case SEQ_TYPE_SOUND_RAM: + case SEQ_TYPE_SOUND_HD: default: break; } @@ -2559,7 +2559,7 @@ void SEQUENCER_OT_rendersize(wmOperatorType *ot) static void seq_copy_del_sound(Scene *scene, Sequence *seq) { - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { Sequence *iseq; for (iseq = seq->seqbase.first; iseq; iseq = iseq->next) { seq_copy_del_sound(scene, iseq); @@ -2900,7 +2900,7 @@ static int sequencer_change_effect_type_exec(bContext *C, wmOperator *op) /* free previous effect and init new effect */ struct SeqEffectHandle sh; - if ((seq->type & SEQ_EFFECT) == 0) { + if ((seq->type & SEQ_TYPE_EFFECT) == 0) { return OPERATOR_CANCELLED; } @@ -2947,7 +2947,7 @@ void SEQUENCER_OT_change_effect_type(struct wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - ot->prop = RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_CROSS, "Type", "Sequencer effect type"); + ot->prop = RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_TYPE_CROSS, "Type", "Sequencer effect type"); } static int sequencer_change_path_exec(bContext *C, wmOperator *op) @@ -2958,7 +2958,7 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op) Sequence *seq = BKE_sequencer_active_get(scene); const int is_relative_path = RNA_boolean_get(op->ptr, "relative_path"); - if (seq->type == SEQ_IMAGE) { + if (seq->type == SEQ_TYPE_IMAGE) { char directory[FILE_MAX]; const int len = RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files")); StripElem *se; @@ -3028,7 +3028,7 @@ static int sequencer_change_path_invoke(bContext *C, wmOperator *op, wmEvent *UN RNA_string_set(op->ptr, "directory", seq->strip->dir); /* set default display depending on seq type */ - if (seq->type == SEQ_IMAGE) { + if (seq->type == SEQ_TYPE_IMAGE) { RNA_boolean_set(op->ptr, "filter_movie", FALSE); } else { diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h index 19cd7ed4ad4..25a322c6905 100644 --- a/source/blender/editors/space_sequencer/sequencer_intern.h +++ b/source/blender/editors/space_sequencer/sequencer_intern.h @@ -138,6 +138,7 @@ void SEQUENCER_OT_select_grouped(struct wmOperatorType *ot); void SEQUENCER_OT_scene_strip_add(struct wmOperatorType *ot); void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot); void SEQUENCER_OT_movieclip_strip_add(struct wmOperatorType *ot); +void SEQUENCER_OT_mask_strip_add(struct wmOperatorType *ot); void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot); void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot); void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c index 3a02c90f99a..79ecd9f7481 100644 --- a/source/blender/editors/space_sequencer/sequencer_ops.c +++ b/source/blender/editors/space_sequencer/sequencer_ops.c @@ -105,6 +105,7 @@ void sequencer_operatortypes(void) /* sequencer_add.c */ WM_operatortype_append(SEQUENCER_OT_scene_strip_add); WM_operatortype_append(SEQUENCER_OT_movieclip_strip_add); + WM_operatortype_append(SEQUENCER_OT_mask_strip_add); WM_operatortype_append(SEQUENCER_OT_movie_strip_add); WM_operatortype_append(SEQUENCER_OT_sound_strip_add); WM_operatortype_append(SEQUENCER_OT_image_strip_add); diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 3911ec0ef82..b03edfc61b9 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -171,11 +171,11 @@ void ED_sequencer_select_sequence_single(Scene * scene, Sequence * seq, int dese BKE_sequencer_active_set(scene, seq); - if ((seq->type == SEQ_IMAGE) || (seq->type == SEQ_MOVIE)) { + if ((seq->type == SEQ_TYPE_IMAGE) || (seq->type == SEQ_TYPE_MOVIE)) { if (seq->strip) BLI_strncpy(ed->act_imagedir, seq->strip->dir, FILE_MAXDIR); } - else if (seq->type == SEQ_SOUND) { + else if (seq->type == SEQ_TYPE_SOUND_RAM) { if (seq->strip) BLI_strncpy(ed->act_sounddir, seq->strip->dir, FILE_MAXDIR); } @@ -409,13 +409,13 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, wmEvent *event) if (seq) { BKE_sequencer_active_set(scene, seq); - if ((seq->type == SEQ_IMAGE) || (seq->type == SEQ_MOVIE)) { + if ((seq->type == SEQ_TYPE_IMAGE) || (seq->type == SEQ_TYPE_MOVIE)) { if (seq->strip) { BLI_strncpy(ed->act_imagedir, seq->strip->dir, FILE_MAXDIR); } } else - if (seq->type == SEQ_SOUND) { + if (seq->type == SEQ_TYPE_SOUND_RAM) { if (seq->strip) { BLI_strncpy(ed->act_sounddir, seq->strip->dir, FILE_MAXDIR); } @@ -930,11 +930,11 @@ static EnumPropertyItem sequencer_prop_select_grouped_types[] = { {0, NULL, 0, NULL, NULL} }; -#define SEQ_IS_SOUND(_seq) ((_seq->type & SEQ_SOUND) && !(_seq->type & SEQ_EFFECT)) +#define SEQ_IS_SOUND(_seq) ((_seq->type & SEQ_TYPE_SOUND_RAM) && !(_seq->type & SEQ_TYPE_EFFECT)) -#define SEQ_IS_EFFECT(_seq) (_seq->type & SEQ_EFFECT) +#define SEQ_IS_EFFECT(_seq) (_seq->type & SEQ_TYPE_EFFECT) -#define SEQ_USE_DATA(_seq) (ELEM(_seq->type, SEQ_SCENE, SEQ_MOVIECLIP) || SEQ_HAS_PATH(_seq)) +#define SEQ_USE_DATA(_seq) (ELEM3(_seq->type, SEQ_TYPE_SCENE, SEQ_TYPE_MOVIECLIP, SEQ_TYPE_MASK) || SEQ_HAS_PATH(_seq)) static short select_grouped_type(Editing *ed, Sequence *actseq) { @@ -1008,22 +1008,33 @@ static short select_grouped_data(Editing *ed, Sequence *actseq) } SEQ_END; } - else if (actseq->type == SEQ_SCENE) { + else if (actseq->type == SEQ_TYPE_SCENE) { Scene *sce = actseq->scene; SEQP_BEGIN (ed, seq) { - if (seq->type == SEQ_SCENE && seq->scene == sce) { + if (seq->type == SEQ_TYPE_SCENE && seq->scene == sce) { seq->flag |= SELECT; changed = TRUE; } } SEQ_END; } - else if (actseq->type == SEQ_MOVIECLIP) { + else if (actseq->type == SEQ_TYPE_MOVIECLIP) { MovieClip *clip = actseq->clip; SEQP_BEGIN (ed, seq) { - if (seq->type == SEQ_MOVIECLIP && seq->clip == clip) { + if (seq->type == SEQ_TYPE_MOVIECLIP && seq->clip == clip) { + seq->flag |= SELECT; + changed = TRUE; + } + } + SEQ_END; + } + else if (actseq->type == SEQ_TYPE_MASK) { + struct Mask *mask = actseq->mask; + SEQP_BEGIN (ed, seq) + { + if (seq->type == SEQ_TYPE_MASK && seq->mask == mask) { seq->flag |= SELECT; changed = TRUE; } @@ -1038,10 +1049,10 @@ static short select_grouped_effect(Editing *ed, Sequence *actseq) { Sequence *seq; short changed = FALSE; - short effects[SEQ_EFFECT_MAX + 1]; + short effects[SEQ_TYPE_EFFECT_MAX + 1]; int i; - for (i = 0; i <= SEQ_EFFECT_MAX; i++) + for (i = 0; i <= SEQ_TYPE_EFFECT_MAX; i++) effects[i] = FALSE; SEQP_BEGIN (ed, seq) @@ -1087,7 +1098,7 @@ static short select_grouped_effect_link(Editing *ed, Sequence *actseq) { Sequence *seq = NULL; short changed = FALSE; - short is_audio = ((actseq->type == SEQ_META) || SEQ_IS_SOUND(actseq)); + short is_audio = ((actseq->type == SEQ_TYPE_META) || SEQ_IS_SOUND(actseq)); int startdisp = actseq->startdisp; int enddisp = actseq->enddisp; int machine = actseq->machine; @@ -1109,7 +1120,7 @@ static short select_grouped_effect_link(Editing *ed, Sequence *actseq) /* Ignore all seqs of incompatible types (audio vs video). */ if ((seq->flag & SELECT) || (seq->startdisp >= enddisp) || (seq->enddisp < startdisp) || (!is_audio && SEQ_IS_SOUND(seq)) || - (is_audio && !((seq->type == SEQ_META) || SEQ_IS_SOUND(seq)))) + (is_audio && !((seq->type == SEQ_TYPE_META) || SEQ_IS_SOUND(seq)))) { continue; } diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 4168cb9ac77..3643f92d334 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -33,6 +33,7 @@ #include <stdio.h> #include "DNA_scene_types.h" +#include "DNA_mask_types.h" #include "MEM_guardedalloc.h" @@ -380,6 +381,29 @@ static void sequencer_dropboxes(void) /* ************* end drop *********** */ +const char *sequencer_context_dir[] = {"edit_mask", NULL}; + +static int sequencer_context(const bContext *C, const char *member, bContextDataResult *result) +{ + Scene *scene = CTX_data_scene(C); + + if (CTX_data_dir(member)) { + CTX_data_dir_set(result, sequencer_context_dir); + + return TRUE; + } + else if (CTX_data_equals(member, "edit_mask")) { + Sequence *seq_act = BKE_sequencer_active_get(scene); + if (seq_act && seq_act->type == SEQ_TYPE_MASK && seq_act->mask) { + CTX_data_id_pointer_set(result, &seq_act->mask->id); + } + return TRUE; + } + + return FALSE; +} + + /* add handlers, stuff you only do once or on area/region changes */ static void sequencer_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar) { @@ -482,6 +506,12 @@ static void sequencer_preview_area_listener(ARegion *ar, wmNotifier *wmn) break; } break; + + case NC_MASK: + if (wmn->action == NA_EDITED) { + ED_region_tag_redraw(ar); + } + break; } } @@ -539,6 +569,7 @@ void ED_spacetype_sequencer(void) st->duplicate = sequencer_duplicate; st->operatortypes = sequencer_operatortypes; st->keymap = sequencer_keymap; + st->context = sequencer_context; st->dropboxes = sequencer_dropboxes; st->refresh = sequencer_refresh; @@ -591,4 +622,3 @@ void ED_spacetype_sequencer(void) sequencer_view3d_cb = ED_view3d_draw_offscreen_imbuf_simple; } } - diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index 0de7e2569c0..e51f7a312eb 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -557,7 +557,7 @@ static void draw_bone_solid_octahedral(void) /* *************** Armature drawing, bones ******************* */ -static void draw_bone_points(int dt, int armflag, unsigned int boneflag, int id) +static void draw_bone_points(const short dt, int armflag, unsigned int boneflag, int id) { /* Draw root point if we are not connected */ if ((boneflag & BONE_CONNECTED) == 0) { @@ -862,7 +862,7 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], } /* does wire only for outline selecting */ -static void draw_sphere_bone(int dt, int armflag, int boneflag, short constflag, unsigned int id, +static void draw_sphere_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) { GLUquadricObj *qobj; @@ -1100,7 +1100,7 @@ static void draw_line_bone(int armflag, int boneflag, short constflag, unsigned glPopMatrix(); } -static void draw_b_bone_boxes(int dt, bPoseChannel *pchan, float xwidth, float length, float zwidth) +static void draw_b_bone_boxes(const short dt, bPoseChannel *pchan, float xwidth, float length, float zwidth) { int segments = 0; @@ -1128,7 +1128,7 @@ static void draw_b_bone_boxes(int dt, bPoseChannel *pchan, float xwidth, float l } } -static void draw_b_bone(int dt, int armflag, int boneflag, short constflag, unsigned int id, +static void draw_b_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) { float xwidth, length, zwidth; @@ -1242,7 +1242,7 @@ static void draw_wire_bone_segments(bPoseChannel *pchan, Mat4 *bbones, float len } } -static void draw_wire_bone(int dt, int armflag, int boneflag, short constflag, unsigned int id, +static void draw_wire_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) { Mat4 *bbones = NULL; @@ -1293,7 +1293,7 @@ static void draw_wire_bone(int dt, int armflag, int boneflag, short constflag, u draw_wire_bone_segments(pchan, bbones, length, segments); } -static void draw_bone(int dt, int armflag, int boneflag, short constflag, unsigned int id, float length) +static void draw_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, float length) { /* Draw a 3d octahedral bone, we use normalized space based on length, @@ -1364,7 +1364,7 @@ static void draw_bone(int dt, int armflag, int boneflag, short constflag, unsign } static void draw_custom_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, - int dt, int armflag, int boneflag, unsigned int id, float length) + const short dt, int armflag, int boneflag, unsigned int id, float length) { if (ob == NULL) return; @@ -1656,8 +1656,9 @@ static void bone_matrix_translate_y(float mat[][4], float y) } /* assumes object is Armature with pose */ -static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, - const short is_ghost, const short is_outline) +static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, + const short dt, const unsigned char ob_wire_col[4], + const short do_const_color, const short is_outline) { RegionView3D *rv3d = ar->regiondata; Object *ob = base->object; @@ -1752,8 +1753,13 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, if (bone == arm->act_bone) flag |= BONE_DRAW_ACTIVE; - /* set color-set to use */ - set_pchan_colorset(ob, pchan); + if (do_const_color) { + /* keep color */ + } + else { + /* set color-set to use */ + set_pchan_colorset(ob, pchan); + } if (use_custom) { /* if drawwire, don't try to draw in solid */ @@ -1827,20 +1833,13 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, } /* prepare colors */ - if (is_ghost) { + if (do_const_color) { /* 13 October 2009, Disabled this to make ghosting show the right colors (Aligorith) */ } - else if (arm->flag & ARM_POSEMODE) + else if (arm->flag & ARM_POSEMODE) set_pchan_colorset(ob, pchan); else { - if ((scene->basact) == base) { - if (base->flag & (SELECT + BA_WAS_SEL)) UI_ThemeColor(TH_ACTIVE); - else UI_ThemeColor(TH_WIRE); - } - else { - if (base->flag & (SELECT + BA_WAS_SEL)) UI_ThemeColor(TH_SELECT); - else UI_ThemeColor(TH_WIRE); - } + glColor3ubv(ob_wire_col); } /* catch exception for bone with hidden parent */ @@ -1956,7 +1955,12 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, /* extra draw service for pose mode */ /* set color-set to use */ - set_pchan_colorset(ob, pchan); + if (do_const_color) { + /* keep color */ + } + else { + set_pchan_colorset(ob, pchan); + } if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) { /* custom bone shapes should not be drawn here! */ @@ -1991,20 +1995,35 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, glDisable(GL_CULL_FACE); /* draw DoFs */ - if (arm->flag & ARM_POSEMODE) - draw_pose_dofs(ob); + if (arm->flag & ARM_POSEMODE) { + if (((base->flag & OB_FROMDUPLI) == 0)) { + draw_pose_dofs(ob); + } + } /* finally names and axes */ - if ((arm->flag & (ARM_DRAWNAMES | ARM_DRAWAXES)) && (is_outline == 0)) { + if ((arm->flag & (ARM_DRAWNAMES | ARM_DRAWAXES)) && + (is_outline == 0) && + ((base->flag & OB_FROMDUPLI) == 0)) + { /* patch for several 3d cards (IBM mostly) that crash on GL_SELECT with text drawing */ if ((G.f & G_PICKSEL) == 0) { float vec[3]; - + unsigned char col[4]; - float col_f[4]; - glGetFloatv(GL_CURRENT_COLOR, col_f); /* in case this is not set below */ - rgb_float_to_uchar(col, col_f); - col[3] = 255; + if (do_const_color) { + /* so we can draw bone names in current const color */ + float tcol[4]; + glGetFloatv(GL_CURRENT_COLOR, tcol); + rgb_float_to_uchar(col, tcol); + col[3] = 255; + } + else { + col[0] = ob_wire_col[0]; + col[1] = ob_wire_col[1]; + col[2] = ob_wire_col[2]; + col[3] = 255; + } if (v3d->zbuf) glDisable(GL_DEPTH_TEST); @@ -2063,7 +2082,7 @@ static void get_matrix_editbone(EditBone *eBone, float bmat[][4]) add_v3_v3(bmat[3], eBone->head); } -static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt) +static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt) { RegionView3D *rv3d = ar->regiondata; EditBone *eBone; @@ -2353,7 +2372,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); BKE_pose_where_is(scene, ob); - draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE); + draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, TRUE, FALSE); } glDisable(GL_BLEND); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); @@ -2432,7 +2451,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base * BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); BKE_pose_where_is(scene, ob); - draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE); + draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, TRUE, FALSE); } glDisable(GL_BLEND); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); @@ -2502,7 +2521,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base) if (CFRA != cfrao) { BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); BKE_pose_where_is(scene, ob); - draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE); + draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, TRUE, FALSE); } } @@ -2517,7 +2536,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base) if (CFRA != cfrao) { BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); BKE_pose_where_is(scene, ob); - draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE); + draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, TRUE, FALSE); } } } @@ -2537,8 +2556,11 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base) /* ********************************** Armature Drawing - Main ************************* */ -/* called from drawobject.c, return 1 if nothing was drawn */ -int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag, const short is_outline) +/* called from drawobject.c, return 1 if nothing was drawn + * (ob_wire_col == NULL) when drawing ghost */ +int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, + const short dt, const short dflag, const unsigned char ob_wire_col[4], + const short is_outline) { Object *ob = base->object; bArmature *arm = ob->data; @@ -2549,11 +2571,8 @@ int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, in if (dt > OB_WIRE && !ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) { /* we use color for solid lighting */ - glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); - glEnable(GL_COLOR_MATERIAL); - glColor3ub(255, 255, 255); // clear spec - glDisable(GL_COLOR_MATERIAL); - + const float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white); glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); // only for lighting... } @@ -2594,7 +2613,7 @@ int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, in if (arm->ghostep) draw_ghost_poses(scene, v3d, ar, base); } - if ((flag & DRAW_SCENESET) == 0) { + if ((dflag & DRAW_SCENESET) == 0) { if (ob == OBACT) arm->flag |= ARM_POSEMODE; else if (OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) { @@ -2605,7 +2624,7 @@ int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, in } } } - draw_pose_bones(scene, v3d, ar, base, dt, FALSE, is_outline); + draw_pose_bones(scene, v3d, ar, base, dt, ob_wire_col, (dflag & DRAW_CONSTCOLOR), is_outline); arm->flag &= ~ARM_POSEMODE; if (ob->mode & OB_MODE_POSE) diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index de1d9f22667..19696b2b0e0 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -1015,14 +1015,14 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *d if (ob && ob->mode & OB_MODE_WEIGHT_PAINT) { if (do_light) { + const float spec[4] = {0.47f, 0.47f, 0.47f, 0.47f}; + /* enforce default material settings */ GPU_enable_material(0, NULL); /* but set default spec */ glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); - glEnable(GL_COLOR_MATERIAL); /* according manpages needed */ - glColor3ub(120, 120, 120); - glDisable(GL_COLOR_MATERIAL); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec); /* diffuse */ glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 498189321be..7e84ab062ca 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -333,7 +333,7 @@ static void view3d_project_short_clip_persmat(ARegion *ar, const float vec[3], s /* check for glsl drawing */ -int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt) +int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const short dt) { if (!GPU_glsl_support()) return 0; @@ -1189,14 +1189,17 @@ static void draw_transp_spot_volume(Lamp *la, float x, float z) glCullFace(GL_BACK); } -static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag) +static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, + const short dt, const short dflag, const unsigned char ob_wire_col[4]) { Object *ob = base->object; const float pixsize = ED_view3d_pixel_size(rv3d, ob->obmat[3]); Lamp *la = ob->data; float vec[3], lvec[3], vvec[3], circrad, x, y, z; float lampsize; - float imat[4][4], curcol[4]; + float imat[4][4]; + + unsigned char curcol[4]; unsigned char col[4]; /* cone can't be drawn for duplicated lamps, because duplilist would be freed to */ /* the moment of view3d_draw_transp() call */ @@ -1210,7 +1213,7 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, if (drawcone && !v3d->transp) { /* in this case we need to draw delayed */ - add_view3d_after(&v3d->afterdraw_transp, base, flag); + ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag); return; } @@ -1228,17 +1231,23 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, /* lamp center */ copy_v3_v3(vec, ob->obmat[3]); - - /* for AA effects */ - glGetFloatv(GL_CURRENT_COLOR, curcol); - curcol[3] = 0.6; - glColor4fv(curcol); - + + if ((dflag & DRAW_CONSTCOLOR) == 0) { + /* for AA effects */ + curcol[0] = ob_wire_col[0]; + curcol[1] = ob_wire_col[1]; + curcol[2] = ob_wire_col[2]; + curcol[3] = 154; + glColor4ubv(curcol); + } + if (lampsize > 0.0f) { - if (ob->id.us > 1) { - if (ob == OBACT || (ob->flag & SELECT)) glColor4ub(0x88, 0xFF, 0xFF, 155); - else glColor4ub(0x77, 0xCC, 0xCC, 155); + if ((dflag & DRAW_CONSTCOLOR) == 0) { + if (ob->id.us > 1) { + if (ob == OBACT || (ob->flag & SELECT)) glColor4ub(0x88, 0xFF, 0xFF, 155); + else glColor4ub(0x77, 0xCC, 0xCC, 155); + } } /* Inner Circle */ @@ -1248,8 +1257,10 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, drawcircball(GL_POLYGON, vec, lampsize, imat); /* restore */ - if (ob->id.us > 1) - glColor4fv(curcol); + if ((dflag & DRAW_CONSTCOLOR) == 0) { + if (ob->id.us > 1) + glColor4ubv(curcol); + } /* Outer circle */ circrad = 3.0f * lampsize; @@ -1481,9 +1492,10 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, glDisable(GL_BLEND); - /* restore for drawing extra stuff */ - glColor3fv(curcol); - + if ((dflag & DRAW_CONSTCOLOR) == 0) { + /* restore for drawing extra stuff */ + glColor3ubv(ob_wire_col); + } } static void draw_limit_line(float sta, float end, unsigned int col) @@ -1516,7 +1528,7 @@ static void draw_focus_cross(float dist, float size) } #ifdef VIEW3D_CAMERA_BORDER_HACK -float view3d_camera_border_hack_col[4]; +unsigned char view3d_camera_border_hack_col[3]; short view3d_camera_border_hack_test = FALSE; #endif @@ -1546,8 +1558,8 @@ static void draw_bundle_sphere(void) } static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D *v3d, - MovieClip *clip, MovieTrackingObject *tracking_object, int flag, - int *global_track_index, int draw_selected) + MovieClip *clip, MovieTrackingObject *tracking_object, + const short dflag, int *global_track_index, int draw_selected) { MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *track; @@ -1590,7 +1602,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D if ((track->flag & TRACK_HAS_BUNDLE) == 0) continue; - if (flag & DRAW_PICKING) + if (dflag & DRAW_PICKING) glLoadName(base->selcol + (tracknr << 16)); glPushMatrix(); @@ -1656,7 +1668,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D glPopMatrix(); - if ((flag & DRAW_PICKING) == 0 && (v3d->flag2 & V3D_SHOW_BUNDLENAME)) { + if ((dflag & DRAW_PICKING) == 0 && (v3d->flag2 & V3D_SHOW_BUNDLENAME)) { float pos[3]; unsigned char tcol[4]; @@ -1670,7 +1682,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D tracknr++; } - if ((flag & DRAW_PICKING) == 0) { + if ((dflag & DRAW_PICKING) == 0) { if ((v3d->flag2 & V3D_SHOW_CAMERAPATH) && (tracking_object->flag & TRACKING_OBJECT_CAMERA)) { MovieTrackingReconstruction *reconstruction; reconstruction = BKE_tracking_object_reconstruction(tracking, tracking_object); @@ -1701,11 +1713,11 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D } static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, MovieClip *clip, - int flag, int draw_selected) + const short dflag, const unsigned char ob_wire_col[4], + int draw_selected) { MovieTracking *tracking = &clip->tracking; MovieTrackingObject *tracking_object; - float curcol[4]; int global_track_index = 1; if ((v3d->flag2 & V3D_SHOW_RECONSTRUCTION) == 0) @@ -1714,8 +1726,6 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, if (v3d->flag2 & V3D_RENDER_OVERRIDE) return; - glGetFloatv(GL_CURRENT_COLOR, curcol); - glEnable(GL_LIGHTING); glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); @@ -1724,7 +1734,7 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, tracking_object = tracking->objects.first; while (tracking_object) { draw_viewport_object_reconstruction(scene, base, v3d, clip, tracking_object, - flag, &global_track_index, draw_selected); + dflag, &global_track_index, draw_selected); tracking_object = tracking_object->next; } @@ -1734,14 +1744,17 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, glDisable(GL_COLOR_MATERIAL); glDisable(GL_LIGHTING); - glColor4fv(curcol); + if ((dflag & DRAW_CONSTCOLOR) == 0) { + glColor3ubv(ob_wire_col); + } - if (flag & DRAW_PICKING) + if (dflag & DRAW_PICKING) glLoadName(base->selcol); } /* flag similar to draw_object() */ -static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int flag) +static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, + const short dflag, const unsigned char ob_wire_col[4]) { /* a standing up pyramid with (0,0,0) as top */ Camera *cam; @@ -1755,13 +1768,22 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base /* draw data for movie clip set as active for scene */ if (clip) { - draw_viewport_reconstruction(scene, base, v3d, clip, flag, FALSE); - draw_viewport_reconstruction(scene, base, v3d, clip, flag, TRUE); + draw_viewport_reconstruction(scene, base, v3d, clip, dflag, ob_wire_col, FALSE); + draw_viewport_reconstruction(scene, base, v3d, clip, dflag, ob_wire_col, TRUE); } #ifdef VIEW3D_CAMERA_BORDER_HACK if (is_view && !(G.f & G_PICKSEL)) { - glGetFloatv(GL_CURRENT_COLOR, view3d_camera_border_hack_col); + if ((dflag & DRAW_CONSTCOLOR) == 0) { + view3d_camera_border_hack_col[0] = ob_wire_col[0]; + view3d_camera_border_hack_col[1] = ob_wire_col[1]; + view3d_camera_border_hack_col[2] = ob_wire_col[2]; + } + else { + float col[4]; + glGetFloatv(GL_CURRENT_COLOR, col); + rgb_float_to_uchar(view3d_camera_border_hack_col, col); + } view3d_camera_border_hack_test = TRUE; return; } @@ -1829,7 +1851,7 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base glEnd(); } - if (flag == 0) { + if (dflag == 0) { if (cam->flag & (CAM_SHOWLIMITS + CAM_SHOWMIST)) { float nobmat[4][4]; World *wrld; @@ -2451,7 +2473,7 @@ static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3], } static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, int sel, BMVert *eve_act, - RegionView3D *rv3d) + RegionView3D *rv3d) { drawDMVerts_userData data; data.sel = sel; @@ -3140,7 +3162,7 @@ static DMDrawOption draw_em_fancy__setGLSLFaceOpts(void *userData, int index) } static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, - Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, int dt) + Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, const short dt) { Mesh *me = ob->data; @@ -3361,7 +3383,8 @@ static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm) } } -static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag) +static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, + const short dt, const short dflag) { Object *ob = base->object; Mesh *me = ob->data; @@ -3447,10 +3470,12 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D else if (dt == OB_SOLID) { if (draw_flags & DRAW_MODIFIERS_PREVIEW) { /* for object selection draws no shade */ - if (flag & (DRAW_PICKING | DRAW_CONSTCOLOR)) { + if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) { dm->drawFacesSolid(dm, NULL, 0, GPU_enable_material); } else { + const float spec[4] = {0.47f, 0.47f, 0.47f, 0.47f}; + /* draw outline */ if ( (v3d->flag & V3D_SELECT_OUTLINE) && ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && @@ -3468,9 +3493,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D /* set default spec */ glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); - glEnable(GL_COLOR_MATERIAL); /* according manpages needed */ - glColor3ub(120, 120, 120); - glDisable(GL_COLOR_MATERIAL); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec); /* diffuse */ glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glEnable(GL_LIGHTING); @@ -3549,7 +3572,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D UI_ThemeColor(TH_GROUP_ACTIVE); else if (ob->flag & OB_FROMGROUP) UI_ThemeColorShade(TH_GROUP_ACTIVE, -16); - else if (flag != DRAW_CONSTCOLOR) + else if (dflag != DRAW_CONSTCOLOR) UI_ThemeColor(is_obact ? TH_ACTIVE : TH_SELECT); else glColor3ub(80, 80, 80); @@ -3558,7 +3581,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D if (ob->flag & OB_FROMGROUP) UI_ThemeColor(TH_GROUP); else { - if (ob->dtx & OB_DRAWWIRE && flag == DRAW_CONSTCOLOR) + if (ob->dtx & OB_DRAWWIRE && dflag == DRAW_CONSTCOLOR) glColor3ub(80, 80, 80); else UI_ThemeColor(TH_WIRE); @@ -3615,7 +3638,8 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D } /* returns 1 if nothing was drawn, for detecting to draw an object center */ -static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag) +static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, + const short dt, const short dflag) { Object *ob = base->object; Object *obedit = scene->obedit; @@ -3679,7 +3703,7 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D (check_alpha) ? &do_alpha_after : NULL); } - draw_mesh_fancy(scene, ar, v3d, rv3d, base, dt, flag); + draw_mesh_fancy(scene, ar, v3d, rv3d, base, dt, dflag); GPU_end_object_materials(); @@ -3687,20 +3711,20 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D } } - if ((flag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) { + if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) { /* GPU_begin_object_materials checked if this is needed */ if (do_alpha_after) { if (ob->dtx & OB_DRAWXRAY) { - add_view3d_after(&v3d->afterdraw_xraytransp, base, flag); + ED_view3d_after_add(&v3d->afterdraw_xraytransp, base, dflag); } else { - add_view3d_after(&v3d->afterdraw_transp, base, flag); + ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag); } } else if (ob->dtx & OB_DRAWXRAY && ob->dtx & OB_DRAWTRANSP) { /* special case xray+transp when alpha is 1.0, without this the object vanishes */ if (v3d->xray == 0 && v3d->transp == 0) { - add_view3d_after(&v3d->afterdraw_xray, base, flag); + ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag); } } } @@ -3808,17 +3832,15 @@ static int drawDispListwire(ListBase *dlbase) return 0; } -static void drawDispListsolid(ListBase *lb, Object *ob, int glsl) +static void drawDispListsolid(ListBase *lb, Object *ob, + const unsigned char ob_wire_col[4], int use_glsl) { DispList *dl; GPUVertexAttribs gattribs; - float *data, curcol[4]; + float *data; float *ndata; if (lb == NULL) return; - - /* for drawing wire */ - glGetFloatv(GL_CURRENT_COLOR, curcol); glEnable(GL_LIGHTING); glEnableClientState(GL_VERTEX_ARRAY); @@ -3841,7 +3863,7 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl) int nr; glDisable(GL_LIGHTING); - glColor3fv(curcol); + glColor3ubv(ob_wire_col); // glVertexPointer(3, GL_FLOAT, 0, dl->verts); // glDrawArrays(GL_LINE_STRIP, 0, dl->nr); @@ -3875,7 +3897,7 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl) case DL_SURF: if (dl->index) { - GPU_enable_material(dl->col + 1, (glsl) ? &gattribs : NULL); + GPU_enable_material(dl->col + 1, (use_glsl) ? &gattribs : NULL); if (dl->rt & CU_SMOOTH) glShadeModel(GL_SMOOTH); else glShadeModel(GL_FLAT); @@ -3889,7 +3911,7 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl) break; case DL_INDEX3: - GPU_enable_material(dl->col + 1, (glsl) ? &gattribs : NULL); + GPU_enable_material(dl->col + 1, (use_glsl) ? &gattribs : NULL); glVertexPointer(3, GL_FLOAT, 0, dl->verts); @@ -3909,7 +3931,7 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl) break; case DL_INDEX4: - GPU_enable_material(dl->col + 1, (glsl) ? &gattribs : NULL); + GPU_enable_material(dl->col + 1, (use_glsl) ? &gattribs : NULL); glEnableClientState(GL_NORMAL_ARRAY); glVertexPointer(3, GL_FLOAT, 0, dl->verts); @@ -3935,7 +3957,7 @@ static void drawCurveDMWired(Object *ob) } /* return 1 when nothing was drawn */ -static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt) +static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, const short dt) { Object *ob = base->object; DerivedMesh *dm = ob->derivedFinal; @@ -3967,7 +3989,8 @@ static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, B } /* returns 1 when nothing was drawn */ -static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt) +static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, + const short dt, const unsigned char ob_wire_col[4]) { Object *ob = base->object; ListBase *lb = NULL; @@ -4015,12 +4038,12 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas else { if (draw_glsl_material(scene, ob, v3d, dt)) { GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL); - drawDispListsolid(lb, ob, 1); + drawDispListsolid(lb, ob, ob_wire_col, TRUE); GPU_end_object_materials(); } else { GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL); - drawDispListsolid(lb, ob, 0); + drawDispListsolid(lb, ob, ob_wire_col, FALSE); GPU_end_object_materials(); } if (cu->editnurb && cu->bevobj == NULL && cu->taperobj == NULL && cu->ext1 == 0.0f && cu->ext2 == 0.0f) { @@ -4052,12 +4075,12 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas if (draw_glsl_material(scene, ob, v3d, dt)) { GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL); - drawDispListsolid(lb, ob, 1); + drawDispListsolid(lb, ob, ob_wire_col, TRUE); GPU_end_object_materials(); } else { GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL); - drawDispListsolid(lb, ob, 0); + drawDispListsolid(lb, ob, ob_wire_col, FALSE); GPU_end_object_materials(); } } @@ -4076,12 +4099,12 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas if (draw_glsl_material(scene, ob, v3d, dt)) { GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL); - drawDispListsolid(lb, ob, 1); + drawDispListsolid(lb, ob, ob_wire_col, TRUE); GPU_end_object_materials(); } else { GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL); - drawDispListsolid(lb, ob, 0); + drawDispListsolid(lb, ob, ob_wire_col, FALSE); GPU_end_object_materials(); } } @@ -5593,7 +5616,8 @@ static void draw_editnurb(Object *ob, Nurb *nurb, int sel) } } -static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb, int dt) +static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb, + const short dt, const unsigned char ob_wire_col[4]) { ToolSettings *ts = scene->toolsettings; Object *ob = base->object; @@ -5602,10 +5626,13 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, BevList *bl; short hide_handles = (cu->drawflag & CU_HIDE_HANDLES); int index; + unsigned char wire_col[3]; /* DispList */ - UI_ThemeColor(TH_WIRE); - drawDispList(scene, v3d, rv3d, base, dt); + UI_GetThemeColor3ubv(TH_WIRE, wire_col); + glColor3ubv(wire_col); + + drawDispList(scene, v3d, rv3d, base, dt, ob_wire_col); if (v3d->zbuf) glDisable(GL_DEPTH_TEST); @@ -5917,7 +5944,8 @@ static void drawcone(const float vec[3], float radius, float height, float tmat[ glEnd(); } /* return 1 if nothing was drawn */ -static int drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt) +static int drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, + const short dt, const unsigned char ob_wire_col[4]) { Object *ob = base->object; MetaBall *mb; @@ -5928,13 +5956,19 @@ static int drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, mb = ob->data; if (mb->editelems) { - UI_ThemeColor(TH_WIRE); - if ((G.f & G_PICKSEL) == 0) drawDispList(scene, v3d, rv3d, base, dt); + if ((G.f & G_PICKSEL) == 0) { + unsigned char wire_col[3]; + UI_GetThemeColor3ubv(TH_WIRE, wire_col); + glColor3ubv(wire_col); + + drawDispList(scene, v3d, rv3d, base, dt, wire_col); + } ml = mb->editelems->first; } else { - if ((base->flag & OB_FROMDUPLI) == 0) - drawDispList(scene, v3d, rv3d, base, dt); + if ((base->flag & OB_FROMDUPLI) == 0) { + drawDispList(scene, v3d, rv3d, base, dt, ob_wire_col); + } ml = mb->elems.first; } @@ -6306,7 +6340,8 @@ static void drawtexspace(Object *ob) } /* draws wire outline */ -static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base) +static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base, + const unsigned char ob_wire_col[4]) { RegionView3D *rv3d = ar->regiondata; Object *ob = base->object; @@ -6345,7 +6380,7 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base) } else if (ob->type == OB_ARMATURE) { if (!(ob->mode & OB_MODE_POSE && base == scene->basact)) - draw_armature(scene, v3d, ar, base, OB_WIRE, FALSE, TRUE); + draw_armature(scene, v3d, ar, base, OB_WIRE, FALSE, ob_wire_col, TRUE); } glLineWidth(1.0); @@ -6437,19 +6472,13 @@ static void draw_hooks(Object *ob) } } -static void drawRBpivot(bRigidBodyJointConstraint *data) +static void drawRBpivot(bRigidBodyJointConstraint *data, const unsigned char ob_wire_col[4]) { const char *axis_str[3] = {"px", "py", "pz"}; int axis; float mat[4][4]; /* color */ - float curcol[4]; - unsigned char tcol[4]; - - glGetFloatv(GL_CURRENT_COLOR, curcol); - rgb_float_to_uchar(tcol, curcol); - tcol[3] = 255; eul_to_mat4(mat, &data->axX); glLineWidth(4.0f); @@ -6468,14 +6497,89 @@ static void drawRBpivot(bRigidBodyJointConstraint *data) glVertex3fv(v); glEnd(); - view3d_cached_text_draw_add(v, axis_str[axis], 0, V3D_CACHE_TEXT_ASCII, tcol); + view3d_cached_text_draw_add(v, axis_str[axis], 0, V3D_CACHE_TEXT_ASCII, ob_wire_col); } glLineWidth(1.0f); setlinestyle(0); } +static void draw_object_wire_color(Scene *scene, Base *base, unsigned char r_ob_wire_col[4], + const int warning_recursive) +{ + Object *ob = base->object; + int colindex = 0; + + /* confusing logic here, there are 2 methods of setting the color + * 'colortab[colindex]' and 'theme_id', colindex overrides theme_id. + * + * note: no theme yet for 'colindex' */ + int theme_id = TH_WIRE; + int theme_shade = 0; + + if ((scene->obedit == NULL) && + (G.moving & G_TRANSFORM_OBJ) && + (base->flag & (SELECT + BA_WAS_SEL))) + { + theme_id = TH_TRANSFORM; + } + else { + /* Sets the 'colindex' */ + if (ob->id.lib) { + colindex = (base->flag & (SELECT + BA_WAS_SEL)) ? 4 : 3; + } + else if (warning_recursive == 1) { + if (base->flag & (SELECT + BA_WAS_SEL)) { + colindex = (scene->basact == base) ? 8 : 7; + } + else { + colindex = 6; + } + } + /* Sets the 'theme_id' or fallback to wire */ + else { + if (ob->flag & OB_FROMGROUP) { + if (base->flag & (SELECT + BA_WAS_SEL)) { + /* uses darker active color for non-active + selected*/ + theme_id = TH_GROUP_ACTIVE; + + if (scene->basact != base) { + theme_shade = -16; + } + } + else { + theme_id = TH_GROUP; + } + } + else { + if (base->flag & (SELECT + BA_WAS_SEL)) { + theme_id = scene->basact == base ? TH_ACTIVE : TH_SELECT; + } + else { + if (ob->type == OB_LAMP) theme_id = TH_LAMP; + else if (ob->type == OB_SPEAKER) theme_id = TH_SPEAKER; + else if (ob->type == OB_CAMERA) theme_id = TH_CAMERA; + else if (ob->type == OB_EMPTY) theme_id = TH_EMPTY; + /* fallback to TH_WIRE */ + } + } + } + } + + /* finally set the color */ + if (colindex == 0) { + if (theme_shade == 0) UI_GetThemeColor3ubv(theme_id, r_ob_wire_col); + else UI_GetThemeColorShade3ubv(theme_id, theme_shade, r_ob_wire_col); + } + else { + cpack_cpy_3ub(r_ob_wire_col, colortab[colindex]); + } + + /* no reason to use this but some functions take col[4] */ + r_ob_wire_col[3] = 255; +} + /* flag can be DRAW_PICKING and/or DRAW_CONSTCOLOR, DRAW_SCENESET */ -void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) +void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short dflag) { static int warning_recursive = 0; ModifierData *md = NULL; @@ -6484,7 +6588,8 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) RegionView3D *rv3d = ar->regiondata; float vec1[3], vec2[3]; unsigned int col = 0; - int /*sel, drawtype,*/ colindex = 0; + unsigned char _ob_wire_col[4]; /* dont initialize this */ + unsigned char *ob_wire_col = NULL; /* dont initialize this, use NULL crashes as a way to find invalid use */ int i, selstart, selend, empty_object = 0; short dt, dtx, zbufoff = 0; const short is_obact = (ob == OBACT); @@ -6508,12 +6613,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) return; /* xray delay? */ - if ((flag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) { + if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) { /* don't do xray in particle mode, need the z-buffer */ if (!(ob->mode & OB_MODE_PARTICLE_EDIT)) { /* xray and transp are set when it is drawing the 2nd/3rd pass */ if (!v3d->xray && !v3d->transp && (ob->dtx & OB_DRAWXRAY) && !(ob->dtx & OB_DRAWTRANSP)) { - add_view3d_after(&v3d->afterdraw_xray, base, flag); + ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag); return; } } @@ -6522,9 +6627,6 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* no return after this point, otherwise leaks */ view3d_cached_text_draw_begin(); - /* patch? children objects with a timeoffs change the parents. How to solve! */ - /* if ( ((int)ob->ctime) != F_(scene->r.cfra)) BKE_object_where_is_calc(scene, ob); */ - /* draw motion paths (in view space) */ if (ob->mpath && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { bAnimVizSettings *avs = &ob->avs; @@ -6544,74 +6646,14 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) ED_view3d_init_mats_rv3d_gl(ob, rv3d); /* which wire color */ - if ((flag & DRAW_CONSTCOLOR) == 0) { - /* confusing logic here, there are 2 methods of setting the color - * 'colortab[colindex]' and 'theme_id', colindex overrides theme_id. - * - * note: no theme yet for 'colindex' */ - int theme_id = TH_WIRE; - int theme_shade = 0; + if ((dflag & DRAW_CONSTCOLOR) == 0) { project_short(ar, ob->obmat[3], &base->sx); - if ((scene->obedit == NULL) && - (G.moving & G_TRANSFORM_OBJ) && - (base->flag & (SELECT + BA_WAS_SEL))) - { - theme_id = TH_TRANSFORM; - } - else { - /* Sets the 'colindex' */ - if (ob->id.lib) { - colindex = (base->flag & (SELECT + BA_WAS_SEL)) ? 4 : 3; - } - else if (warning_recursive == 1) { - if (base->flag & (SELECT + BA_WAS_SEL)) { - colindex = (scene->basact == base) ? 8 : 7; - } - else { - colindex = 6; - } - } - /* Sets the 'theme_id' or fallback to wire */ - else { - if (ob->flag & OB_FROMGROUP) { - if (base->flag & (SELECT + BA_WAS_SEL)) { - /* uses darker active color for non-active + selected*/ - theme_id = TH_GROUP_ACTIVE; - - if (scene->basact != base) { - theme_shade = -16; - } - } - else { - theme_id = TH_GROUP; - } - } - else { - if (base->flag & (SELECT + BA_WAS_SEL)) { - theme_id = scene->basact == base ? TH_ACTIVE : TH_SELECT; - } - else { - if (ob->type == OB_LAMP) theme_id = TH_LAMP; - else if (ob->type == OB_SPEAKER) theme_id = TH_SPEAKER; - else if (ob->type == OB_CAMERA) theme_id = TH_CAMERA; - else if (ob->type == OB_EMPTY) theme_id = TH_EMPTY; - /* fallback to TH_WIRE */ - } - } - } - } + draw_object_wire_color(scene, base, _ob_wire_col, warning_recursive); + ob_wire_col = _ob_wire_col; - /* finally set the color */ - if (colindex == 0) { - if (theme_shade == 0) UI_ThemeColor(theme_id); - else UI_ThemeColorShade(theme_id, theme_shade); - } - else { - col = colortab[colindex]; - cpack(col); - } + glColor3ubv(ob_wire_col); } /* maximum drawtype */ @@ -6669,18 +6711,18 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* draw outline for selected objects, mesh does itself */ if ((v3d->flag & V3D_SELECT_OUTLINE) && ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && ob->type != OB_MESH) { - if (dt > OB_WIRE && (ob->mode & OB_MODE_EDIT) == 0 && (flag & DRAW_SCENESET) == 0) { - if (!(ob->dtx & OB_DRAWWIRE) && (ob->flag & SELECT) && !(flag & DRAW_PICKING)) { + if (dt > OB_WIRE && (ob->mode & OB_MODE_EDIT) == 0 && (dflag & DRAW_SCENESET) == 0) { + if (!(ob->dtx & OB_DRAWWIRE) && (ob->flag & SELECT) && !(dflag & DRAW_PICKING)) { - drawObjectSelect(scene, v3d, ar, base); + drawObjectSelect(scene, v3d, ar, base, ob_wire_col); } } } switch (ob->type) { case OB_MESH: - empty_object = draw_mesh_object(scene, ar, v3d, rv3d, base, dt, flag); - if (flag != DRAW_CONSTCOLOR) dtx &= ~OB_DRAWWIRE; // mesh draws wire itself + empty_object = draw_mesh_object(scene, ar, v3d, rv3d, base, dt, dflag); + if (dflag != DRAW_CONSTCOLOR) dtx &= ~OB_DRAWWIRE; // mesh draws wire itself break; case OB_FONT: @@ -6691,11 +6733,11 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if (cu->flag & CU_FAST) { cpack(0xFFFFFF); set_inverted_drawing(1); - drawDispList(scene, v3d, rv3d, base, OB_WIRE); + drawDispList(scene, v3d, rv3d, base, OB_WIRE, ob_wire_col); set_inverted_drawing(0); } else { - drawDispList(scene, v3d, rv3d, base, dt); + drawDispList(scene, v3d, rv3d, base, dt, ob_wire_col); } if (cu->linewidth != 0.0f) { @@ -6770,7 +6812,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } } else if (ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb)) { - empty_object = drawDispList(scene, v3d, rv3d, base, dt); + empty_object = drawDispList(scene, v3d, rv3d, base, dt, ob_wire_col); } break; @@ -6780,7 +6822,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if (cu->editnurb) { ListBase *nurbs = BKE_curve_editNurbs_get(cu); - drawnurb(scene, v3d, rv3d, base, nurbs->first, dt); + drawnurb(scene, v3d, rv3d, base, nurbs->first, dt, ob_wire_col); } else if (dt == OB_BOUNDBOX) { if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && (v3d->drawtype >= OB_WIRE)) == 0) { @@ -6788,7 +6830,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } } else if (ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb)) { - empty_object = drawDispList(scene, v3d, rv3d, base, dt); + empty_object = drawDispList(scene, v3d, rv3d, base, dt, ob_wire_col); //XXX old animsys if (cu->path) // curve_draw_speed(scene, ob); @@ -6799,14 +6841,14 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) MetaBall *mb = ob->data; if (mb->editelems) - drawmball(scene, v3d, rv3d, base, dt); + drawmball(scene, v3d, rv3d, base, dt, ob_wire_col); else if (dt == OB_BOUNDBOX) { if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && (v3d->drawtype >= OB_WIRE)) == 0) { draw_bounding_volume(scene, ob, ob->boundtype); } } else - empty_object = drawmball(scene, v3d, rv3d, base, dt); + empty_object = drawmball(scene, v3d, rv3d, base, dt, ob_wire_col); break; } case OB_EMPTY: @@ -6821,7 +6863,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) break; case OB_LAMP: if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - drawlamp(scene, v3d, rv3d, base, dt, flag); + drawlamp(scene, v3d, rv3d, base, dt, dflag, ob_wire_col); if (dtx || (base->flag & SELECT)) glMultMatrixf(ob->obmat); } break; @@ -6829,12 +6871,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0 || (rv3d->persp == RV3D_CAMOB && v3d->camera == ob)) /* special exception for active camera */ { - drawcamera(scene, v3d, rv3d, base, flag); + drawcamera(scene, v3d, rv3d, base, dflag, ob_wire_col); break; } case OB_SPEAKER: if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) - drawspeaker(scene, v3d, rv3d, ob, flag); + drawspeaker(scene, v3d, rv3d, ob, dflag); break; case OB_LATTICE: if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { @@ -6852,7 +6894,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) else { if (dt > OB_WIRE) GPU_enable_material(0, NULL); /* we use default material */ - empty_object = draw_armature(scene, v3d, ar, base, dt, flag, FALSE); + empty_object = draw_armature(scene, v3d, ar, base, dt, dflag, ob_wire_col, FALSE); if (dt > OB_WIRE) GPU_disable_material(); } @@ -6866,7 +6908,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - if (ob->soft /*&& flag & OB_SBMOTION*/) { + if (ob->soft /*&& dflag & OB_SBMOTION*/) { float mrt[3][3], msc[3][3], mtr[3][3]; SoftBody *sb = NULL; float tipw = 0.5f, tiph = 0.5f, drawsize = 4.0f; @@ -6891,7 +6933,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* code for new particle system */ if ((warning_recursive == 0) && (ob->particlesystem.first) && - (flag & DRAW_PICKING) == 0 && + (dflag & DRAW_PICKING) == 0 && (ob != scene->obedit) ) { @@ -6925,7 +6967,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* draw edit particles last so that they can draw over child particles */ if ( (warning_recursive == 0) && - (flag & DRAW_PICKING) == 0 && + (dflag & DRAW_PICKING) == 0 && (!scene->obedit)) { @@ -7056,7 +7098,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if (con->type == CONSTRAINT_TYPE_RIGIDBODYJOINT) { bRigidBodyJointConstraint *data = (bRigidBodyJointConstraint *)con->data; if (data->flag & CONSTRAINT_DRAW_PIVOT) - drawRBpivot(data); + drawRBpivot(data, ob_wire_col); } } @@ -7083,14 +7125,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if (dtx & OB_DRAWNAME) { /* patch for several 3d cards (IBM mostly) that crash on GL_SELECT with text drawing */ /* but, we also don't draw names for sets or duplicators */ - if (flag == 0) { - float zero[3] = {0, 0, 0}; - float curcol[4]; - unsigned char tcol[4]; - glGetFloatv(GL_CURRENT_COLOR, curcol); - rgb_float_to_uchar(tcol, curcol); - tcol[3] = 255; - view3d_cached_text_draw_add(zero, ob->id.name + 2, 10, 0, tcol); + if (dflag == 0) { + const float zero[3] = {0, 0, 0}; + view3d_cached_text_draw_add(zero, ob->id.name + 2, 10, 0, ob_wire_col); } } /*if (dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);*/ @@ -7146,13 +7183,13 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) do_draw_center = DESELECT; if (do_draw_center != -1) { - if (flag & DRAW_PICKING) { + if (dflag & DRAW_PICKING) { /* draw a single point for opengl selection */ glBegin(GL_POINTS); glVertex3fv(ob->obmat[3]); glEnd(); } - else if ((flag & DRAW_CONSTCOLOR) == 0) { + else if ((dflag & DRAW_CONSTCOLOR) == 0) { /* we don't draw centers for duplicators and sets */ if (U.obcenter_dia > 0) { /* check > 0 otherwise grease pencil can draw into the circle select which is annoying. */ @@ -7163,7 +7200,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } /* not for sets, duplicators or picking */ - if (flag == 0 && (v3d->flag & V3D_HIDE_HELPLINES) == 0 && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { + if (dflag == 0 && (v3d->flag & V3D_HIDE_HELPLINES) == 0 && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { ListBase *list; /* draw hook center and offset line */ @@ -7505,7 +7542,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec /* helper function for drawing object instances - meshes */ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, - Object *ob, int dt, int outline) + Object *ob, const short dt, int outline) { Mesh *me = ob->data; DerivedMesh *dm = NULL, *edm = NULL; @@ -7553,7 +7590,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r if (dm) dm->release(dm); } -void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, int dt, int outline) +void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const short dt, int outline) { if (ob == NULL) return; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 28fd2c8bc74..a6948222d93 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -1016,7 +1016,7 @@ static void space_view3d_listener(struct ScrArea *sa, struct wmNotifier *wmn) break; } - // removed since BKE_image_user_frame_calc is now called in draw_bgpic because screen_ops doesnt call the notifier. + // removed since BKE_image_user_frame_calc is now called in view3d_draw_bgpic because screen_ops doesnt call the notifier. #if 0 if (wmn->category == NC_SCENE && wmn->data == ND_FRAME) { View3D *v3d = area->spacedata.first; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 14afcaa855f..6d9507ebff1 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -508,8 +508,7 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit) } /* set variable axis */ - vert[0][1] = vert[1][1] = - vert[2][0] = vert[3][0] = line; + vert[0][1] = vert[1][1] = vert[2][0] = vert[3][0] = line; glDrawArrays(GL_LINES, 0, 4); } @@ -1128,7 +1127,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) #ifdef VIEW3D_CAMERA_BORDER_HACK if (view3d_camera_border_hack_test == TRUE) { - glColor4fv(view3d_camera_border_hack_col); + glColor3ubv(view3d_camera_border_hack_col); glRectf(x1i + 1, y1i + 1, x2i - 1, y2i - 1); view3d_camera_border_hack_test = FALSE; } @@ -1147,7 +1146,6 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) /* border */ if (scene->r.mode & R_BORDER) { - cpack(0); x3 = x1 + scene->r.border.xmin * (x2 - x1); y3 = y1 + scene->r.border.ymin * (y2 - y1); @@ -1528,7 +1526,8 @@ exit: /* ************************************************************* */ -static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, int foreground) +static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, + const short do_forground, const short do_camera_frame) { RegionView3D *rv3d = ar->regiondata; BGpic *bgpic; @@ -1537,7 +1536,7 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, int foreground) ImBuf *ibuf = NULL, *freeibuf; float vec[4], fac, asp, zoomx, zoomy; float x1, y1, x2, y2, cx, cy; - int fg_flag = foreground ? V3D_BGPIC_FOREGROUND : 0; + int fg_flag = do_forground ? V3D_BGPIC_FOREGROUND : 0; for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) { @@ -1560,7 +1559,7 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, int foreground) BKE_image_user_frame_calc(&bgpic->iuser, CFRA, 0); ibuf = BKE_image_get_ibuf(ima, &bgpic->iuser); } - else { + else if (bgpic->source == V3D_BGPIC_MOVIE) { clip = NULL; if (bgpic->flag & V3D_BGPIC_CAMERACLIP) { @@ -1595,14 +1594,21 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, int foreground) IMB_rect_from_float(ibuf); if (rv3d->persp == RV3D_CAMOB) { - rctf vb; - ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, FALSE); - - x1 = vb.xmin; - y1 = vb.ymin; - x2 = vb.xmax; - y2 = vb.ymax; + if (do_camera_frame) { + rctf vb; + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, FALSE); + x1 = vb.xmin; + y1 = vb.ymin; + x2 = vb.xmax; + y2 = vb.ymax; + } + else { + x1 = ar->winrct.xmin; + y1 = ar->winrct.ymin; + x2 = ar->winrct.xmax; + y2 = ar->winrct.ymax; + } } else { float sco[2]; @@ -1696,7 +1702,8 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, int foreground) } } -static void draw_bgpics(Scene *scene, ARegion *ar, View3D *v3d, int foreground) +static void view3d_draw_bgpic_test(Scene *scene, ARegion *ar, View3D *v3d, + const short do_forground, const short do_camera_frame) { RegionView3D *rv3d = ar->regiondata; @@ -1708,11 +1715,11 @@ static void draw_bgpics(Scene *scene, ARegion *ar, View3D *v3d, int foreground) if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) { if (rv3d->persp == RV3D_CAMOB) { - draw_bgpic(scene, ar, v3d, foreground); + view3d_draw_bgpic(scene, ar, v3d, do_forground, do_camera_frame); } } else { - draw_bgpic(scene, ar, v3d, foreground); + view3d_draw_bgpic(scene, ar, v3d, do_forground, do_camera_frame); } } @@ -1721,17 +1728,17 @@ static void draw_bgpics(Scene *scene, ARegion *ar, View3D *v3d, int foreground) typedef struct View3DAfter { struct View3DAfter *next, *prev; struct Base *base; - int flag; + short dflag; } View3DAfter; /* temp storage of Objects that need to be drawn as last */ -void add_view3d_after(ListBase *lb, Base *base, int flag) +void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag) { View3DAfter *v3da = MEM_callocN(sizeof(View3DAfter), "View 3d after"); BLI_assert((base->flag & OB_FROMDUPLI) == 0); BLI_addtail(lb, v3da); v3da->base = base; - v3da->flag = flag; + v3da->dflag = dflag; } /* disables write in zbuffer and draws it over */ @@ -1744,7 +1751,7 @@ static void view3d_draw_transp(Scene *scene, ARegion *ar, View3D *v3d) for (v3da = v3d->afterdraw_transp.first; v3da; v3da = next) { next = v3da->next; - draw_object(scene, ar, v3d, v3da->base, v3da->flag); + draw_object(scene, ar, v3d, v3da->base, v3da->dflag); BLI_remlink(&v3d->afterdraw_transp, v3da); MEM_freeN(v3da); } @@ -1765,7 +1772,7 @@ static void view3d_draw_xray(Scene *scene, ARegion *ar, View3D *v3d, int clear) v3d->xray = TRUE; for (v3da = v3d->afterdraw_xray.first; v3da; v3da = next) { next = v3da->next; - draw_object(scene, ar, v3d, v3da->base, v3da->flag); + draw_object(scene, ar, v3d, v3da->base, v3da->dflag); BLI_remlink(&v3d->afterdraw_xray, v3da); MEM_freeN(v3da); } @@ -1786,7 +1793,7 @@ static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, int c for (v3da = v3d->afterdraw_xraytransp.first; v3da; v3da = next) { next = v3da->next; - draw_object(scene, ar, v3d, v3da->base, v3da->flag); + draw_object(scene, ar, v3d, v3da->base, v3da->dflag); BLI_remlink(&v3d->afterdraw_xraytransp, v3da); MEM_freeN(v3da); } @@ -2428,14 +2435,13 @@ static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy, float viewmat[][4], float winmat[][4], - int draw_background) + int do_bgpic) { RegionView3D *rv3d = ar->regiondata; Base *base; float backcol[3]; int bwinx, bwiny; rcti brect; - ImBuf *bg_ibuf = NULL; glPushMatrix(); @@ -2465,66 +2471,21 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype)) gpu_update_lamps_shadows(scene, v3d); - /* if scene has got active clip, use it for render backdrop */ - if (draw_background && scene->clip && rv3d->persp == RV3D_CAMOB && v3d->camera) { - MovieClipUser user = {0}; - - BKE_movieclip_user_set_frame(&user, CFRA); - bg_ibuf = BKE_movieclip_get_ibuf(scene->clip, &user); + /* set background color, fallback on the view background color + * (if active clip is set but frame is failed to load fallback to horizon color as background) */ + if (scene->world) { + if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) + linearrgb_to_srgb_v3_v3(backcol, &scene->world->horr); + else + copy_v3_v3(backcol, &scene->world->horr); + glClearColor(backcol[0], backcol[1], backcol[2], 0.0); } - - if (!bg_ibuf) { - /* set background color, fallback on the view background color - * (if active clip is set but frame is failed to load fallback to horizon color as background) */ - if (scene->world) { - if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) - linearrgb_to_srgb_v3_v3(backcol, &scene->world->horr); - else - copy_v3_v3(backcol, &scene->world->horr); - glClearColor(backcol[0], backcol[1], backcol[2], 0.0); - } - else { - UI_ThemeClearColor(TH_BACK); - } + else { + UI_ThemeClearColor(TH_BACK); } - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - if (bg_ibuf) { - unsigned char *pixels, *cp, *dst_cp; - int i; - - if (bg_ibuf->rect_float && !bg_ibuf->rect) - IMB_rect_from_float(bg_ibuf); - - dst_cp = pixels = MEM_callocN(4 * sizeof(unsigned char) * bg_ibuf->x * bg_ibuf->y, "draw offscreen clip pixels"); - cp = (unsigned char *)bg_ibuf->rect; - for (i = 0; i < bg_ibuf->x * bg_ibuf->y; i++, cp += 4, dst_cp += 4) { - dst_cp[0] = cp[0]; - dst_cp[1] = cp[1]; - dst_cp[2] = cp[2]; - dst_cp[3] = 255; - } - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - ED_region_pixelspace(ar); - - glPixelZoom((float)winx / bg_ibuf->x, (float)winy / bg_ibuf->y); - glaDrawPixelsTex(0, 0, bg_ibuf->x, bg_ibuf->y, GL_UNSIGNED_BYTE, pixels); - - glPixelZoom(1.0, 1.0); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - - IMB_freeImBuf(bg_ibuf); - MEM_freeN(pixels); - } + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* setup view matrices */ view3d_main_area_setup_view(scene, v3d, ar, viewmat, winmat); @@ -2540,6 +2501,11 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, else v3d->zbuf = FALSE; + /* important to do before clipping */ + if (do_bgpic) { + view3d_draw_bgpic_test(scene, ar, v3d, FALSE, FALSE); + } + if (rv3d->rflag & RV3D_CLIPPING) ED_view3d_clipping_set(rv3d); @@ -2581,6 +2547,11 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, if (rv3d->rflag & RV3D_CLIPPING) ED_view3d_clipping_disable(); + /* important to do after clipping */ + if (do_bgpic) { + view3d_draw_bgpic_test(scene, ar, v3d, TRUE, FALSE); + } + /* cleanup */ if (v3d->zbuf) { v3d->zbuf = FALSE; @@ -2763,12 +2734,15 @@ static void draw_viewport_fps(Scene *scene, ARegion *ar) BLF_draw_default_ascii(22, ar->winy - 17, 0.0f, printable, sizeof(printable)); } -static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar) +static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit); + +static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw_border) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); RenderEngineType *type; + GLint scissor[4]; /* create render engine */ if (!rv3d->render_engine) { @@ -2785,22 +2759,53 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar) view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL); /* background draw */ + ED_region_pixelspace(ar); + + if (draw_border) { + /* for border draw, we only need to clear a subset of the 3d view */ + rctf viewborder; + rcti cliprct; + + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, FALSE); + + cliprct.xmin = viewborder.xmin + scene->r.border.xmin * (viewborder.xmax - viewborder.xmin); + cliprct.ymin = viewborder.ymin + scene->r.border.ymin * (viewborder.ymax - viewborder.ymin); + cliprct.xmax = viewborder.xmin + scene->r.border.xmax * (viewborder.xmax - viewborder.xmin); + cliprct.ymax = viewborder.ymin + scene->r.border.ymax * (viewborder.ymax - viewborder.ymin); + + cliprct.xmin += ar->winrct.xmin; + cliprct.xmax += ar->winrct.xmin; + cliprct.ymin += ar->winrct.ymin; + cliprct.ymax += ar->winrct.ymin; + + cliprct.xmin = MAX2(cliprct.xmin, ar->winrct.xmin); + cliprct.ymin = MAX2(cliprct.ymin, ar->winrct.ymin); + cliprct.xmax = MIN2(cliprct.xmax, ar->winrct.xmax); + cliprct.ymax = MIN2(cliprct.ymax, ar->winrct.ymax); + + glGetIntegerv(GL_SCISSOR_BOX, scissor); + glScissor(cliprct.xmin, cliprct.ymin, cliprct.xmax - cliprct.xmin, cliprct.ymax - cliprct.ymin); + } + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - ED_region_pixelspace(ar); - - /* render result draw */ if (v3d->flag & V3D_DISPBGPICS) - draw_bgpic(scene, ar, v3d, FALSE); + view3d_draw_bgpic(scene, ar, v3d, FALSE, TRUE); else fdrawcheckerboard(0, 0, ar->winx, ar->winy); + if (draw_border) { + /* restore scissor as it was before */ + glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); + } + + /* render result draw */ type = rv3d->render_engine->type; type->view_draw(rv3d->render_engine, C); if (v3d->flag & V3D_DISPBGPICS) - draw_bgpic(scene, ar, v3d, TRUE); + view3d_draw_bgpic(scene, ar, v3d, TRUE, TRUE); return 1; } @@ -2896,7 +2901,7 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const } } - draw_bgpics(scene, ar, v3d, FALSE); + view3d_draw_bgpic_test(scene, ar, v3d, FALSE, TRUE); if (rv3d->rflag & RV3D_CLIPPING) ED_view3d_clipping_set(rv3d); @@ -2955,8 +2960,6 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const } } - draw_bgpics(scene, ar, v3d, TRUE); - // REEB_draw(); if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { @@ -2976,6 +2979,9 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const if (rv3d->rflag & RV3D_CLIPPING) ED_view3d_clipping_disable(); + /* important to do after clipping */ + view3d_draw_bgpic_test(scene, ar, v3d, TRUE, TRUE); + BIF_draw_manipulator(C); #if 0 @@ -3055,15 +3061,21 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha void view3d_main_area_draw(const bContext *C, ARegion *ar) { + Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d = CTX_wm_region_view3d(C); const char *grid_unit = NULL; + int draw_border = (rv3d->persp == RV3D_CAMOB && (scene->r.mode & R_BORDER)); - /* draw viewport using external renderer? */ - if (!(v3d->drawtype == OB_RENDER && view3d_main_area_draw_engine(C, ar))) { - /* draw viewport using opengl */ + /* draw viewport using opengl */ + if (v3d->drawtype != OB_RENDER || draw_border) { view3d_main_area_draw_objects(C, ar, &grid_unit); ED_region_pixelspace(ar); } + + /* draw viewport using external renderer */ + if (v3d->drawtype == OB_RENDER) + view3d_main_area_draw_engine(C, ar, draw_border); view3d_main_area_draw_info(C, ar, grid_unit); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 8ba0d75c786..d632314f3ca 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -498,7 +498,7 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event) static void viewops_data_free(bContext *C, wmOperator *op) { ARegion *ar; - Paint *p = paint_get_active(CTX_data_scene(C)); + Paint *p = paint_get_active_from_context(C); if (op->customdata) { ViewOpsData *vod = op->customdata; diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 29edc0158d6..3c6a0dd4b9f 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -53,13 +53,17 @@ struct wmWindowManager; #define BL_NEAR_CLIP 0.001 /* drawing flags: */ -#define DRAW_PICKING 1 -#define DRAW_CONSTCOLOR 2 -#define DRAW_SCENESET 4 +enum { + DRAW_PICKING = (1 << 0), + DRAW_CONSTCOLOR = (1 << 1), + DRAW_SCENESET = (1 << 2) +}; /* draw_mesh_fancy/draw_mesh_textured draw_flags */ -#define DRAW_MODIFIERS_PREVIEW 1 -#define DRAW_FACE_SELECT 2 +enum { + DRAW_MODIFIERS_PREVIEW = (1 << 0), + DRAW_FACE_SELECT = (1 << 1) +}; /* view3d_header.c */ void VIEW3D_OT_layers(struct wmOperatorType *ot); @@ -112,23 +116,28 @@ void draw_motion_paths_cleanup(View3D *v3d); /* drawobject.c */ -void draw_object(Scene *scene, struct ARegion *ar, View3D *v3d, Base *base, int flag); -int draw_glsl_material(Scene *scene, struct Object *ob, View3D *v3d, int dt); -void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob, int dt, int outline); +void draw_object(Scene *scene, struct ARegion *ar, View3D *v3d, Base *base, const short dflag); +int draw_glsl_material(Scene *scene, struct Object *ob, View3D *v3d, const short dt); +void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const short dt, int outline); void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob); void drawaxes(float size, char drawtype); void view3d_cached_text_draw_begin(void); void view3d_cached_text_draw_add(const float co[3], const char *str, short xoffs, short flag, const unsigned char col[4]); void view3d_cached_text_draw_end(View3D * v3d, ARegion * ar, int depth_write, float mat[][4]); -#define V3D_CACHE_TEXT_ZBUF (1 << 0) -#define V3D_CACHE_TEXT_WORLDSPACE (1 << 1) -#define V3D_CACHE_TEXT_ASCII (1 << 2) -#define V3D_CACHE_TEXT_GLOBALSPACE (1 << 3) -#define V3D_CACHE_TEXT_LOCALCLIP (1 << 4) + +enum { + V3D_CACHE_TEXT_ZBUF = (1 << 0), + V3D_CACHE_TEXT_WORLDSPACE = (1 << 1), + V3D_CACHE_TEXT_ASCII = (1 << 2), + V3D_CACHE_TEXT_GLOBALSPACE = (1 << 3), + V3D_CACHE_TEXT_LOCALCLIP = (1 << 4) +}; /* drawarmature.c */ -int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag, const short is_outline); +int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, + const short dt, const short dflag, const unsigned char ob_wire_col[4], + const short is_outline); /* drawmesh.c */ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, @@ -140,7 +149,7 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d, void view3d_main_area_draw(const struct bContext *C, struct ARegion *ar); void draw_depth(Scene *scene, struct ARegion *ar, View3D *v3d, int (*func)(void *)); void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d); -void add_view3d_after(ListBase *lb, Base *base, int flag); +void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag); void circf(float x, float y, float rad); void circ(float x, float y, float rad); @@ -211,7 +220,7 @@ void draw_volume(struct ARegion *ar, struct GPUTexture *tex, float min[3], float * any direction it starts to fail */ #define VIEW3D_CAMERA_BORDER_HACK #ifdef VIEW3D_CAMERA_BORDER_HACK -extern float view3d_camera_border_hack_col[4]; +extern unsigned char view3d_camera_border_hack_col[3]; extern short view3d_camera_border_hack_test; #endif diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 602f790c8df..d2f2fdcaa81 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1870,7 +1870,6 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, i for (base = vc->scene->base.first; base && hits; base = base->next) { if (BASE_SELECTABLE(vc->v3d, base)) { while (base->selcol == (*col & 0xFFFF)) { /* we got an object */ - if (*col & 0xFFFF0000) { /* we got a bone */ bone = get_indexed_bone(base->object, *col & ~(BONESEL_ANY)); if (bone) { @@ -1878,16 +1877,13 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, i if ((bone->flag & BONE_UNSELECTABLE) == 0) { bone->flag |= BONE_SELECTED; bone_selected = 1; -// XXX select_actionchannel_by_name(base->object->action, bone->name, 1); } } else { bArmature *arm = base->object->data; bone->flag &= ~BONE_SELECTED; -// XXX select_actionchannel_by_name(base->object->action, bone->name, 0); if (arm->act_bone == bone) arm->act_bone = NULL; - } } } @@ -1897,7 +1893,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, i else ED_base_object_select(base, BA_DESELECT); } - + col += 4; /* next color */ hits--; if (hits == 0) break; @@ -1906,13 +1902,16 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, i if (bone_selected) { Object *ob = base->object; - bArmature *arm = ob->data; - - WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob); - if (arm->flag & ARM_HAS_VIZ_DEPS) { - /* mask modifier ('armature' mode), etc. */ - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + if (ob && (ob->type == OB_ARMATURE)) { + bArmature *arm = ob->data; + + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob); + + if (arm && (arm->flag & ARM_HAS_VIZ_DEPS)) { + /* mask modifier ('armature' mode), etc. */ + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + } } } } diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 2a4b2f06b90..8bafce70ec4 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -49,6 +49,7 @@ #include "DNA_constraint_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_mask_types.h" #include "DNA_movieclip_types.h" #include "DNA_scene_types.h" /* PET modes */ @@ -162,13 +163,35 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) else if (t->spacetype==SPACE_CLIP) { View2D *v2d = t->view; float divx, divy; + float mulx, muly; + float aspx = 1.0f, aspy = 1.0f; divx = v2d->mask.xmax-v2d->mask.xmin; divy = v2d->mask.ymax-v2d->mask.ymin; - r_vec[0] = (v2d->cur.xmax-v2d->cur.xmin)*(dx)/divx; - r_vec[1] = (v2d->cur.ymax-v2d->cur.ymin)*(dy)/divy; + mulx = (v2d->cur.xmax-v2d->cur.xmin); + muly = (v2d->cur.ymax-v2d->cur.ymin); + + if (t->options & CTX_MASK) { + /* clamp w/h, mask only */ + divx = divy = maxf(divx, divy); + mulx = muly = minf(mulx, muly); + } + + r_vec[0] = mulx * (dx) / divx; + r_vec[1] = muly * (dy) / divy; r_vec[2] = 0.0f; + + if (t->options & CTX_MOVIECLIP) { + ED_space_clip_aspect_dimension_aware(t->sa->spacedata.first, &aspx, &aspy); + } + else if (t->options & CTX_MASK) { + /* TODO - NOT WORKING, this isnt so bad since its only display aspect */ + ED_space_clip_mask_aspect(t->sa->spacedata.first, &aspx, &aspy); + } + + r_vec[0] *= aspx; + r_vec[1] *= aspy; } else { printf("%s: called in an invalid context\n", __func__); @@ -226,9 +249,18 @@ void projectIntView(TransInfo *t, const float vec[3], int adr[2]) } else if (t->spacetype==SPACE_CLIP) { float v[2]; + float aspx = 1.0f, aspy = 1.0f; copy_v2_v2(v, vec); + if (t->options & CTX_MOVIECLIP) + ED_space_clip_aspect_dimension_aware(t->sa->spacedata.first, &aspx, &aspy); + else if (t->options & CTX_MASK) + ED_space_clip_mask_aspect(t->sa->spacedata.first, &aspx, &aspy); + + v[0] /= aspx; + v[1] /= aspy; + UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr+1); } } @@ -279,16 +311,23 @@ void applyAspectRatio(TransInfo *t, float vec[2]) vec[1] /= aspy; } else if ((t->spacetype==SPACE_CLIP) && (t->mode==TFM_TRANSLATION)) { - if (t->options & CTX_MOVIECLIP) { + if (t->options & (CTX_MOVIECLIP | CTX_MASK)) { SpaceClip *sc = t->sa->spacedata.first; float aspx, aspy; - int width, height; - ED_space_clip_size(sc, &width, &height); - ED_space_clip_aspect(sc, &aspx, &aspy); - vec[0] *= width / aspx; - vec[1] *= height / aspy; + if (t->options & CTX_MOVIECLIP) { + ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy); + + vec[0] /= aspx; + vec[1] /= aspy; + } + else if (t->options & CTX_MASK) { + ED_space_clip_mask_aspect(sc, &aspx, &aspy); + + vec[0] /= aspx; + vec[1] /= aspy; + } } } } @@ -312,16 +351,19 @@ void removeAspectRatio(TransInfo *t, float vec[2]) vec[1] *= aspy; } else if ((t->spacetype==SPACE_CLIP) && (t->mode==TFM_TRANSLATION)) { - if (t->options & CTX_MOVIECLIP) { + if (t->options & (CTX_MOVIECLIP | CTX_MASK)) { SpaceClip *sc = t->sa->spacedata.first; - float aspx, aspy; - int width, height; + float aspx = 1.0f, aspy = 1.0f; - ED_space_clip_size(sc, &width, &height); - ED_space_clip_aspect(sc, &aspx, &aspy); + if (t->options & CTX_MOVIECLIP) { + ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy); + } + else if (t->options & CTX_MASK) { + ED_space_clip_mask_aspect(sc, &aspx, &aspy); + } - vec[0] *= aspx / width; - vec[1] *= aspy / height; + vec[0] *= aspx; + vec[1] *= aspy; } } } @@ -367,12 +409,20 @@ static void viewRedrawForce(const bContext *C, TransInfo *t) } else if (t->spacetype==SPACE_CLIP) { SpaceClip *sc = (SpaceClip*)t->sa->spacedata.first; - MovieClip *clip = ED_space_clip(sc); - /* objects could be parented to tracking data, so send this for viewport refresh */ - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + if (ED_space_clip_show_trackedit(sc)) { + MovieClip *clip = ED_space_clip(sc); + + /* objects could be parented to tracking data, so send this for viewport refresh */ + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); + } + else if (ED_space_clip_show_maskedit(sc)) { + Mask *mask = ED_space_clip_mask(sc); - WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); + WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask); + } } } @@ -663,7 +713,7 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cm } else { short orientation = (t->current_orientation != V3D_MANIP_GLOBAL ? - t->current_orientation : V3D_MANIP_LOCAL); + t->current_orientation : V3D_MANIP_LOCAL); if (!(t->modifiers & MOD_CONSTRAINT_PLANE)) setUserConstraint(t, orientation, constraint_axis, msg2); else if (t->modifiers & MOD_CONSTRAINT_PLANE) @@ -725,7 +775,7 @@ int transformEvent(TransInfo *t, wmEvent *event) t->redraw |= TREDRAW_HARD; } else if (t->mode == TFM_TRANSLATION) { - if (t->options & CTX_MOVIECLIP) { + if (t->options & (CTX_MOVIECLIP | CTX_MASK)) { restoreTransObjects(t); t->flag ^= T_ALT_TRANSFORM; @@ -735,7 +785,7 @@ int transformEvent(TransInfo *t, wmEvent *event) break; case TFM_MODAL_ROTATE: /* only switch when... */ - if (!(t->options & CTX_TEXTURE) && !(t->options & CTX_MOVIECLIP)) { + if (!(t->options & CTX_TEXTURE) && !(t->options & (CTX_MOVIECLIP | CTX_MASK))) { if ( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) { resetTransRestrictions(t); @@ -762,6 +812,14 @@ int transformEvent(TransInfo *t, wmEvent *event) initSnapping(t, NULL); // need to reinit after mode change t->redraw |= TREDRAW_HARD; } + else if (t->mode == TFM_RESIZE) { + if (t->options & CTX_MOVIECLIP) { + restoreTransObjects(t); + + t->flag ^= T_ALT_TRANSFORM; + t->redraw |= TREDRAW_HARD; + } + } break; case TFM_MODAL_SNAP_INV_ON: @@ -994,7 +1052,7 @@ int transformEvent(TransInfo *t, wmEvent *event) break; case RKEY: /* only switch when... */ - if (!(t->options & CTX_TEXTURE) && !(t->options & CTX_MOVIECLIP)) { + if (!(t->options & CTX_TEXTURE)) { if ( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) { resetTransRestrictions(t); @@ -1125,10 +1183,10 @@ int transformEvent(TransInfo *t, wmEvent *event) return OPERATOR_PASS_THROUGH; } -int calculateTransformCenter(bContext *C, int centerMode, float *cent3d, int *cent2d) +int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], int cent2d[2]) { TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data"); - int success = 1; + int success; t->state = TRANS_RUNNING; @@ -1143,10 +1201,10 @@ int calculateTransformCenter(bContext *C, int centerMode, float *cent3d, int *ce t->around = centerMode; // override userdefined mode if (t->total == 0) { - success = 0; + success = FALSE; } else { - success = 1; + success = TRUE; calculateCenter(t); @@ -1456,6 +1514,8 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) { if (t->obedit) ts->proportional = proportional; + else if (t->options & CTX_MASK) + ts->proportional_mask = (proportional != PROP_EDIT_OFF); else ts->proportional_objects = (proportional != PROP_EDIT_OFF); } @@ -1665,6 +1725,9 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int case TFM_CURVE_SHRINKFATTEN: initCurveShrinkFatten(t); break; + case TFM_MASK_SHRINKFATTEN: + initMaskShrinkFatten(t); + break; case TFM_TRACKBALL: initTrackball(t); break; @@ -2675,6 +2738,9 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { copy_v3_v3(center, td->center); } + else if (t->options & CTX_MOVIECLIP) { + copy_v3_v3(center, td->center); + } else { copy_v3_v3(center, t->center); } @@ -3048,6 +3114,10 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short { center = td->center; } + + if (t->options & CTX_MOVIECLIP) { + center = td->center; + } } if (t->flag & T_POINTS) { @@ -3860,8 +3930,77 @@ int CurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) continue; if (td->val) { - // *td->val= ratio; *td->val= td->ival*ratio; + /* apply PET */ + *td->val = (*td->val * td->factor) + ((1.0f - td->factor) * td->ival); + if (*td->val <= 0.0f) *td->val = 0.001f; + } + } + + recalcData(t); + + ED_area_headerprint(t->sa, str); + + return 1; +} + + +void initMaskShrinkFatten(TransInfo *t) +{ + t->mode = TFM_MASK_SHRINKFATTEN; + t->transform = MaskShrinkFatten; + + initMouseInputMode(t, &t->mouse, INPUT_SPRING); + + t->idx_max = 0; + t->num.idx_max = 0; + t->snap[0] = 0.0f; + t->snap[1] = 0.1f; + t->snap[2] = t->snap[1] * 0.1f; + + t->num.increment = t->snap[1]; + + t->flag |= T_NO_ZERO; + t->num.flag |= NUM_NO_ZERO; + + t->flag |= T_NO_CONSTRAINT; +} + +int MaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) +{ + TransData *td = t->data; + float ratio; + int i; + char str[50]; + + ratio = t->values[0]; + + snapGrid(t, &ratio); + + applyNumInput(&t->num, &ratio); + + /* header print for NumInput */ + if (hasNumInput(&t->num)) { + char c[20]; + + outputNumInput(&(t->num), c); + sprintf(str, "Shrink/Fatten: %s", c); + } + else { + sprintf(str, "Shrink/Fatten: %3f", ratio); + } + + for (i = 0 ; i < t->total; i++, td++) { + if (td->flag & TD_NOACTION) + break; + + if (td->flag & TD_SKIP) + continue; + + if (td->val) { + *td->val = td->ival * ratio; + /* apply PET */ + *td->val = (*td->val * td->factor) + ((1.0f - td->factor) * td->ival); if (*td->val <= 0.0f) *td->val = 0.001f; } } @@ -5077,7 +5216,7 @@ void initEdgeSlide(TransInfo *t) int handleEventEdgeSlide(struct TransInfo *t, struct wmEvent *event) { - if (t->flag & TFM_EDGE_SLIDE) { + if (t->mode == TFM_EDGE_SLIDE) { SlideData *sld = t->customData; if (sld) { @@ -5119,7 +5258,7 @@ int handleEventEdgeSlide(struct TransInfo *t, struct wmEvent *event) void drawNonPropEdge(const struct bContext *C, TransInfo *t) { - if (t->flag & TFM_EDGE_SLIDE) { + if (t->mode == TFM_EDGE_SLIDE) { SlideData *sld = (SlideData *)t->customData; /* Non-Prop mode */ if (sld && sld->is_proportional == FALSE) { diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 6051fd2577b..fdc09c1bed0 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -494,6 +494,9 @@ int Tilt(TransInfo *t, const int mval[2]); void initCurveShrinkFatten(TransInfo *t); int CurveShrinkFatten(TransInfo *t, const int mval[2]); +void initMaskShrinkFatten(TransInfo *t); +int MaskShrinkFatten(TransInfo *t, const int mval[2]); + void initTrackball(TransInfo *t); int Trackball(TransInfo *t, const int mval[2]); @@ -552,7 +555,7 @@ struct wmKeyMap *transform_modal_keymap(struct wmKeyConfig *keyconf); /*********************** transform_conversions.c ********** */ struct ListBase; -void flushTransGPactionData(TransInfo *t); +void flushTransIntFrameActionData(TransInfo *t); void flushTransGraphData(TransInfo *t); void remake_graph_transdata(TransInfo *t, struct ListBase *anim_data); void flushTransUVs(TransInfo *t); @@ -561,6 +564,7 @@ int clipUVTransform(TransInfo *t, float *vec, int resize); void flushTransNodes(TransInfo *t); void flushTransSeq(TransInfo *t); void flushTransTracking(TransInfo *t); +void flushTransMasking(TransInfo *t); /*********************** exported from transform_manipulator.c ********** */ int gimbal_axis(struct Object *ob, float gmat[][3]); /* return 0 when no gimbal for selection */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index a069194d868..007ec3c5250 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -53,6 +53,7 @@ #include "DNA_meshdata_types.h" #include "DNA_gpencil_types.h" #include "DNA_movieclip_types.h" +#include "DNA_mask_types.h" #include "MEM_guardedalloc.h" @@ -87,6 +88,7 @@ #include "BKE_sequencer.h" #include "BKE_tessmesh.h" #include "BKE_tracking.h" +#include "BKE_mask.h" #include "ED_anim_api.h" @@ -102,6 +104,7 @@ #include "ED_types.h" #include "ED_uvedit.h" #include "ED_clip.h" +#include "ED_mask.h" #include "ED_util.h" /* for crazyspace correction */ #include "WM_api.h" /* for WM_event_add_notifier to deal with stabilization nodes */ @@ -1333,7 +1336,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) Object *obedit= CTX_data_edit_object(C); Curve *cu= obedit->data; TransData *td = NULL; - Nurb *nu; + Nurb *nu; BezTriple *bezt; BPoint *bp; float mtx[3][3], smtx[3][3]; @@ -1886,7 +1889,7 @@ static void get_edge_center(float cent_r[3], BMVert *eve) /* way to overwrite what data is edited with transform */ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx, - BMEditMesh *em, BMVert *eve, float *bweight) + BMEditMesh *em, BMVert *eve, float *bweight) { td->flag = 0; //if (key) @@ -2236,7 +2239,7 @@ void flushTransSeq(TransInfo *t) if ((seq->depth != 0 || seq_tx_test(seq))) /* for meta's, their children move */ seq->start= new_frame - tdsq->start_offset; #else - if (seq->type != SEQ_META && (seq->depth != 0 || seq_tx_test(seq))) /* for meta's, their children move */ + if (seq->type != SEQ_TYPE_META && (seq->depth != 0 || seq_tx_test(seq))) /* for meta's, their children move */ seq->start= new_frame - tdsq->start_offset; #endif if (seq->depth==0) { @@ -2279,7 +2282,7 @@ void flushTransSeq(TransInfo *t) /* calc all meta's then effects [#27953] */ for (seq = seqbasep->first; seq; seq = seq->next) { - if (seq->type == SEQ_META && seq->flag & SELECT) { + if (seq->type == SEQ_TYPE_META && seq->flag & SELECT) { calc_sequence(t->scene, seq); } } @@ -2794,6 +2797,99 @@ static void posttrans_gpd_clean (bGPdata *gpd) } } + +/* Called by special_aftertrans_update to make sure selected gp-frames replace + * any other gp-frames which may reside on that frame (that are not selected). + * It also makes sure sorted are still stored in chronological order after + * transform. + */ +static void posttrans_mask_clean(Mask *mask) +{ + MaskLayer *masklay; + + for (masklay = mask->masklayers.first; masklay; masklay= masklay->next) { + ListBase sel_buffer = {NULL, NULL}; + MaskLayerShape *masklay_shape, *masklay_shape_new; + MaskLayerShape *masklay_shape_sort, *masklay_shape_sort_new; + + /* loop 1: loop through and isolate selected gp-frames to buffer + * (these need to be sorted as they are isolated) + */ + for (masklay_shape= masklay->splines_shapes.first; masklay_shape; masklay_shape= masklay_shape_new) { + short added= 0; + masklay_shape_new= masklay_shape->next; + + if (masklay_shape->flag & GP_FRAME_SELECT) { + BLI_remlink(&masklay->splines_shapes, masklay_shape); + + /* find place to add them in buffer + * - go backwards as most frames will still be in order, + * so doing it this way will be faster + */ + for (masklay_shape_sort= sel_buffer.last; masklay_shape_sort; masklay_shape_sort= masklay_shape_sort->prev) { + /* if current (masklay_shape) occurs after this one in buffer, add! */ + if (masklay_shape_sort->frame < masklay_shape->frame) { + BLI_insertlinkafter(&sel_buffer, masklay_shape_sort, masklay_shape); + added= 1; + break; + } + } + if (added == 0) + BLI_addhead(&sel_buffer, masklay_shape); + } + } + + /* error checking: it is unlikely, but may be possible to have none selected */ + if (sel_buffer.first == NULL) + continue; + + /* if all were selected (i.e. masklay->splines_shapes is empty), then just transfer sel-buf over */ + if (masklay->splines_shapes.first == NULL) { + masklay->splines_shapes.first= sel_buffer.first; + masklay->splines_shapes.last= sel_buffer.last; + + continue; + } + + /* loop 2: remove duplicates of splines_shapes in buffers */ + for (masklay_shape= masklay->splines_shapes.first; masklay_shape && sel_buffer.first; masklay_shape= masklay_shape_new) { + masklay_shape_new= masklay_shape->next; + + /* loop through sel_buffer, emptying stuff from front of buffer if ok */ + for (masklay_shape_sort= sel_buffer.first; masklay_shape_sort && masklay_shape; masklay_shape_sort= masklay_shape_sort_new) { + masklay_shape_sort_new= masklay_shape_sort->next; + + /* if this buffer frame needs to go before current, add it! */ + if (masklay_shape_sort->frame < masklay_shape->frame) { + /* transfer buffer frame to splines_shapes list (before current) */ + BLI_remlink(&sel_buffer, masklay_shape_sort); + BLI_insertlinkbefore(&masklay->splines_shapes, masklay_shape, masklay_shape_sort); + } + /* if this buffer frame is on same frame, replace current with it and stop */ + else if (masklay_shape_sort->frame == masklay_shape->frame) { + /* transfer buffer frame to splines_shapes list (before current) */ + BLI_remlink(&sel_buffer, masklay_shape_sort); + BLI_insertlinkbefore(&masklay->splines_shapes, masklay_shape, masklay_shape_sort); + + /* get rid of current frame */ + BKE_mask_layer_shape_unlink(masklay, masklay_shape); + } + } + } + + /* if anything is still in buffer, append to end */ + for (masklay_shape_sort= sel_buffer.first; masklay_shape_sort; masklay_shape_sort= masklay_shape_sort_new) { + masklay_shape_sort_new= masklay_shape_sort->next; + + BLI_remlink(&sel_buffer, masklay_shape_sort); + BLI_addtail(&masklay->splines_shapes, masklay_shape_sort); + } + + /* NOTE: this is the only difference to grease pencil code above */ + BKE_mask_layer_shape_sort(masklay); + } +} + /* Called during special_aftertrans_update to make sure selected keyframes replace * any other keyframes which may reside on that frame (that is not selected). */ @@ -2933,6 +3029,27 @@ static int count_gplayer_frames(bGPDlayer *gpl, char side, float cfra) return count; } +/* fully select selected beztriples, but only include if it's on the right side of cfra */ +static int count_masklayer_frames(MaskLayer *masklay, char side, float cfra) +{ + MaskLayerShape *masklayer_shape; + int count = 0; + + if (masklay == NULL) + return count; + + /* only include points that occur on the right side of cfra */ + for (masklayer_shape= masklay->splines_shapes.first; masklayer_shape; masklayer_shape= masklayer_shape->next) { + if (masklayer_shape->flag & MASK_SHAPE_SELECT) { + if (FrameOnMouseSide(side, (float)masklayer_shape->frame, cfra)) + count++; + } + } + + return count; +} + + /* This function assigns the information to transdata */ static void TimeToTransData(TransData *td, float *time, AnimData *adt) { @@ -2995,7 +3112,7 @@ typedef struct tGPFtransdata { } tGPFtransdata; /* This function helps flush transdata written to tempdata into the gp-frames */ -void flushTransGPactionData(TransInfo *t) +void flushTransIntFrameActionData(TransInfo *t) { tGPFtransdata *tfd; int i; @@ -3046,6 +3163,35 @@ static int GPLayerToTransData (TransData *td, tGPFtransdata *tfd, bGPDlayer *gpl return count; } +/* refer to comment above #GPLayerToTransData, this is the same but for masks */ +static int MaskLayerToTransData(TransData *td, tGPFtransdata *tfd, MaskLayer *masklay, char side, float cfra) +{ + MaskLayerShape *masklay_shape; + int count= 0; + + /* check for select frames on right side of current frame */ + for (masklay_shape= masklay->splines_shapes.first; masklay_shape; masklay_shape= masklay_shape->next) { + if (masklay_shape->flag & MASK_SHAPE_SELECT) { + if (FrameOnMouseSide(side, (float)masklay_shape->frame, cfra)) { + /* memory is calloc'ed, so that should zero everything nicely for us */ + td->val= &tfd->val; + td->ival= (float)masklay_shape->frame; + + tfd->val= (float)masklay_shape->frame; + tfd->sdata= &masklay_shape->frame; + + /* advance td now */ + td++; + tfd++; + count++; + } + } + } + + return count; +} + + static void createTransActionData(bContext *C, TransInfo *t) { Scene *scene= t->scene; @@ -3066,7 +3212,7 @@ static void createTransActionData(bContext *C, TransInfo *t) return; /* filter data */ - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT); else filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/); @@ -3099,8 +3245,12 @@ static void createTransActionData(bContext *C, TransInfo *t) if (ale->type == ANIMTYPE_FCURVE) count += count_fcurve_keys(ale->key_data, t->frame_side, cfra); - else + else if (ale->type == ANIMTYPE_GPLAYER) count += count_gplayer_frames(ale->data, t->frame_side, cfra); + else if (ale->type == ANIMTYPE_MASKLAYER) + count += count_masklayer_frames(ale->data, t->frame_side, cfra); + else + BLI_assert(0); } /* stop if trying to build list if nothing selected */ @@ -3118,7 +3268,7 @@ static void createTransActionData(bContext *C, TransInfo *t) td= t->data; td2d = t->data2d; - if (ac.datatype == ANIMCONT_GPENCIL) { + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { if (t->mode == TFM_TIME_SLIDE) { t->customData= MEM_callocN((sizeof(float)*2)+(sizeof(tGPFtransdata)*count), "TimeSlide + tGPFtransdata"); tfd= (tGPFtransdata *)((float *)(t->customData) + 2); @@ -3141,6 +3291,14 @@ static void createTransActionData(bContext *C, TransInfo *t) td += i; tfd += i; } + else if (ale->type == ANIMTYPE_MASKLAYER) { + MaskLayer *masklay = (MaskLayer *)ale->data; + int i; + + i = MaskLayerToTransData(td, tfd, masklay, t->frame_side, cfra); + td += i; + tfd += i; + } else { AnimData *adt= ANIM_nla_mapping_get(&ac, ale); FCurve *fcu= (FCurve *)ale->key_data; @@ -3784,7 +3942,7 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count *count = 0; *flag = 0; } - else if (seq->type == SEQ_META) { + else if (seq->type == SEQ_TYPE_META) { /* for meta's we only ever need to extend their children, no matter what depth * just check the meta's are in the bounds */ @@ -3841,7 +3999,7 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count /* Recursive */ - if ((seq->type == SEQ_META) && ((seq->flag & (SEQ_LEFTSEL|SEQ_RIGHTSEL)) == 0)) { + if ((seq->type == SEQ_TYPE_META) && ((seq->flag & (SEQ_LEFTSEL|SEQ_RIGHTSEL)) == 0)) { /* if any handles are selected, don't recurse */ *recursive = TRUE; } @@ -3856,9 +4014,9 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count #ifdef SEQ_TX_NESTED_METAS *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL|SEQ_RIGHTSEL); *count = 1; /* ignore the selection for nested */ - *recursive = (seq->type == SEQ_META); + *recursive = (seq->type == SEQ_TYPE_META); #else - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { /* Meta's can only directly be moved between channels since they * don't have their start and length set directly (children affect that) * since this Meta is nested we don't need any of its data in fact. @@ -4061,7 +4219,7 @@ static void freeSeqData(TransInfo *t) seq= ((TransDataSeq *)td->extra)->seq; if ((seq != seq_prev)) { /* check effects strips, we cant change their time */ - if ((seq->type & SEQ_EFFECT) && seq->seq1) { + if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) { has_effect= TRUE; } else { @@ -4120,7 +4278,7 @@ static void freeSeqData(TransInfo *t) for (a=0; a<t->total; a++, td++) { seq= ((TransDataSeq *)td->extra)->seq; if ((seq != seq_prev)) { - if ((seq->type & SEQ_EFFECT) && seq->seq1) { + if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) { calc_sequence(t->scene, seq); } } @@ -4132,7 +4290,7 @@ static void freeSeqData(TransInfo *t) for (a=0; a<t->total; a++, td++) { seq= ((TransDataSeq *)td->extra)->seq; if ((seq != seq_prev)) { - if ((seq->type & SEQ_EFFECT) && seq->seq1) { + if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) { if (seq_test_overlap(seqbasep, seq)) { shuffle_seq(seqbasep, seq, t->scene); } @@ -4147,7 +4305,7 @@ static void freeSeqData(TransInfo *t) for (seq= seqbasep->first; seq; seq= seq->next) { /* We might want to build a list of effects that need to be updated during transform */ - if (seq->type & SEQ_EFFECT) { + if (seq->type & SEQ_TYPE_EFFECT) { if (seq->seq1 && seq->seq1->flag & SELECT) calc_sequence(t->scene, seq); else if (seq->seq2 && seq->seq2->flag & SELECT) calc_sequence(t->scene, seq); else if (seq->seq3 && seq->seq3->flag & SELECT) calc_sequence(t->scene, seq); @@ -4216,7 +4374,7 @@ static void createTransSeqData(bContext *C, TransInfo *t) Sequence *seq; for (seq= ed->seqbasep->first; seq; seq= seq->next) { /* hack */ - if ((seq->flag & SELECT)==0 && seq->type & SEQ_EFFECT) { + if ((seq->flag & SELECT)==0 && seq->type & SEQ_TYPE_EFFECT) { Sequence *seq_user; int i; for (i=0; i<3; i++) { @@ -4897,6 +5055,24 @@ void special_aftertrans_update(bContext *C, TransInfo *t) WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); } } + else if (t->options & CTX_MASK) { + SpaceClip *sc = t->sa->spacedata.first; + Mask *mask = ED_space_clip_mask(sc); + + if (t->scene->nodetree) { + /* tracks can be used for stabilization nodes, + * flush update for such nodes */ + nodeUpdateID(t->scene->nodetree, &mask->id); + WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); + } + + /* TODO - dont key all masks... */ + if (IS_AUTOKEY_ON(t->scene)) { + Scene *scene = t->scene; + + ED_mask_layer_shape_auto_key_select(mask, CFRA); + } + } } else if (t->spacetype == SPACE_ACTION) { SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; @@ -4983,6 +5159,26 @@ void special_aftertrans_update(bContext *C, TransInfo *t) } } } + else if (ac.datatype == ANIMCONT_MASK) { + /* remove duplicate frames and also make sure points are in order! */ + /* 3 cases here for curve cleanups: + * 1) NOTRANSKEYCULL on -> cleanup of duplicates shouldn't be done + * 2) canceled == 0 -> user confirmed the transform, so duplicates should be removed + * 3) canceled + duplicate -> user canceled the transform, but we made duplicates, so get rid of these + */ + if ((saction->flag & SACTION_NOTRANSKEYCULL)==0 && + ((canceled == 0) || (duplicate))) + { + Mask *mask; + + // XXX: BAD! this get gpencil datablocks directly from main db... + // but that's how this currently works :/ + for (mask = G.main->mask.first; mask; mask = mask->id.next) { + if (ID_REAL_USERS(mask)) + posttrans_mask_clean(mask); + } + } + } /* marker transform, not especially nice but we may want to move markers * at the same time as keyframes in the dope sheet. @@ -5006,7 +5202,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) } /* make sure all F-Curves are set correctly */ - if (ac.datatype != ANIMCONT_GPENCIL) + if (!ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) ANIM_editkeyframes_refresh(&ac); /* clear flag that was set for time-slide drawing */ @@ -5392,23 +5588,24 @@ typedef struct TransDataTracking { short coord; } TransDataTracking; -static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTracking *tdt, MovieTrackingTrack *track, - int area, float loc[2], float rel[2], const float off[2]) +static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTracking *tdt, + MovieTrackingTrack *track, MovieTrackingMarker *marker, + int area, float loc[2], float rel[2], const float off[2], float aspx, float aspy) { int anchor = area == TRACK_AREA_POINT && off; tdt->mode = transDataTracking_ModeTracks; if (anchor) { - td2d->loc[0] = rel[0]; /* hold original location */ - td2d->loc[1] = rel[1]; + td2d->loc[0] = rel[0] * aspx; /* hold original location */ + td2d->loc[1] = rel[1] * aspy; tdt->loc= loc; td2d->loc2d = loc; /* current location */ } else { - td2d->loc[0] = loc[0]; /* hold original location */ - td2d->loc[1] = loc[1]; + td2d->loc[0] = loc[0] * aspx; /* hold original location */ + td2d->loc[1] = loc[1] * aspy; td2d->loc2d = loc; /* current location */ } @@ -5422,8 +5619,8 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra if (rel) { if (!anchor) { - td2d->loc[0] += rel[0]; - td2d->loc[1] += rel[1]; + td2d->loc[0] += rel[0] * aspx; + td2d->loc[1] += rel[1] * aspy; } copy_v2_v2(tdt->srelative, rel); @@ -5434,9 +5631,12 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra td->flag = 0; td->loc = td2d->loc; - copy_v3_v3(td->center, td->loc); copy_v3_v3(td->iloc, td->loc); + //copy_v3_v3(td->center, td->loc); + td->center[0] = marker->pos[0] * aspx; + td->center[1] = marker->pos[1] * aspy; + memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; @@ -5451,26 +5651,37 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra } static void trackToTransData(SpaceClip *sc, TransData *td, TransData2D *td2d, - TransDataTracking *tdt, MovieTrackingTrack *track) + TransDataTracking *tdt, MovieTrackingTrack *track, float aspx, float aspy) { - MovieTrackingMarker *marker = BKE_tracking_ensure_marker(track, sc->user.framenr); + int framenr = ED_space_clip_clip_framenr(sc); + MovieTrackingMarker *marker = BKE_tracking_ensure_marker(track, framenr); tdt->flag = marker->flag; - marker->flag &= ~(MARKER_DISABLED|MARKER_TRACKED); + marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED); - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_POINT, track->offset, marker->pos, track->offset); + markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_POINT, + track->offset, marker->pos, track->offset, aspx, aspy); - if (track->flag & SELECT) - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_POINT, marker->pos, NULL, NULL); + if (track->flag & SELECT) { + markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_POINT, + marker->pos, NULL, NULL, aspx, aspy); + } if (track->pat_flag & SELECT) { - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, track->pat_min, marker->pos, NULL); - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, track->pat_max, marker->pos, NULL); + int a; + + for (a = 0; a < 4; a++) { + markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_PAT, + marker->pattern_corners[a], marker->pos, NULL, aspx, aspy); + } } if (track->search_flag & SELECT) { - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_SEARCH, track->search_min, marker->pos, NULL); - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_SEARCH, track->search_max, marker->pos, NULL); + markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_SEARCH, + marker->search_min, marker->pos, NULL, aspx, aspy); + + markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_SEARCH, + marker->search_max, marker->pos, NULL, aspx, aspy); } } @@ -5496,7 +5707,8 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) MovieTrackingTrack *track; MovieTrackingMarker *marker; TransDataTracking *tdt; - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); + float aspx, aspy; /* count */ t->total = 0; @@ -5512,7 +5724,7 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) t->total++; if (track->pat_flag & SELECT) - t->total+= 2; + t->total+= 4; if (track->search_flag & SELECT) t->total+= 2; @@ -5524,6 +5736,8 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) if (t->total == 0) return; + ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy); + td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransTracking TransData"); td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransTracking TransData2D"); tdt = t->customData = MEM_callocN(t->total*sizeof(TransDataTracking), "TransTracking TransDataTracking"); @@ -5536,25 +5750,23 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { marker = BKE_tracking_get_marker(track, framenr); - trackToTransData(sc, td, td2d, tdt, track); + trackToTransData(sc, td, td2d, tdt, track, aspx, aspy); /* offset */ td++; td2d++; tdt++; - if ((marker->flag & MARKER_DISABLED) == 0) { - if (track->flag & SELECT) { - td++; - td2d++; - tdt++; - } + if (track->flag & SELECT) { + td++; + td2d++; + tdt++; + } - if (track->pat_flag & SELECT) { - td += 2; - td2d += 2; - tdt +=2; - } + if (track->pat_flag & SELECT) { + td += 4; + td2d += 4; + tdt += 4; } if (track->search_flag & SELECT) { @@ -5706,9 +5918,6 @@ static void createTransTrackingData(bContext *C, TransInfo *t) if (!clip || width == 0 || height == 0) return; - if (!ELEM(t->mode, TFM_RESIZE, TFM_TRANSLATION)) - return; - if (ar->regiontype == RGN_TYPE_PREVIEW) { /* transformation was called from graph editor */ createTransTrackingCurvesData(C, t); @@ -5726,7 +5935,7 @@ static void cancelTransTracking(TransInfo *t) ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track; MovieTrackingMarker *marker; - int a, framenr = sc->user.framenr; + int a, framenr = ED_space_clip_clip_framenr(sc); if (tdt->mode == transDataTracking_ModeTracks) { track = tracksbase->first; @@ -5776,10 +5985,14 @@ static void cancelTransTracking(TransInfo *t) void flushTransTracking(TransInfo *t) { + SpaceClip *sc = t->sa->spacedata.first; TransData *td; TransData2D *td2d; TransDataTracking *tdt; int a; + float aspx, aspy; + + ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy); if (t->state == TRANS_CANCEL) cancelTransTracking(t); @@ -5787,31 +6000,46 @@ void flushTransTracking(TransInfo *t) /* flush to 2d vector from internally used 3d vector */ for (a=0, td= t->data, td2d= t->data2d, tdt= t->customData; a<t->total; a++, td2d++, td++, tdt++) { if (tdt->mode == transDataTracking_ModeTracks) { - if (t->flag & T_ALT_TRANSFORM) { - if (tdt->area == TRACK_AREA_POINT && tdt->relative) { - float d[2], d2[2]; + float loc2d[2]; - if (!tdt->smarkers) { - tdt->smarkers = MEM_callocN(sizeof(*tdt->smarkers)*tdt->markersnr, "flushTransTracking markers"); - for (a = 0; a < tdt->markersnr; a++) - copy_v2_v2(tdt->smarkers[a], tdt->markers[a].pos); - } + if (t->mode == TFM_ROTATION && tdt->area == TRACK_AREA_SEARCH) { + continue; + } - sub_v2_v2v2(d, td2d->loc, tdt->soffset); - sub_v2_v2(d, tdt->srelative); + loc2d[0] = td2d->loc[0] / aspx; + loc2d[1] = td2d->loc[1] / aspy; - sub_v2_v2v2(d2, td2d->loc, tdt->srelative); + if (t->flag & T_ALT_TRANSFORM) { + if (t->mode == TFM_RESIZE) { + if (tdt->area != TRACK_AREA_PAT) + continue; + } + else if (t->mode == TFM_TRANSLATION) { + if (tdt->area == TRACK_AREA_POINT && tdt->relative) { + float d[2], d2[2]; + + if (!tdt->smarkers) { + tdt->smarkers = MEM_callocN(sizeof(*tdt->smarkers)*tdt->markersnr, "flushTransTracking markers"); + for (a = 0; a < tdt->markersnr; a++) + copy_v2_v2(tdt->smarkers[a], tdt->markers[a].pos); + } + + sub_v2_v2v2(d, loc2d, tdt->soffset); + sub_v2_v2(d, tdt->srelative); - for (a= 0; a<tdt->markersnr; a++) - add_v2_v2v2(tdt->markers[a].pos, tdt->smarkers[a], d2); + sub_v2_v2v2(d2, loc2d, tdt->srelative); - negate_v2_v2(td2d->loc2d, d); + for (a= 0; a<tdt->markersnr; a++) + add_v2_v2v2(tdt->markers[a].pos, tdt->smarkers[a], d2); + + negate_v2_v2(td2d->loc2d, d); + } } } if (tdt->area!=TRACK_AREA_POINT || tdt->relative==0) { - td2d->loc2d[0] = td2d->loc[0]; - td2d->loc2d[1] = td2d->loc[1]; + td2d->loc2d[0] = loc2d[0]; + td2d->loc2d[1] = loc2d[1]; if (tdt->relative) sub_v2_v2(td2d->loc2d, tdt->relative); @@ -5823,6 +6051,219 @@ void flushTransTracking(TransInfo *t) } } +/* * masking * */ + +typedef struct TransDataMasking { + int is_handle; + + float handle[2], orig_handle[2]; + float vec[3][3]; + MaskSplinePoint *point; +} TransDataMasking; + +static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, + TransData *td, TransData2D *td2d, TransDataMasking *tdm, int propmode) +{ + BezTriple *bezt = &point->bezt; + float aspx, aspy; + short is_sel_point = MASKPOINT_ISSEL_KNOT(point); + short is_sel_any = MASKPOINT_ISSEL_ANY(point); + + tdm->point = point; + copy_m3_m3(tdm->vec, bezt->vec); + + ED_space_clip_mask_aspect(sc, &aspx, &aspy); + + if (propmode || is_sel_point) { + int i; + for (i = 0; i < 3; i++) { + /* CV coords are scaled by aspects. this is needed for rotations and + * proportional editing to be consistent with the stretched CV coords + * that are displayed. this also means that for display and numinput, + * and when the the CV coords are flushed, these are converted each time */ + td2d->loc[0] = bezt->vec[i][0]*aspx; + td2d->loc[1] = bezt->vec[i][1]*aspy; + td2d->loc[2] = 0.0f; + td2d->loc2d = bezt->vec[i]; + + td->flag = 0; + td->loc = td2d->loc; + copy_v3_v3(td->center, td->loc); + copy_v3_v3(td->iloc, td->loc); + + memset(td->axismtx, 0, sizeof(td->axismtx)); + td->axismtx[2][2] = 1.0f; + + td->ext = NULL; + + if (i == 1) { + /* scaling weights */ + td->val = &bezt->weight; + td->ival = *td->val; + } + else { + td->val = NULL; + } + + if (is_sel_any) { + td->flag |= TD_SELECTED; + } + td->dist= 0.0; + + unit_m3(td->mtx); + unit_m3(td->smtx); + + td++; + td2d++; + } + } + else { + tdm->is_handle = TRUE; + + BKE_mask_point_handle(point, tdm->handle); + + copy_v2_v2(tdm->orig_handle, tdm->handle); + + td2d->loc[0] = tdm->handle[0]*aspx; + td2d->loc[1] = tdm->handle[1]*aspy; + td2d->loc[2] = 0.0f; + td2d->loc2d = tdm->handle; + + td->flag = 0; + td->loc = td2d->loc; + copy_v3_v3(td->center, td->loc); + copy_v3_v3(td->iloc, td->loc); + + memset(td->axismtx, 0, sizeof(td->axismtx)); + td->axismtx[2][2] = 1.0f; + + td->ext= NULL; + td->val= NULL; + + if (is_sel_any) { + td->flag |= TD_SELECTED; + } + + td->dist= 0.0; + + unit_m3(td->mtx); + unit_m3(td->smtx); + + td++; + td2d++; + } +} + +static void createTransMaskingData(bContext *C, TransInfo *t) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + TransData *td = NULL; + TransData2D *td2d = NULL; + TransDataMasking *tdm = NULL; + int count = 0, countsel = 0; + int propmode = t->flag & T_PROP_EDIT; + + t->total = 0; + + if (!mask) + return; + + /* count */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline = masklay->splines.first; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(point)) { + if (MASKPOINT_ISSEL_KNOT(point)) + countsel += 3; + else + countsel += 1; + } + + if (propmode) + count += 3; + } + } + } + + /* note: in prop mode we need at least 1 selected */ + if (countsel == 0) return; + + t->total = (propmode) ? count: countsel; + td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransObData(Mask Editing)"); + /* for each 2d uv coord a 3d vector is allocated, so that they can be + * treated just as if they were 3d verts */ + td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransObData2D(Mask Editing)"); + tdm = t->customData = MEM_callocN(t->total*sizeof(TransDataMasking), "TransDataMasking(Mask Editing)"); + + t->flag |= T_FREE_CUSTOMDATA; + + /* create data */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline = masklay->splines.first; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (propmode || MASKPOINT_ISSEL_ANY(point)) { + MaskPointToTransData(sc, point, td, td2d, tdm, propmode); + + if (propmode || MASKPOINT_ISSEL_KNOT(point)) { + td += 3; + td2d += 3; + tdm += 3; + } + else { + td++; + td2d++; + tdm++; + } + } + } + } + } +} + +void flushTransMasking(TransInfo *t) +{ + SpaceClip *sc = t->sa->spacedata.first; + TransData2D *td; + TransDataMasking *tdm; + int a; + float aspx, aspy, invx, invy; + + ED_space_clip_mask_aspect(sc, &aspx, &aspy); + invx = 1.0f/aspx; + invy = 1.0f/aspy; + + /* flush to 2d vector from internally used 3d vector */ + for (a=0, td = t->data2d, tdm = t->customData; a<t->total; a++, td++, tdm++) { + td->loc2d[0]= td->loc[0]*invx; + td->loc2d[1]= td->loc[1]*invy; + + if (tdm->is_handle) + BKE_mask_point_set_handle(tdm->point, td->loc2d, t->flag & T_ALT_TRANSFORM, tdm->orig_handle, tdm->vec); + } +} + void createTransData(bContext *C, TransInfo *t) { Scene *scene = t->scene; @@ -5892,6 +6333,15 @@ void createTransData(bContext *C, TransInfo *t) t->flag |= T_POINTS|T_2D_EDIT; if (t->options & CTX_MOVIECLIP) createTransTrackingData(C, t); + else if (t->options & CTX_MASK) { + createTransMaskingData(C, t); + + if (t->data && (t->flag & T_PROP_EDIT)) { + sort_trans_data(t); // makes selected become first in array + set_prop_dist(t, TRUE); + sort_trans_data_dist(t); + } + } } else if (t->obedit) { t->ext = NULL; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 0f742458ed3..1b8cc14ecac 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -49,6 +49,7 @@ #include "DNA_view3d_types.h" #include "DNA_modifier_types.h" #include "DNA_movieclip_types.h" +#include "DNA_mask_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" @@ -349,9 +350,9 @@ static void recalcData_actedit(TransInfo *t) ANIM_animdata_context_getdata(&ac); /* perform flush */ - if (ac.datatype == ANIMCONT_GPENCIL) { + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { /* flush transform values back to actual coordinates */ - flushTransGPactionData(t); + flushTransIntFrameActionData(t); } else { /* get animdata blocks visible in editor, assuming that these will be the ones where things changed */ @@ -638,33 +639,49 @@ static void recalcData_spaceclip(TransInfo *t) { SpaceClip *sc = t->sa->spacedata.first; - MovieClip *clip = ED_space_clip(sc); - ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); - MovieTrackingTrack *track; + if (ED_space_clip_show_trackedit(sc)) { + MovieClip *clip = ED_space_clip(sc); + ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + MovieTrackingTrack *track; + int framenr = sc->user.framenr; - flushTransTracking(t); + flushTransTracking(t); - track = tracksbase->first; - while (track) { - if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) { - if (t->mode == TFM_TRANSLATION) { - if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) - BKE_tracking_clamp_track(track, CLAMP_PAT_POS); - if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) - BKE_tracking_clamp_track(track, CLAMP_SEARCH_POS); - } - else if (t->mode == TFM_RESIZE) { - if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) - BKE_tracking_clamp_track(track, CLAMP_PAT_DIM); - if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) - BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM); + track = tracksbase->first; + while (track) { + if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) { + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); + + if (t->mode == TFM_TRANSLATION) { + if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) + BKE_tracking_clamp_marker(marker, CLAMP_PAT_POS); + if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) + BKE_tracking_clamp_marker(marker, CLAMP_SEARCH_POS); + } + else if (t->mode == TFM_RESIZE) { + if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) + BKE_tracking_clamp_marker(marker, CLAMP_PAT_DIM); + if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) + BKE_tracking_clamp_marker(marker, CLAMP_SEARCH_DIM); + } + else if (t->mode == TFM_ROTATION) { + if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) + BKE_tracking_clamp_marker(marker, CLAMP_PAT_POS); + } } + + track = track->next; } - track = track->next; + DAG_id_tag_update(&clip->id, 0); } + else if (ED_space_clip_show_maskedit(sc)) { + Mask *mask = ED_space_clip_mask(sc); - DAG_id_tag_update(&clip->id, 0); + flushTransMasking(t); + + DAG_id_tag_update(&mask->id, 0); + } } /* helper for recalcData() - for 3d-view transforms */ @@ -1109,9 +1126,12 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) else if (t->spacetype==SPACE_CLIP) { SpaceClip *sclip = sa->spacedata.first; t->view = &ar->v2d; + t->around = sclip->around; if (ED_space_clip_show_trackedit(sclip)) t->options |= CTX_MOVIECLIP; + else if (ED_space_clip_show_maskedit(sclip)) + t->options |= CTX_MASK; } else { if (ar) { @@ -1174,6 +1194,15 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) t->flag |= T_PROP_CONNECTED; } } + else if (t->options & CTX_MASK) { + if (ts->proportional_mask) { + t->flag |= T_PROP_EDIT; + + if (ts->proportional == PROP_EDIT_CONNECTED) { + t->flag |= T_PROP_CONNECTED; + } + } + } else if (t->obedit == NULL && ts->proportional_objects) { t->flag |= T_PROP_EDIT; } diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 6fd8e07d34a..52b32ae66fc 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -51,8 +51,7 @@ #include "transform.h" -typedef struct TransformModeItem -{ +typedef struct TransformModeItem { char *idname; int mode; void (*opfunc)(wmOperatorType*); @@ -135,6 +134,7 @@ EnumPropertyItem transform_mode_types[] = {TFM_BONESIZE, "BONE_SIZE", 0, "Bonesize", ""}, {TFM_BONE_ENVELOPE, "BONE_ENVELOPE", 0, "Bone_Envelope", ""}, {TFM_CURVE_SHRINKFATTEN, "CURVE_SHRINKFATTEN", 0, "Curve_Shrinkfatten", ""}, + {TFM_MASK_SHRINKFATTEN, "MASK_SHRINKFATTEN", 0, "Mask_Shrinkfatten", ""}, {TFM_BONE_ROLL, "BONE_ROLL", 0, "Bone_Roll", ""}, {TFM_TIME_TRANSLATE, "TIME_TRANSLATE", 0, "Time_Translate", ""}, {TFM_TIME_SLIDE, "TIME_SLIDE", 0, "Time_Slide", ""}, @@ -1025,6 +1025,7 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0); WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0); break; default: break; diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 4c6ead3d3f4..75ed7d7eb19 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -1151,7 +1151,7 @@ void GPU_buffer_unbind(void) glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); } } - GLStates &= !(GPU_BUFFER_VERTEX_STATE | GPU_BUFFER_NORMAL_STATE | + GLStates &= ~(GPU_BUFFER_VERTEX_STATE | GPU_BUFFER_NORMAL_STATE | GPU_BUFFER_TEXCOORD_STATE | GPU_BUFFER_COLOR_STATE | GPU_BUFFER_ELEMENT_STATE); @@ -1191,7 +1191,7 @@ void GPU_color_switch(int mode) else { if (GLStates & GPU_BUFFER_COLOR_STATE) glDisableClientState(GL_COLOR_ARRAY); - GLStates &= (!GPU_BUFFER_COLOR_STATE); + GLStates &= ~GPU_BUFFER_COLOR_STATE; } } diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 7ae4aa550f9..3e53f2f3836 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -230,11 +230,12 @@ static struct GPUTextureState { Image *ima, *curima; int domipmap, linearmipmap; + int texpaint; /* store this so that new images created while texture painting won't be set to mipmapped */ int alphablend; float anisotropic; MTFace *lasttface; -} GTS = {0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 1, 0, -1, 1.f, NULL}; +} GTS = {0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 1, 0, 0, -1, 1.f, NULL}; /* Mipmap settings */ @@ -256,7 +257,7 @@ void GPU_set_linear_mipmap(int linear) static int gpu_get_mipmap(void) { - return GTS.domipmap; + return GTS.domipmap && !GTS.texpaint; } static GLenum gpu_get_mipmap_filter(int mag) @@ -730,6 +731,8 @@ void GPU_paint_set_mipmap(int mipmap) if (!GTS.domipmap) return; + GTS.texpaint = !mipmap; + if (mipmap) { for (ima=G.main->image.first; ima; ima=ima->id.next) { if (ima->bindcode) { diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 31008ff8685..78b5219206d 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -772,7 +772,7 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la GPU_link(mat, "mtex_value_invert", shadfac, &shadfac); GPU_link(mat, "mix_mult", shadfac, rgb, GPU_uniform(lamp->shadow_color), &rgb); GPU_link(mat, "mtex_value_invert", shadfac, &shadfac); - add_to_diffuse(mat, ma, shi, is, rgb, &shr->diff); + add_to_diffuse(mat, ma, shi, is, rgb, &shr->diff); } } diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 65c0bcb3c63..fb248f1b016 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1105,7 +1105,7 @@ void mtex_normal(vec3 texco, sampler2D ima, out vec3 normal) // It needs to be done because in Blender // the normal used points inward. // Should this ever change this negate must be removed. - vec4 color = texture2D(ima, texco.xy); + vec4 color = texture2D(ima, texco.xy); normal = 2.0*(vec3(-color.r, color.g, color.b) - vec3(-0.5, 0.5, 0.5)); } @@ -1190,7 +1190,7 @@ void mtex_bump_init_viewspace( vec3 surf_pos, vec3 surf_norm, } void mtex_bump_tap3( vec3 texco, sampler2D ima, float hScale, - out float dBs, out float dBt ) + out float dBs, out float dBt ) { vec2 STll = texco.xy; vec2 STlr = texco.xy + dFdx(texco.xy) ; @@ -1261,8 +1261,8 @@ void mtex_bump_bicubic( vec3 texco, sampler2D ima, float hScale, mat4 H; - for(int i = 0; i < 4; i++){ - for(int j = 0; j < 4; j++){ + for(int i = 0; i < 4; i++) { + for(int j = 0; j < 4; j++) { ivec2 iTexTmp = iTexLocMod + ivec2(i,j); // wrap texture coordinates manually for texelFetch to work on uvs oitside the 0,1 range. @@ -1945,22 +1945,23 @@ void shade_alpha_obcolor(vec4 col, vec4 obcol, out vec4 outcol) float fresnel_dielectric(vec3 Incoming, vec3 Normal, float eta) { - /* compute fresnel reflectance without explicitly computing - the refracted direction */ - float c = abs(dot(Incoming, Normal)); - float g = eta * eta - 1.0 + c * c; - float result; - - if(g > 0.0) { - g = sqrt(g); - float A =(g - c)/(g + c); - float B =(c *(g + c)- 1.0)/(c *(g - c)+ 1.0); - result = 0.5 * A * A *(1.0 + B * B); - } - else - result = 1.0; /* TIR (no refracted component) */ + /* compute fresnel reflectance without explicitly computing + * the refracted direction */ + float c = abs(dot(Incoming, Normal)); + float g = eta * eta - 1.0 + c * c; + float result; + + if(g > 0.0) { + g = sqrt(g); + float A =(g - c)/(g + c); + float B =(c *(g + c)- 1.0)/(c *(g - c)+ 1.0); + result = 0.5 * A * A *(1.0 + B * B); + } + else { + result = 1.0; /* TIR (no refracted component) */ + } - return result; + return result; } float hypot(float x, float y) @@ -2135,13 +2136,13 @@ void node_tex_environment_empty(vec3 co, out vec4 color) void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha) { color = texture2D(ima, co.xy); - alpha = color.a; + alpha = color.a; } void node_tex_image_empty(vec3 co, out vec4 color, out float alpha) { color = vec4(0.0); - alpha = 0.0; + alpha = 0.0; } void node_tex_magic(vec3 p, float scale, float distortion, out vec4 color, out float fac) diff --git a/source/blender/ikplugin/CMakeLists.txt b/source/blender/ikplugin/CMakeLists.txt index 87b0c6c671a..f37b254d719 100644 --- a/source/blender/ikplugin/CMakeLists.txt +++ b/source/blender/ikplugin/CMakeLists.txt @@ -57,8 +57,5 @@ if(WITH_IK_ITASC) ) endif() -if(WIN32) - add_definitions(-DEIGEN_DONT_ALIGN_STATICALLY) -endif() blender_add_lib(bf_ikplugin "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/ikplugin/SConscript b/source/blender/ikplugin/SConscript index 4cff3399fdc..38c53894df8 100644 --- a/source/blender/ikplugin/SConscript +++ b/source/blender/ikplugin/SConscript @@ -8,7 +8,4 @@ incs += ' ../blenkernel ../include ../ikplugin #/intern/itasc #/extern/Eigen3' defs.append('WITH_IK_ITASC') -if env['PLATFORM'] == 'win32': - defs.append('EIGEN_DONT_ALIGN_STATICALLY') - env.BlenderLib ( 'bf_ikplugin', sources, Split(incs), defs, libtype=['core','player'], priority=[180, 190] ) diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp index ebbb201de8e..048dd955726 100644 --- a/source/blender/ikplugin/intern/itasc_plugin.cpp +++ b/source/blender/ikplugin/intern/itasc_plugin.cpp @@ -1000,7 +1000,7 @@ static void convert_pose(IK_Scene *ikscene) // assume uniform scaling and take Y scale as general scale for the armature scale = len_v3(ikscene->blArmature->obmat[1]); - rot = (ikscene->jointArray.rows() > 0) ? &ikscene->jointArray(0) : NULL; + rot = ikscene->jointArray(0); for (joint=a=0, ikchan = ikscene->channels; a<ikscene->numchan && joint<ikscene->numjoint; ++a, ++ikchan) { pchan= ikchan->pchan; bone= pchan->bone; @@ -1041,7 +1041,7 @@ static void BKE_pose_rest(IK_Scene *ikscene) // rest pose is 0 SetToZero(ikscene->jointArray); // except for transY joints - rot = (ikscene->jointArray.rows() > 0) ? &ikscene->jointArray(0) : NULL; + rot = ikscene->jointArray(0); for (joint=a=0, ikchan = ikscene->channels; a<ikscene->numchan && joint<ikscene->numjoint; ++a, ++ikchan) { pchan= ikchan->pchan; bone= pchan->bone; @@ -1140,7 +1140,7 @@ static IK_Scene* convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan) // in Blender, the rest pose is always 0 for joints BKE_pose_rest(ikscene); } - rot = (ikscene->jointArray.rows() > 0) ? &ikscene->jointArray(0) : NULL; + rot = ikscene->jointArray(0); for (a=0, ikchan = ikscene->channels; a<tree->totchannel; ++a, ++ikchan) { pchan= ikchan->pchan; bone= pchan->bone; diff --git a/source/blender/imbuf/intern/dds/ColorBlock.cpp b/source/blender/imbuf/intern/dds/ColorBlock.cpp index 42bec5874ca..0b9f5c163fb 100644 --- a/source/blender/imbuf/intern/dds/ColorBlock.cpp +++ b/source/blender/imbuf/intern/dds/ColorBlock.cpp @@ -176,7 +176,7 @@ bool ColorBlock::isSingleColorNoAlpha() const int i; for (i = 0; i < 16; i++) { - if (m_color[i].a != 0) c = m_color[i]; + if (m_color[i].a != 0) c = m_color[i]; } Color32 mask(0xFF, 0xFF, 0xFF, 0x00); diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index 93a5f8eca7c..baea18d4898 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -904,8 +904,7 @@ static ExrHandle *imb_exr_begin_read_mem(InputFile *file, int width, int height) /* ********************************************************* */ -typedef struct RGBA -{ +typedef struct RGBA { float r; float g; float b; diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 814b1d18876..46a0f21fde0 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -206,6 +206,7 @@ typedef struct PreviewImage { #define ID_GD MAKE_ID2('G', 'D') /* GreasePencil */ #define ID_WM MAKE_ID2('W', 'M') /* WindowManager */ #define ID_MC MAKE_ID2('M', 'C') /* MovieClip */ +#define ID_MSK MAKE_ID2('M', 'S') /* Mask */ #define ID_LS MAKE_ID2('L', 'S') /* FreestyleLineStyle */ /* NOTE! Fake IDs, needed for g.sipo->blocktype or outliner */ diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index a997a655899..651b69f6aca 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -50,37 +50,37 @@ struct GHash; /* Data point for motion path (mpv) */ typedef struct bMotionPathVert { - float co[3]; /* coordinates of point in 3D-space */ - int flag; /* quick settings */ + float co[3]; /* coordinates of point in 3D-space */ + int flag; /* quick settings */ } bMotionPathVert; /* bMotionPathVert->flag */ typedef enum eMotionPathVert_Flag { - /* vert is selected */ - MOTIONPATH_VERT_SEL = (1<<0) + /* vert is selected */ + MOTIONPATH_VERT_SEL = (1 << 0) } eMotionPathVert_Flag; /* ........ */ /* Motion Path data cache (mpath) - * - for elements providing transforms (i.e. Objects or PoseChannels) + * - for elements providing transforms (i.e. Objects or PoseChannels) */ typedef struct bMotionPath { - bMotionPathVert *points; /* path samples */ - int length; /* the number of cached verts */ + bMotionPathVert *points; /* path samples */ + int length; /* the number of cached verts */ - int start_frame; /* for drawing paths, the start frame number */ - int end_frame; /* for drawing paths, the end frame number */ + int start_frame; /* for drawing paths, the start frame number */ + int end_frame; /* for drawing paths, the end frame number */ - int flag; /* baking settings - eMotionPath_Flag */ + int flag; /* baking settings - eMotionPath_Flag */ } bMotionPath; /* bMotionPath->flag */ typedef enum eMotionPath_Flag { - /* (for bones) path represents the head of the bone */ - MOTIONPATH_FLAG_BHEAD = (1<<0), - /* motion path is being edited */ - MOTIONPATH_FLAG_EDIT = (1<<1) + /* (for bones) path represents the head of the bone */ + MOTIONPATH_FLAG_BHEAD = (1 << 0), + /* motion path is being edited */ + MOTIONPATH_FLAG_EDIT = (1 << 1) } eMotionPath_Flag; /* Visualisation General --------------------------- */ @@ -89,83 +89,83 @@ typedef enum eMotionPath_Flag { /* Animation Visualisation Settings (avs) */ typedef struct bAnimVizSettings { /* Onion-Skinning Settings ----------------- */ - int ghost_sf, ghost_ef; /* start and end frames of ghost-drawing range (only used for GHOST_TYPE_RANGE) */ - int ghost_bc, ghost_ac; /* number of frames before/after current frame to show */ + int ghost_sf, ghost_ef; /* start and end frames of ghost-drawing range (only used for GHOST_TYPE_RANGE) */ + int ghost_bc, ghost_ac; /* number of frames before/after current frame to show */ - short ghost_type; /* eOnionSkin_Types */ - short ghost_step; /* number of frames between each ghost shown (not for GHOST_TYPE_KEYS) */ + short ghost_type; /* eOnionSkin_Types */ + short ghost_step; /* number of frames between each ghost shown (not for GHOST_TYPE_KEYS) */ - short ghost_flag; /* eOnionSkin_Flag */ + short ghost_flag; /* eOnionSkin_Flag */ /* General Settings ------------------------ */ - short recalc; /* eAnimViz_RecalcFlags */ + short recalc; /* eAnimViz_RecalcFlags */ /* Motion Path Settings ------------------- */ - short path_type; /* eMotionPath_Types */ - short path_step; /* number of frames between points indicated on the paths */ + short path_type; /* eMotionPath_Types */ + short path_step; /* number of frames between points indicated on the paths */ - short path_viewflag; /* eMotionPaths_ViewFlag */ - short path_bakeflag; /* eMotionPaths_BakeFlag */ + short path_viewflag; /* eMotionPaths_ViewFlag */ + short path_bakeflag; /* eMotionPaths_BakeFlag */ - int path_sf, path_ef; /* start and end frames of path-calculation range */ - int path_bc, path_ac; /* number of frames before/after current frame to show */ + int path_sf, path_ef; /* start and end frames of path-calculation range */ + int path_bc, path_ac; /* number of frames before/after current frame to show */ } bAnimVizSettings; /* bAnimVizSettings->recalc */ typedef enum eAnimViz_RecalcFlags { - /* motionpaths need recalculating */ - ANIMVIZ_RECALC_PATHS = (1<<0) + /* motionpaths need recalculating */ + ANIMVIZ_RECALC_PATHS = (1 << 0) } eAnimViz_RecalcFlags; /* bAnimVizSettings->ghost_type */ typedef enum eOnionSkin_Types { - /* no ghosts at all */ + /* no ghosts at all */ GHOST_TYPE_NONE = 0, - /* around current frame */ - GHOST_TYPE_ACFRA, - /* show ghosts within the specified frame range */ - GHOST_TYPE_RANGE, - /* show ghosts on keyframes within the specified range only */ - GHOST_TYPE_KEYS + /* around current frame */ + GHOST_TYPE_ACFRA = 1, + /* show ghosts within the specified frame range */ + GHOST_TYPE_RANGE = 2, + /* show ghosts on keyframes within the specified range only */ + GHOST_TYPE_KEYS = 3 } eOnionSkin_Types; /* bAnimVizSettings->ghost_flag */ typedef enum eOnionSkin_Flag { - /* only show selected bones in ghosts */ - GHOST_FLAG_ONLYSEL = (1<<0) + /* only show selected bones in ghosts */ + GHOST_FLAG_ONLYSEL = (1 << 0) } eOnionSkin_Flag; /* bAnimVizSettings->path_type */ typedef enum eMotionPaths_Types { - /* show the paths along their entire ranges */ + /* show the paths along their entire ranges */ MOTIONPATH_TYPE_RANGE = 0, - /* only show the parts of the paths around the current frame */ - MOTIONPATH_TYPE_ACFRA + /* only show the parts of the paths around the current frame */ + MOTIONPATH_TYPE_ACFRA = 1, } eMotionPath_Types; /* bAnimVizSettings->path_viewflag */ typedef enum eMotionPaths_ViewFlag { - /* show frames on path */ - MOTIONPATH_VIEW_FNUMS = (1<<0), - /* show keyframes on path */ - MOTIONPATH_VIEW_KFRAS = (1<<1), - /* show keyframe/frame numbers */ - MOTIONPATH_VIEW_KFNOS = (1<<2), - /* find keyframes in whole action (instead of just in matching group name) */ - MOTIONPATH_VIEW_KFACT = (1<<3) + /* show frames on path */ + MOTIONPATH_VIEW_FNUMS = (1 << 0), + /* show keyframes on path */ + MOTIONPATH_VIEW_KFRAS = (1 << 1), + /* show keyframe/frame numbers */ + MOTIONPATH_VIEW_KFNOS = (1 << 2), + /* find keyframes in whole action (instead of just in matching group name) */ + MOTIONPATH_VIEW_KFACT = (1 << 3) } eMotionPath_ViewFlag; /* bAnimVizSettings->path_bakeflag */ typedef enum eMotionPaths_BakeFlag { - /* motion paths directly associated with this block of settings needs updating */ - MOTIONPATH_BAKE_NEEDS_RECALC = (1<<0), - /* for bones - calculate head-points for curves instead of tips */ - MOTIONPATH_BAKE_HEADS = (1<<1), - /* motion paths exist for AnimVizSettings instance - set when calc for first time, and unset when clearing */ - MOTIONPATH_BAKE_HAS_PATHS = (1<<2) + /* motion paths directly associated with this block of settings needs updating */ + MOTIONPATH_BAKE_NEEDS_RECALC = (1 << 0), + /* for bones - calculate head-points for curves instead of tips */ + MOTIONPATH_BAKE_HEADS = (1 << 1), + /* motion paths exist for AnimVizSettings instance - set when calc for first time, and unset when clearing */ + MOTIONPATH_BAKE_HAS_PATHS = (1 << 2) } eMotionPath_BakeFlag; /* ************************************************ */ @@ -179,142 +179,142 @@ typedef enum eMotionPaths_BakeFlag { * with respect to the restposition of Armature bones */ typedef struct bPoseChannel { - struct bPoseChannel *next, *prev; + struct bPoseChannel *next, *prev; - IDProperty *prop; /* User-Defined Properties on this PoseChannel */ + IDProperty *prop; /* User-Defined Properties on this PoseChannel */ - ListBase constraints;/* Constraints that act on this PoseChannel */ - char name[64]; /* need to match bone name length: MAXBONENAME */ + ListBase constraints; /* Constraints that act on this PoseChannel */ + char name[64]; /* need to match bone name length: MAXBONENAME */ - short flag; /* dynamic, for detecting transform changes */ - short ikflag; /* settings for IK bones */ - short protectflag; /* protect channels from being transformed */ - short agrp_index; /* index of action-group this bone belongs to (0 = default/no group) */ - char constflag; /* for quick detecting which constraints affect this channel */ - char selectflag; /* copy of bone flag, so you can work with library armatures, not for runtime use */ - char pad0[6]; + short flag; /* dynamic, for detecting transform changes */ + short ikflag; /* settings for IK bones */ + short protectflag; /* protect channels from being transformed */ + short agrp_index; /* index of action-group this bone belongs to (0 = default/no group) */ + char constflag; /* for quick detecting which constraints affect this channel */ + char selectflag; /* copy of bone flag, so you can work with library armatures, not for runtime use */ + char pad0[6]; - struct Bone *bone; /* set on read file or rebuild pose */ - struct bPoseChannel *parent; /* set on read file or rebuild pose */ - struct bPoseChannel *child; /* set on read file or rebuild pose, the 'ik' child, for b-bones */ - - struct ListBase iktree; /* "IK trees" - only while evaluating pose */ - struct ListBase siktree; /* Spline-IK "trees" - only while evaluating pose */ - - bMotionPath *mpath; /* motion path cache for this bone */ - struct Object *custom; /* draws custom object instead of default bone shape */ - struct bPoseChannel *custom_tx; /* odd feature, display with another bones transform. + struct Bone *bone; /* set on read file or rebuild pose */ + struct bPoseChannel *parent; /* set on read file or rebuild pose */ + struct bPoseChannel *child; /* set on read file or rebuild pose, the 'ik' child, for b-bones */ + + struct ListBase iktree; /* "IK trees" - only while evaluating pose */ + struct ListBase siktree; /* Spline-IK "trees" - only while evaluating pose */ + + bMotionPath *mpath; /* motion path cache for this bone */ + struct Object *custom; /* draws custom object instead of default bone shape */ + struct bPoseChannel *custom_tx; /* odd feature, display with another bones transform. * needed in rare cases for advanced rigs, * since the alternative is highly complicated - campbell */ - /* transforms - written in by actions or transform */ - float loc[3]; - float size[3]; - - /* rotations - written in by actions or transform (but only one representation gets used at any time) */ - float eul[3]; /* euler rotation */ - float quat[4]; /* quaternion rotation */ - float rotAxis[3], rotAngle; /* axis-angle rotation */ - short rotmode; /* eRotationModes - rotation representation to use */ - short pad; + /* transforms - written in by actions or transform */ + float loc[3]; + float size[3]; + + /* rotations - written in by actions or transform (but only one representation gets used at any time) */ + float eul[3]; /* euler rotation */ + float quat[4]; /* quaternion rotation */ + float rotAxis[3], rotAngle; /* axis-angle rotation */ + short rotmode; /* eRotationModes - rotation representation to use */ + short pad; - float chan_mat[4][4]; /* matrix result of loc/quat/size , and where we put deform in, see next line */ - float pose_mat[4][4]; /* constraints accumulate here. in the end, pose_mat = bone->arm_mat * chan_mat + float chan_mat[4][4]; /* matrix result of loc/quat/size , and where we put deform in, see next line */ + float pose_mat[4][4]; /* constraints accumulate here. in the end, pose_mat = bone->arm_mat * chan_mat * this matrix is object space */ - float constinv[4][4]; /* inverse result of constraints. + float constinv[4][4]; /* inverse result of constraints. * doesn't include effect of restposition, parent, and local transform*/ - float pose_head[3]; /* actually pose_mat[3] */ - float pose_tail[3]; /* also used for drawing help lines... */ + float pose_head[3]; /* actually pose_mat[3] */ + float pose_tail[3]; /* also used for drawing help lines... */ - float limitmin[3], limitmax[3]; /* DOF constraint, note! - these are stored in degrees, not radians */ - float stiffness[3]; /* DOF stiffness */ - float ikstretch; - float ikrotweight; /* weight of joint rotation constraint */ - float iklinweight; /* weight of joint stretch constraint */ + float limitmin[3], limitmax[3]; /* DOF constraint, note! - these are stored in degrees, not radians */ + float stiffness[3]; /* DOF stiffness */ + float ikstretch; + float ikrotweight; /* weight of joint rotation constraint */ + float iklinweight; /* weight of joint stretch constraint */ - void *temp; /* use for outliner */ + void *temp; /* use for outliner */ } bPoseChannel; /* PoseChannel (transform) flags */ typedef enum ePchan_Flag { - /* has transforms */ - POSE_LOC = (1<<0), - POSE_ROT = (1<<1), - POSE_SIZE = (1<<2), - /* old IK/cache stuff... */ - POSE_IK_MAT = (1<<3), - POSE_UNUSED2 = (1<<4), - POSE_UNUSED3 = (1<<5), - POSE_UNUSED4 = (1<<6), - POSE_UNUSED5 = (1<<7), - /* has Standard IK */ - POSE_HAS_IK = (1<<8), - /* IK/Pose solving*/ - POSE_CHAIN = (1<<9), - POSE_DONE = (1<<10), - /* visualisation */ - POSE_KEY = (1<<11), - POSE_STRIDE = (1<<12), - /* standard IK solving */ - POSE_IKTREE = (1<<13), - /* has Spline IK */ - POSE_HAS_IKS = (1<<14), - /* spline IK solving */ - POSE_IKSPLINE = (1<<15) + /* has transforms */ + POSE_LOC = (1 << 0), + POSE_ROT = (1 << 1), + POSE_SIZE = (1 << 2), + /* old IK/cache stuff... */ + POSE_IK_MAT = (1 << 3), + POSE_UNUSED2 = (1 << 4), + POSE_UNUSED3 = (1 << 5), + POSE_UNUSED4 = (1 << 6), + POSE_UNUSED5 = (1 << 7), + /* has Standard IK */ + POSE_HAS_IK = (1 << 8), + /* IK/Pose solving*/ + POSE_CHAIN = (1 << 9), + POSE_DONE = (1 << 10), + /* visualisation */ + POSE_KEY = (1 << 11), + POSE_STRIDE = (1 << 12), + /* standard IK solving */ + POSE_IKTREE = (1 << 13), + /* has Spline IK */ + POSE_HAS_IKS = (1 << 14), + /* spline IK solving */ + POSE_IKSPLINE = (1 << 15) } ePchan_Flag; /* PoseChannel constflag (constraint detection) */ typedef enum ePchan_ConstFlag { - PCHAN_HAS_IK = (1<<0), - PCHAN_HAS_CONST = (1<<1), - /* only used for drawing Posemode, not stored in channel */ - PCHAN_HAS_ACTION = (1<<2), - PCHAN_HAS_TARGET = (1<<3), - /* only for drawing Posemode too */ - PCHAN_HAS_STRIDE = (1<<4), - /* spline IK */ - PCHAN_HAS_SPLINEIK = (1<<5) + PCHAN_HAS_IK = (1 << 0), + PCHAN_HAS_CONST = (1 << 1), + /* only used for drawing Posemode, not stored in channel */ + PCHAN_HAS_ACTION = (1 << 2), + PCHAN_HAS_TARGET = (1 << 3), + /* only for drawing Posemode too */ + PCHAN_HAS_STRIDE = (1 << 4), + /* spline IK */ + PCHAN_HAS_SPLINEIK = (1 << 5) } ePchan_ConstFlag; /* PoseChannel->ikflag */ typedef enum ePchan_IkFlag { - BONE_IK_NO_XDOF = (1<<0), - BONE_IK_NO_YDOF = (1<<1), - BONE_IK_NO_ZDOF = (1<<2), + BONE_IK_NO_XDOF = (1 << 0), + BONE_IK_NO_YDOF = (1 << 1), + BONE_IK_NO_ZDOF = (1 << 2), - BONE_IK_XLIMIT = (1<<3), - BONE_IK_YLIMIT = (1<<4), - BONE_IK_ZLIMIT = (1<<5), - - BONE_IK_ROTCTL = (1<<6), - BONE_IK_LINCTL = (1<<7), + BONE_IK_XLIMIT = (1 << 3), + BONE_IK_YLIMIT = (1 << 4), + BONE_IK_ZLIMIT = (1 << 5), + + BONE_IK_ROTCTL = (1 << 6), + BONE_IK_LINCTL = (1 << 7), - BONE_IK_NO_XDOF_TEMP = (1<<10), - BONE_IK_NO_YDOF_TEMP = (1<<11), - BONE_IK_NO_ZDOF_TEMP = (1<<12) + BONE_IK_NO_XDOF_TEMP = (1 << 10), + BONE_IK_NO_YDOF_TEMP = (1 << 11), + BONE_IK_NO_ZDOF_TEMP = (1 << 12) } ePchan_IkFlag; /* PoseChannel->rotmode and Object->rotmode */ typedef enum eRotationModes { - /* quaternion rotations (default, and for older Blender versions) */ - ROT_MODE_QUAT = 0, - /* euler rotations - keep in sync with enum in BLI_math.h */ - ROT_MODE_EUL = 1, /* Blender 'default' (classic) - must be as 1 to sync with BLI_math_rotation.h defines */ + /* quaternion rotations (default, and for older Blender versions) */ + ROT_MODE_QUAT = 0, + /* euler rotations - keep in sync with enum in BLI_math.h */ + ROT_MODE_EUL = 1, /* Blender 'default' (classic) - must be as 1 to sync with BLI_math_rotation.h defines */ ROT_MODE_XYZ = 1, - ROT_MODE_XZY, - ROT_MODE_YXZ, - ROT_MODE_YZX, - ROT_MODE_ZXY, - ROT_MODE_ZYX, + ROT_MODE_XZY = 2, + ROT_MODE_YXZ = 3, + ROT_MODE_YZX = 4, + ROT_MODE_ZXY = 5, + ROT_MODE_ZYX = 6, /* NOTE: space is reserved here for 18 other possible * euler rotation orders not implemented */ - /* axis angle rotations */ + /* axis angle rotations */ ROT_MODE_AXISANGLE = -1, - ROT_MODE_MIN = ROT_MODE_AXISANGLE, /* sentinel for Py API */ + ROT_MODE_MIN = ROT_MODE_AXISANGLE, /* sentinel for Py API */ ROT_MODE_MAX = ROT_MODE_ZYX } eRotationModes; @@ -326,46 +326,46 @@ typedef enum eRotationModes { * though there is a define for it (hack for the outliner). */ typedef struct bPose { - ListBase chanbase; /* list of pose channels, PoseBones in RNA */ - struct GHash *chanhash; /* ghash for quicker string lookups */ + ListBase chanbase; /* list of pose channels, PoseBones in RNA */ + struct GHash *chanhash; /* ghash for quicker string lookups */ short flag, pad; - unsigned int proxy_layer; /* proxy layer: copy from armature, gets synced */ + unsigned int proxy_layer; /* proxy layer: copy from armature, gets synced */ int pad1; - float ctime; /* local action time of this pose */ - float stride_offset[3]; /* applied to object */ - float cyclic_offset[3]; /* result of match and cycles, applied in BKE_pose_where_is() */ + float ctime; /* local action time of this pose */ + float stride_offset[3]; /* applied to object */ + float cyclic_offset[3]; /* result of match and cycles, applied in BKE_pose_where_is() */ - ListBase agroups; /* list of bActionGroups */ + ListBase agroups; /* list of bActionGroups */ - int active_group; /* index of active group (starts from 1) */ - int iksolver; /* ik solver to use, see ePose_IKSolverType */ - void *ikdata; /* temporary IK data, depends on the IK solver. Not saved in file */ - void *ikparam; /* IK solver parameters, structure depends on iksolver */ + int active_group; /* index of active group (starts from 1) */ + int iksolver; /* ik solver to use, see ePose_IKSolverType */ + void *ikdata; /* temporary IK data, depends on the IK solver. Not saved in file */ + void *ikparam; /* IK solver parameters, structure depends on iksolver */ - bAnimVizSettings avs; /* settings for visualization of bone animation */ + bAnimVizSettings avs; /* settings for visualization of bone animation */ char proxy_act_bone[64]; /* proxy active bone name, MAXBONENAME */ } bPose; /* Pose->flag */ typedef enum ePose_Flags { - /* results in BKE_pose_rebuild being called */ - POSE_RECALC = (1<<0), - /* prevents any channel from getting overridden by anim from IPO */ - POSE_LOCKED = (1<<1), - /* clears the POSE_LOCKED flag for the next time the pose is evaluated */ - POSE_DO_UNLOCK = (1<<2), - /* pose has constraints which depend on time (used when depsgraph updates for a new frame) */ - POSE_CONSTRAINTS_TIMEDEPEND = (1<<3), - /* recalculate bone paths */ - POSE_RECALCPATHS = (1<<4), - /* set by BKE_pose_rebuild to give a chance to the IK solver to rebuild IK tree */ - POSE_WAS_REBUILT = (1<<5), - /* set by game_copy_pose to indicate that this pose is used in the game engine */ - POSE_GAME_ENGINE = (1<<6) + /* results in BKE_pose_rebuild being called */ + POSE_RECALC = (1 << 0), + /* prevents any channel from getting overridden by anim from IPO */ + POSE_LOCKED = (1 << 1), + /* clears the POSE_LOCKED flag for the next time the pose is evaluated */ + POSE_DO_UNLOCK = (1 << 2), + /* pose has constraints which depend on time (used when depsgraph updates for a new frame) */ + POSE_CONSTRAINTS_TIMEDEPEND = (1 << 3), + /* recalculate bone paths */ + POSE_RECALCPATHS = (1 << 4), + /* set by BKE_pose_rebuild to give a chance to the IK solver to rebuild IK tree */ + POSE_WAS_REBUILT = (1 << 5), + /* set by game_copy_pose to indicate that this pose is used in the game engine */ + POSE_GAME_ENGINE = (1 << 6) } ePose_Flags; /* IK Solvers ------------------------------------ */ @@ -378,37 +378,37 @@ typedef enum ePose_IKSolverType { /* header for all bPose->ikparam structures */ typedef struct bIKParam { - int iksolver; + int iksolver; } bIKParam; /* bPose->ikparam when bPose->iksolver=1 */ typedef struct bItasc { - int iksolver; + int iksolver; float precision; short numiter; short numstep; float minstep; float maxstep; - short solver; + short solver; short flag; float feedback; - float maxvel; /* max velocity to SDLS solver */ - float dampmax; /* maximum damping for DLS solver */ - float dampeps; /* threshold of singular value from which the damping start progressively */ + float maxvel; /* max velocity to SDLS solver */ + float dampmax; /* maximum damping for DLS solver */ + float dampeps; /* threshold of singular value from which the damping start progressively */ } bItasc; /* bItasc->flag */ typedef enum eItasc_Flags { - ITASC_AUTO_STEP = (1<<0), - ITASC_INITIAL_REITERATION = (1<<1), - ITASC_REITERATION = (1<<2), - ITASC_SIMULATION = (1<<3) + ITASC_AUTO_STEP = (1 << 0), + ITASC_INITIAL_REITERATION = (1 << 1), + ITASC_REITERATION = (1 << 2), + ITASC_SIMULATION = (1 << 3) } eItasc_Flags; /* bItasc->solver */ typedef enum eItasc_Solver { - ITASC_SOLVER_SDLS = 0, /* selective damped least square, suitable for CopyPose constraint */ - ITASC_SOLVER_DLS /* damped least square with numerical filtering of damping */ + ITASC_SOLVER_SDLS = 0, /* selective damped least square, suitable for CopyPose constraint */ + ITASC_SOLVER_DLS = 1, /* damped least square with numerical filtering of damping */ } eItasc_Solver; /* ************************************************ */ @@ -434,34 +434,34 @@ typedef enum eItasc_Solver { typedef struct bActionGroup { struct bActionGroup *next, *prev; - ListBase channels; /* Note: this must not be touched by standard listbase functions which would clear links to other channels */ + ListBase channels; /* Note: this must not be touched by standard listbase functions which would clear links to other channels */ - int flag; /* settings for this action-group */ - int customCol; /* index of custom color set to use when used for bones (0=default - used for all old files, -1=custom set) */ - char name[64]; /* name of the group */ + int flag; /* settings for this action-group */ + int customCol; /* index of custom color set to use when used for bones (0=default - used for all old files, -1=custom set) */ + char name[64]; /* name of the group */ - ThemeWireColor cs; /* color set to use when customCol == -1 */ + ThemeWireColor cs; /* color set to use when customCol == -1 */ } bActionGroup; /* Action Group flags */ typedef enum eActionGroup_Flag { - /* group is selected */ - AGRP_SELECTED = (1<<0), - /* group is 'active' / last selected one */ - AGRP_ACTIVE = (1<<1), - /* keyframes/channels belonging to it cannot be edited */ - AGRP_PROTECTED = (1<<2), - /* for UI (DopeSheet), sub-channels are shown */ - AGRP_EXPANDED = (1<<3), - /* sub-channels are not evaluated */ - AGRP_MUTED = (1<<4), - /* sub-channels are not visible in Graph Editor */ - AGRP_NOTVISIBLE = (1<<5), - /* for UI (Graph Editor), sub-channels are shown */ - AGRP_EXPANDED_G = (1<<6), - - AGRP_TEMP = (1<<30), - AGRP_MOVED = (1<<31) + /* group is selected */ + AGRP_SELECTED = (1 << 0), + /* group is 'active' / last selected one */ + AGRP_ACTIVE = (1 << 1), + /* keyframes/channels belonging to it cannot be edited */ + AGRP_PROTECTED = (1 << 2), + /* for UI (DopeSheet), sub-channels are shown */ + AGRP_EXPANDED = (1 << 3), + /* sub-channels are not evaluated */ + AGRP_MUTED = (1 << 4), + /* sub-channels are not visible in Graph Editor */ + AGRP_NOTVISIBLE = (1 << 5), + /* for UI (Graph Editor), sub-channels are shown */ + AGRP_EXPANDED_G = (1 << 6), + + AGRP_TEMP = (1 << 30), + AGRP_MOVED = (1 << 31) } eActionGroup_Flag; @@ -478,31 +478,31 @@ typedef enum eActionGroup_Flag { * affects a group of related settings (as defined by the user). */ typedef struct bAction { - ID id; /* ID-serialisation for relinking */ + ID id; /* ID-serialisation for relinking */ - ListBase curves; /* function-curves (FCurve) */ - ListBase chanbase; /* legacy data - Action Channels (bActionChannel) in pre-2.5 animation system */ - ListBase groups; /* groups of function-curves (bActionGroup) */ - ListBase markers; /* markers local to the Action (used to provide Pose-Libraries) */ + ListBase curves; /* function-curves (FCurve) */ + ListBase chanbase; /* legacy data - Action Channels (bActionChannel) in pre-2.5 animation system */ + ListBase groups; /* groups of function-curves (bActionGroup) */ + ListBase markers; /* markers local to the Action (used to provide Pose-Libraries) */ - int flag; /* settings for this action */ - int active_marker; /* index of the active marker */ + int flag; /* settings for this action */ + int active_marker; /* index of the active marker */ - int idroot; /* type of ID-blocks that action can be assigned to (if 0, will be set to whatever ID first evaluates it) */ + int idroot; /* type of ID-blocks that action can be assigned to (if 0, will be set to whatever ID first evaluates it) */ int pad; } bAction; /* Flags for the action */ typedef enum eAction_Flags { - /* flags for displaying in UI */ - ACT_COLLAPSED = (1<<0), - ACT_SELECTED = (1<<1), - - /* flags for evaluation/editing */ - ACT_MUTED = (1<<9), - ACT_PROTECTED = (1<<10), - ACT_DISABLED = (1<<11) + /* flags for displaying in UI */ + ACT_COLLAPSED = (1 << 0), + ACT_SELECTED = (1 << 1), + + /* flags for evaluation/editing */ + ACT_MUTED = (1 << 9), + ACT_PROTECTED = (1 << 10), + ACT_DISABLED = (1 << 11) } eAction_Flags; @@ -511,68 +511,68 @@ typedef enum eAction_Flags { /* Storage for Dopesheet/Grease-Pencil Editor data */ typedef struct bDopeSheet { - ID *source; /* currently ID_SCE (for Dopesheet), and ID_SC (for Grease Pencil) */ - ListBase chanbase; /* cache for channels (only initialized when pinned) */ // XXX not used! + ID *source; /* currently ID_SCE (for Dopesheet), and ID_SC (for Grease Pencil) */ + ListBase chanbase; /* cache for channels (only initialized when pinned) */ // XXX not used! - struct Group *filter_grp; /* object group for ADS_FILTER_ONLYOBGROUP filtering option */ - char searchstr[64]; /* string to search for in displayed names of F-Curves for ADS_FILTER_BY_FCU_NAME filtering option */ + struct Group *filter_grp; /* object group for ADS_FILTER_ONLYOBGROUP filtering option */ + char searchstr[64]; /* string to search for in displayed names of F-Curves for ADS_FILTER_BY_FCU_NAME filtering option */ - int filterflag; /* flags to use for filtering data */ - int flag; /* standard flags */ + int filterflag; /* flags to use for filtering data */ + int flag; /* standard flags */ - int renameIndex; /* index+1 of channel to rename - only gets set by renaming operator */ + int renameIndex; /* index+1 of channel to rename - only gets set by renaming operator */ int pad; } bDopeSheet; /* DopeSheet filter-flag */ typedef enum eDopeSheet_FilterFlag { - /* general filtering */ - ADS_FILTER_ONLYSEL = (1<<0), /* only include channels relating to selected data */ - - /* temporary filters */ - ADS_FILTER_ONLYDRIVERS = (1<<1), /* for 'Drivers' editor - only include Driver data from AnimData */ - ADS_FILTER_ONLYNLA = (1<<2), /* for 'NLA' editor - only include NLA data from AnimData */ - ADS_FILTER_SELEDIT = (1<<3), /* for Graph Editor - used to indicate whether to include a filtering flag or not */ - - /* general filtering 2 */ - ADS_FILTER_SUMMARY = (1<<4), /* for 'DopeSheet' Editors - include 'summary' line */ - ADS_FILTER_ONLYOBGROUP = (1<<5), /* only the objects in the specified object group get used */ - - /* datatype-based filtering */ - ADS_FILTER_NOSHAPEKEYS = (1<<6), - ADS_FILTER_NOMESH = (1<<7), - ADS_FILTER_NOOBJ = (1<<8), /* for animdata on object level, if we only want to concentrate on materials/etc. */ - ADS_FILTER_NOLAT = (1<<9), - ADS_FILTER_NOCAM = (1<<10), - ADS_FILTER_NOMAT = (1<<11), - ADS_FILTER_NOLAM = (1<<12), - ADS_FILTER_NOCUR = (1<<13), - ADS_FILTER_NOWOR = (1<<14), - ADS_FILTER_NOSCE = (1<<15), - ADS_FILTER_NOPART = (1<<16), - ADS_FILTER_NOMBA = (1<<17), - ADS_FILTER_NOARM = (1<<18), - ADS_FILTER_NONTREE = (1<<19), - ADS_FILTER_NOTEX = (1<<20), - ADS_FILTER_NOSPK = (1<<21), - ADS_FILTER_NOLINESTYLE = (1<<22), - - /* NLA-specific filters */ - ADS_FILTER_NLA_NOACT = (1<<25), /* if the AnimData block has no NLA data, don't include to just show Action-line */ - - /* general filtering 3 */ - ADS_FILTER_INCL_HIDDEN = (1<<26), /* include 'hidden' channels too (i.e. those from hidden Objects/Bones) */ - ADS_FILTER_BY_FCU_NAME = (1<<27), /* for F-Curves, filter by the displayed name (i.e. to isolate all Location curves only) */ - - /* combination filters (some only used at runtime) */ - ADS_FILTER_NOOBDATA = (ADS_FILTER_NOCAM|ADS_FILTER_NOMAT|ADS_FILTER_NOLAM|ADS_FILTER_NOCUR|ADS_FILTER_NOPART|ADS_FILTER_NOARM|ADS_FILTER_NOSPK) + /* general filtering */ + ADS_FILTER_ONLYSEL = (1 << 0), /* only include channels relating to selected data */ + + /* temporary filters */ + ADS_FILTER_ONLYDRIVERS = (1 << 1), /* for 'Drivers' editor - only include Driver data from AnimData */ + ADS_FILTER_ONLYNLA = (1 << 2), /* for 'NLA' editor - only include NLA data from AnimData */ + ADS_FILTER_SELEDIT = (1 << 3), /* for Graph Editor - used to indicate whether to include a filtering flag or not */ + + /* general filtering 2 */ + ADS_FILTER_SUMMARY = (1 << 4), /* for 'DopeSheet' Editors - include 'summary' line */ + ADS_FILTER_ONLYOBGROUP = (1 << 5), /* only the objects in the specified object group get used */ + + /* datatype-based filtering */ + ADS_FILTER_NOSHAPEKEYS = (1 << 6), + ADS_FILTER_NOMESH = (1 << 7), + ADS_FILTER_NOOBJ = (1 << 8), /* for animdata on object level, if we only want to concentrate on materials/etc. */ + ADS_FILTER_NOLAT = (1 << 9), + ADS_FILTER_NOCAM = (1 << 10), + ADS_FILTER_NOMAT = (1 << 11), + ADS_FILTER_NOLAM = (1 << 12), + ADS_FILTER_NOCUR = (1 << 13), + ADS_FILTER_NOWOR = (1 << 14), + ADS_FILTER_NOSCE = (1 << 15), + ADS_FILTER_NOPART = (1 << 16), + ADS_FILTER_NOMBA = (1 << 17), + ADS_FILTER_NOARM = (1 << 18), + ADS_FILTER_NONTREE = (1 << 19), + ADS_FILTER_NOTEX = (1 << 20), + ADS_FILTER_NOSPK = (1 << 21), + ADS_FILTER_NOLINESTYLE = (1 << 22), + + /* NLA-specific filters */ + ADS_FILTER_NLA_NOACT = (1 << 25), /* if the AnimData block has no NLA data, don't include to just show Action-line */ + + /* general filtering 3 */ + ADS_FILTER_INCL_HIDDEN = (1 << 26), /* include 'hidden' channels too (i.e. those from hidden Objects/Bones) */ + ADS_FILTER_BY_FCU_NAME = (1 << 27), /* for F-Curves, filter by the displayed name (i.e. to isolate all Location curves only) */ + + /* combination filters (some only used at runtime) */ + ADS_FILTER_NOOBDATA = (ADS_FILTER_NOCAM | ADS_FILTER_NOMAT | ADS_FILTER_NOLAM | ADS_FILTER_NOCUR | ADS_FILTER_NOPART | ADS_FILTER_NOARM | ADS_FILTER_NOSPK) } eDopeSheet_FilterFlag; /* DopeSheet general flags */ typedef enum eDopeSheet_Flag { - ADS_FLAG_SUMMARY_COLLAPSED = (1<<0), /* when summary is shown, it is collapsed, so all other channels get hidden */ - ADS_FLAG_SHOW_DBFILTERS = (1<<1) /* show filters for datablocks */ + ADS_FLAG_SUMMARY_COLLAPSED = (1 << 0), /* when summary is shown, it is collapsed, so all other channels get hidden */ + ADS_FLAG_SHOW_DBFILTERS = (1 << 1) /* show filters for datablocks */ } eDopeSheet_Flag; @@ -580,72 +580,74 @@ typedef enum eDopeSheet_Flag { /* Action Editor Space. This is defined here instead of in DNA_space_types.h */ typedef struct SpaceAction { struct SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ + ListBase regionbase; /* storage of regions for inactive spaces */ int spacetype; float blockscale; short blockhandler[8]; - View2D v2d DNA_DEPRECATED; /* copied to region */ + View2D v2d DNA_DEPRECATED; /* copied to region */ - bAction *action; /* the currently active action */ - bDopeSheet ads; /* the currently active context (when not showing action) */ + bAction *action; /* the currently active action */ + bDopeSheet ads; /* the currently active context (when not showing action) */ - char mode, autosnap; /* mode: editing context; autosnap: automatic keyframe snapping mode */ - short flag; /* flag: bitmapped settings; */ - float timeslide; /* for Time-Slide transform mode drawing - current frame? */ + char mode, autosnap; /* mode: editing context; autosnap: automatic keyframe snapping mode */ + short flag; /* flag: bitmapped settings; */ + float timeslide; /* for Time-Slide transform mode drawing - current frame? */ } SpaceAction; /* SpaceAction flag */ typedef enum eSAction_Flag { - /* during transform (only set for TimeSlide) */ - SACTION_MOVING = (1<<0), - /* show sliders */ - SACTION_SLIDERS = (1<<1), - /* draw time in seconds instead of time in frames */ - SACTION_DRAWTIME = (1<<2), - /* don't filter action channels according to visibility */ + /* during transform (only set for TimeSlide) */ + SACTION_MOVING = (1 << 0), + /* show sliders */ + SACTION_SLIDERS = (1 << 1), + /* draw time in seconds instead of time in frames */ + SACTION_DRAWTIME = (1 << 2), + /* don't filter action channels according to visibility */ //SACTION_NOHIDE = (1<<3), // XXX depreceated... old animation system - /* don't kill overlapping keyframes after transform */ - SACTION_NOTRANSKEYCULL = (1<<4), - /* don't include keyframes that are out of view */ + /* don't kill overlapping keyframes after transform */ + SACTION_NOTRANSKEYCULL = (1 << 4), + /* don't include keyframes that are out of view */ //SACTION_HORIZOPTIMISEON = (1<<5), // XXX depreceated... old irrelevant trick - /* show pose-markers (local to action) in Action Editor mode */ - SACTION_POSEMARKERS_SHOW = (1<<6), - /* don't draw action channels using group colors (where applicable) */ - SACTION_NODRAWGCOLORS = (1<<7), - /* don't draw current frame number beside frame indicator */ - SACTION_NODRAWCFRANUM = (1<<8), - /* temporary flag to force channel selections to be synced with main */ - SACTION_TEMP_NEEDCHANSYNC = (1<<9), - /* don't perform realtime updates */ - SACTION_NOREALTIMEUPDATES = (1<<10), - /* move markers as well as keyframes */ - SACTION_MARKERS_MOVE = (1<<11) + /* show pose-markers (local to action) in Action Editor mode */ + SACTION_POSEMARKERS_SHOW = (1 << 6), + /* don't draw action channels using group colors (where applicable) */ + SACTION_NODRAWGCOLORS = (1 << 7), + /* don't draw current frame number beside frame indicator */ + SACTION_NODRAWCFRANUM = (1 << 8), + /* temporary flag to force channel selections to be synced with main */ + SACTION_TEMP_NEEDCHANSYNC = (1 << 9), + /* don't perform realtime updates */ + SACTION_NOREALTIMEUPDATES = (1 << 10), + /* move markers as well as keyframes */ + SACTION_MARKERS_MOVE = (1 << 11) } eSAction_Flag; /* SpaceAction Mode Settings */ typedef enum eAnimEdit_Context { - /* action on the active object */ - SACTCONT_ACTION = 0, - /* list of all shapekeys on the active object, linked with their F-Curves */ - SACTCONT_SHAPEKEY, - /* editing of gpencil data */ - SACTCONT_GPENCIL, - /* dopesheet (default) */ - SACTCONT_DOPESHEET + /* action on the active object */ + SACTCONT_ACTION = 0, + /* list of all shapekeys on the active object, linked with their F-Curves */ + SACTCONT_SHAPEKEY = 1, + /* editing of gpencil data */ + SACTCONT_GPENCIL = 2, + /* dopesheet (default) */ + SACTCONT_DOPESHEET = 3, + /* mask */ + SACTCONT_MASK = 4 } eAnimEdit_Context; /* SpaceAction AutoSnap Settings (also used by other Animation Editors) */ typedef enum eAnimEdit_AutoSnap { - /* no auto-snap */ - SACTSNAP_OFF = 0, - /* snap to 1.0 frame/second intervals */ - SACTSNAP_STEP, - /* snap to actual frames/seconds (nla-action time) */ - SACTSNAP_FRAME, - /* snap to nearest marker */ - SACTSNAP_MARKER + /* no auto-snap */ + SACTSNAP_OFF = 0, + /* snap to 1.0 frame/second intervals */ + SACTSNAP_STEP = 1, + /* snap to actual frames/seconds (nla-action time) */ + SACTSNAP_FRAME = 2, + /* snap to nearest marker */ + SACTSNAP_MARKER = 3 } eAnimEdit_AutoSnap; @@ -653,7 +655,7 @@ typedef enum eAnimEdit_AutoSnap { /* Legacy Data */ /* WARNING: Action Channels are now depreceated... they were part of the old animation system! - * (ONLY USED FOR DO_VERSIONS...) + * (ONLY USED FOR DO_VERSIONS...) * * Action Channels belong to Actions. They are linked with an IPO block, and can also own * Constraint Channels in certain situations. @@ -664,27 +666,27 @@ typedef enum eAnimEdit_AutoSnap { * to the position of the group in the list, and their position within the group. */ typedef struct bActionChannel { - struct bActionChannel *next, *prev; - bActionGroup *grp; /* Action Group this Action Channel belongs to */ + struct bActionChannel *next, *prev; + bActionGroup *grp; /* Action Group this Action Channel belongs to */ - struct Ipo *ipo; /* IPO block this action channel references */ - ListBase constraintChannels; /* Constraint Channels (when Action Channel represents an Object or Bone) */ + struct Ipo *ipo; /* IPO block this action channel references */ + ListBase constraintChannels; /* Constraint Channels (when Action Channel represents an Object or Bone) */ - int flag; /* settings accessed via bitmapping */ - char name[64]; /* channel name, MAX_NAME */ - int temp; /* temporary setting - may be used to indicate group that channel belongs to during syncing */ + int flag; /* settings accessed via bitmapping */ + char name[64]; /* channel name, MAX_NAME */ + int temp; /* temporary setting - may be used to indicate group that channel belongs to during syncing */ } bActionChannel; /* Action Channel flags (ONLY USED FOR DO_VERSIONS...) */ typedef enum ACHAN_FLAG { - ACHAN_SELECTED = (1<<0), - ACHAN_HILIGHTED = (1<<1), - ACHAN_HIDDEN = (1<<2), - ACHAN_PROTECTED = (1<<3), - ACHAN_EXPANDED = (1<<4), - ACHAN_SHOWIPO = (1<<5), - ACHAN_SHOWCONS = (1<<6), - ACHAN_MOVED = (1<<31) + ACHAN_SELECTED = (1 << 0), + ACHAN_HILIGHTED = (1 << 1), + ACHAN_HIDDEN = (1 << 2), + ACHAN_PROTECTED = (1 << 3), + ACHAN_EXPANDED = (1 << 4), + ACHAN_SHOWIPO = (1 << 5), + ACHAN_SHOWCONS = (1 << 6), + ACHAN_MOVED = (1 << 31) } ACHAN_FLAG; #endif diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h index f4e06455c63..4a5ad69cb91 100644 --- a/source/blender/makesdna/DNA_actuator_types.h +++ b/source/blender/makesdna/DNA_actuator_types.h @@ -62,8 +62,7 @@ typedef struct bActionActuator { float layer_weight; /* How much of the previous layer to use for blending. (<0 = disable, 0 = add mode) */ } bActionActuator; -typedef struct Sound3D -{ +typedef struct Sound3D { float min_gain; float max_gain; float reference_distance; diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index fd8b08e68c6..4928a88b33e 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -44,8 +44,7 @@ * variables with different names to minimize confusion. */ -typedef struct ClothSimSettings -{ +typedef struct ClothSimSettings { struct LinkNode *cache; /* UNUSED atm */ float mingoal; /* see SB */ float Cdis; /* Mechanical damping of springs. */ @@ -83,14 +82,13 @@ typedef struct ClothSimSettings short shapekey_rest; /* vertex group for scaling structural stiffness */ short presets; /* used for presets on GUI */ short reset; - short pad; + short pad; struct EffectorWeights *effector_weights; } ClothSimSettings; -typedef struct ClothCollSettings -{ +typedef struct ClothCollSettings { struct LinkNode *collision_list; /* e.g. pointer to temp memory for collisions */ float epsilon; /* min distance for collisions. */ float self_friction; /* Fiction/damping with self contact. */ @@ -101,6 +99,9 @@ typedef struct ClothCollSettings short self_loop_count; /* How many iterations for the selfcollision loop */ short loop_count; /* How many iterations for the collision loop. */ struct Group *group; /* Only use colliders from this group of objects */ + short vgroup_selfcol; /* vgroup to paint which vertices are used for self collisions */ + short pad; + int pad2; } ClothCollSettings; diff --git a/source/blender/makesdna/DNA_color_types.h b/source/blender/makesdna/DNA_color_types.h index 676389ffeea..99e2a123fe7 100644 --- a/source/blender/makesdna/DNA_color_types.h +++ b/source/blender/makesdna/DNA_color_types.h @@ -96,22 +96,36 @@ typedef enum CurveMappingPreset { } CurveMappingPreset; /* histogram->mode */ -#define HISTO_MODE_LUMA 0 -#define HISTO_MODE_RGB 1 -#define HISTO_MODE_R 2 -#define HISTO_MODE_G 3 -#define HISTO_MODE_B 4 +enum { + HISTO_MODE_LUMA = 0, + HISTO_MODE_RGB = 1, + HISTO_MODE_R = 2, + HISTO_MODE_G = 3, + HISTO_MODE_B = 4, + HISTO_MODE_ALPHA = 5 +}; + +enum { + HISTO_FLAG_LINE = (1 << 0), + HISTO_FLAG_SAMPLELINE = (1 << 1) +}; typedef struct Histogram { int channels; int x_resolution; + float data_luma[256]; float data_r[256]; float data_g[256]; float data_b[256]; - float data_luma[256]; + float data_a[256]; float xmax, ymax; - int mode; + short mode; + short flag; int height; + + /* sample line only */ + /* image coords src -> dst */ + float co[2][2]; } Histogram; struct ImBuf; diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 7a2d2929e47..59d8e81de39 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -380,7 +380,7 @@ typedef struct bRotLimitConstraint { short flag2; } bRotLimitConstraint; -/* Limit Scaling Constraint */ +/* Limit Scale Constraint */ typedef struct bSizeLimitConstraint { float xmin, xmax; float ymin, ymax; diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h index dfc70e5bd66..f6c4822bb55 100644 --- a/source/blender/makesdna/DNA_image_types.h +++ b/source/blender/makesdna/DNA_image_types.h @@ -65,6 +65,7 @@ typedef struct ImageUser { #define IMA_ANIM_ALWAYS 1 #define IMA_ANIM_REFRESHED 2 /* #define IMA_DO_PREMUL 4 */ +#define IMA_NEED_FRAME_RECALC 8 typedef struct Image { ID id; diff --git a/source/blender/makesdna/DNA_listBase.h b/source/blender/makesdna/DNA_listBase.h index 35549aee3d2..333e414278d 100644 --- a/source/blender/makesdna/DNA_listBase.h +++ b/source/blender/makesdna/DNA_listBase.h @@ -41,22 +41,19 @@ extern "C" { #endif /* generic - all structs which are used in linked-lists used this */ -typedef struct Link -{ +typedef struct Link { struct Link *next, *prev; } Link; /* use this when it is not worth defining a custom one... */ -typedef struct LinkData -{ +typedef struct LinkData { struct LinkData *next, *prev; void *data; } LinkData; /* never change the size of this! genfile.c detects pointerlen with it */ -typedef struct ListBase -{ +typedef struct ListBase { void *first, *last; } ListBase; diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h new file mode 100644 index 00000000000..20701f9adc0 --- /dev/null +++ b/source/blender/makesdna/DNA_mask_types.h @@ -0,0 +1,191 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file DNA_mask_types.h + * \ingroup DNA + * \since march-2012 + * \author Sergey Sharybin + */ + +#ifndef __DNA_MASK_TYPES_H__ +#define __DNA_MASK_TYPES_H__ + +#include "DNA_defs.h" +#include "DNA_ID.h" +#include "DNA_listBase.h" +#include "DNA_curve_types.h" + +typedef struct Mask { + ID id; + struct AnimData *adt; + ListBase masklayers; /* mask layers */ + int masklay_act; /* index of active mask layer (-1 == None) */ + int masklay_tot; /* total number of mask layers */ + + int sfra, efra; /* frames, used by the sequencer */ + + int flag; /* for anim info */ + int pad; +} Mask; + +typedef struct MaskParent { + // int flag; /* parenting flags */ /* not used */ + int pad; + int id_type; /* type of parenting */ + ID *id; /* ID block of entity to which mask/spline is parented to + * in case of parenting to movie tracking data set to MovieClip datablock */ + char parent[64]; /* entity of parent to which parenting happened + * in case of parenting to movie tracking data contains name of layer */ + char sub_parent[64]; /* sub-entity of parent to which parenting happened + * in case of parenting to movie tracking data contains name of track */ + float parent_orig[2]; /* track location at the moment of parenting */ +} MaskParent; + +typedef struct MaskSplinePointUW { + float u, w; /* u coordinate along spline segment and weight of this point */ + int flag; /* different flags of this point */ +} MaskSplinePointUW; + +typedef struct MaskSplinePoint { + BezTriple bezt; /* actual point coordinates and it's handles */ + int pad; + int tot_uw; /* number of uv feather values */ + MaskSplinePointUW *uw; /* feather UV values */ + MaskParent parent; /* parenting information of particular spline point */ +} MaskSplinePoint; + +typedef struct MaskSpline { + struct MaskSpline *next, *prev; + + int flag; /* defferent spline flag (closed, ...) */ + int tot_point; /* total number of points */ + MaskSplinePoint *points; /* points which defines spline itself */ + MaskParent parent; /* parenting information of the whole spline */ + + int weight_interp, pad; /* weight interpolation */ + + MaskSplinePoint *points_deform; /* deformed copy of 'points' BezTriple data - not saved */ +} MaskSpline; + +/* one per frame */ +typedef struct MaskLayerShape { + struct MaskLayerShape *next, *prev; + + float *data; /* u coordinate along spline segment and weight of this point */ + int tot_vert; /* to ensure no buffer overruns's: alloc size is (tot_vert * MASK_OBJECT_SHAPE_ELEM_SIZE) */ + int frame; /* different flags of this point */ + char flag; /* animation flag */ + char pad[7]; +} MaskLayerShape; + +/* cast to this for convenience, not saved */ +#define MASK_OBJECT_SHAPE_ELEM_SIZE 8 /* 3x 2D points + weight + radius == 8 */ + +# +# +typedef struct MaskLayerShapeElem { + float value[MASK_OBJECT_SHAPE_ELEM_SIZE]; +} MaskLayerShapeElem; + +typedef struct MaskLayer { + struct MaskLayer *next, *prev; + + char name[64]; /* name of the mask layer (64 = MAD_ID_NAME - 2) */ + + ListBase splines; /* list of splines which defines this mask layer */ + ListBase splines_shapes; + + struct MaskSpline *act_spline; /* active spline */ + struct MaskSplinePoint *act_point; /* active point */ + + /* blending options */ + float alpha; + char blend; + char blend_flag; + + char flag; /* for animation */ + char restrictflag; /* matching 'Object' flag of the same name - eventually use in the outliner */ +} MaskLayer; + +/* MaskParent->flag */ +/* #define MASK_PARENT_ACTIVE (1 << 0) */ /* UNUSED */ + +/* MaskSpline->flag */ +/* reserve (1 << 0) for SELECT */ +#define MASK_SPLINE_CYCLIC (1 << 1) + +/* MaskSpline->weight_interp */ +#define MASK_SPLINE_INTERP_LINEAR 1 +#define MASK_SPLINE_INTERP_EASE 2 + +/* ob->restrictflag */ +#define MASK_RESTRICT_VIEW 1 +#define MASK_RESTRICT_SELECT 2 +#define MASK_RESTRICT_RENDER 4 + +/* SpaceClip->mask_draw_flag */ +#define MASK_DRAWFLAG_SMOOTH 1 + +/* copy of eSpaceImage_UVDT */ +/* SpaceClip->mask_draw_type */ +enum { + MASK_DT_OUTLINE = 0, + MASK_DT_DASH, + MASK_DT_BLACK, + MASK_DT_WHITE +}; + +/* masklay->blend */ +enum { + MASK_BLEND_ADD = 0, + MASK_BLEND_SUBTRACT = 1 +}; + +/* masklay->blend_flag */ +enum { + MASK_BLENDFLAG_INVERT = (1 << 0) +}; + +/* masklay->flag */ +enum { + MASK_LAYERFLAG_LOCKED = (1 << 4), + MASK_LAYERFLAG_SELECT = (1 << 5) +}; + +/* masklay_shape->flag */ +enum { + MASK_SHAPE_SELECT = (1 << 0) +}; + + +/* mask->flag */ +enum { + MASK_ANIMF_EXPAND = (1 << 4) +}; + +#endif // __DNA_MASK_TYPES_H__ diff --git a/source/blender/makesdna/DNA_movieclip_types.h b/source/blender/makesdna/DNA_movieclip_types.h index f073a1957dc..b9d63167700 100644 --- a/source/blender/makesdna/DNA_movieclip_types.h +++ b/source/blender/makesdna/DNA_movieclip_types.h @@ -85,11 +85,16 @@ typedef struct MovieClip { int flag; int len; /* length of movie */ + + int start_frame, pad; } MovieClip; typedef struct MovieClipScopes { int ok; /* 1 means scopes are ok and recalculation is unneeded */ int track_preview_height; /* height of track preview widget */ + int frame_width, frame_height; /* width and height of frame for which scopes are calculated */ + struct MovieTrackingMarker undist_marker; /* undistorted position of marker used for pattern sampling */ + struct ImBuf *track_search; /* search area of a track */ struct ImBuf *track_preview; /* ImBuf displayed in track preview */ float track_pos[2]; /* sub-pizel position of marker in track ImBuf */ short track_disabled; /* active track is disabled, special notifier should be drawn */ @@ -121,6 +126,7 @@ typedef struct MovieClipScopes { /* MovieClip->flag */ #define MCLIP_USE_PROXY (1<<0) #define MCLIP_USE_PROXY_CUSTOM_DIR (1<<1) +/*#define MCLIP_CUSTOM_START_FRAME (1<<2)*/ /* UNUSED */ #define MCLIP_TIMECODE_FLAGS (MCLIP_USE_PROXY|MCLIP_USE_PROXY_CUSTOM_DIR) diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 5b87ecc44ae..5be7688d714 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -241,6 +241,14 @@ typedef struct bNodeLink { #define NTREE_QUALITY_MEDIUM 1 #define NTREE_QUALITY_LOW 2 +/* tree->chunksize */ +#define NTREE_CHUNCKSIZE_32 32 +#define NTREE_CHUNCKSIZE_64 64 +#define NTREE_CHUNCKSIZE_128 128 +#define NTREE_CHUNCKSIZE_256 256 +#define NTREE_CHUNCKSIZE_512 512 +#define NTREE_CHUNCKSIZE_1024 1024 + /* the basis for a Node tree, all links and nodes reside internal here */ /* only re-usable node trees are in the library though, materials and textures allocate own tree struct */ typedef struct bNodeTree { @@ -563,6 +571,7 @@ typedef struct NodeTexSky { typedef struct NodeTexImage { NodeTexBase base; + ImageUser iuser; int color_space, pad; } NodeTexImage; @@ -572,6 +581,7 @@ typedef struct NodeTexChecker { typedef struct NodeTexEnvironment { NodeTexBase base; + ImageUser iuser; int color_space, projection; } NodeTexEnvironment; diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 44d7ec660f2..24d33b49db2 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -301,6 +301,15 @@ typedef struct DupliObject { short type; /* from Object.transflag */ char no_draw, animated; + + /* Lowest-level particle index. + * Note: This is needed for particle info in shaders. + * Otherwise dupli groups in particle systems would override the + * index value from higher dupli levels. Would be nice to have full generic access + * to all dupli levels somehow, but for now this should cover most use-cases. + */ + int particle_index; + int pad; } DupliObject; /* **************** OBJECT ********************* */ diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index f5d525d47b5..0853df87a35 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -234,8 +234,8 @@ typedef struct ParticleSettings { struct PartDeflect *pd2; } ParticleSettings; -typedef struct ParticleSystem -{ /* note1: make sure all (runtime) are NULL's in 'copy_particlesystem' XXX, this function is no more! - need to invstigate */ +typedef struct ParticleSystem { + /* note1: make sure all (runtime) are NULL's in 'copy_particlesystem' XXX, this function is no more! - need to invstigate */ /* note2: make sure any uses of this struct in DNA are accounted for in 'BKE_object_copy_particlesystems' */ struct ParticleSystem *next, *prev; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 5cdd3fbd183..eb6742aa9f9 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1008,7 +1008,8 @@ typedef struct ToolSettings { short snap_flag, snap_target; short proportional, prop_mode; char proportional_objects; /* proportional edit, object mode */ - char pad[5]; + char proportional_mask; /* proportional edit, object mode */ + char pad[4]; char auto_normalize; /*auto normalizing mode in wpaint*/ char multipaint; /* paint multiple bones in wpaint */ diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index b4dc40a81c3..161c448476d 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -72,7 +72,7 @@ typedef struct StripColorBalance { } StripColorBalance; typedef struct StripProxy { - char dir[768]; // custom directory for index and proxy files + char dir[768]; // custom directory for index and proxy files // (defaults to BL_proxy) char file[256]; // custom file @@ -81,7 +81,7 @@ typedef struct StripProxy { short tc; // time code in use short quality; // proxy build quality - short build_size_flags;// size flags (see below) of all proxies + short build_size_flags; // size flags (see below) of all proxies // to build short build_tc_flags; // time code flags (see below) of all tc indices // to build @@ -110,28 +110,29 @@ typedef struct Sequence { void *lib; /* needed (to be like ipo), else it will raise libdata warnings, this should never be used */ char name[64]; /* SEQ_NAME_MAXSTR - name, set by default and needs to be unique, for RNA paths */ - int flag, type; /*flags bitmap (see below) and the type of sequence*/ + int flag, type; /*flags bitmap (see below) and the type of sequence*/ int len; /* the length of the contents of this strip - before handles are applied */ int start, startofs, endofs; int startstill, endstill; int machine, depth; /*machine - the strip channel, depth - the depth in the sequence when dealing with metastrips */ - int startdisp, enddisp; /*starting and ending points in the sequence*/ + int startdisp, enddisp; /*starting and ending points in the sequence*/ float sat; float mul, handsize; short anim_preseek; - short streamindex; /* streamindex for movie or sound files with several streams */ + short streamindex; /* streamindex for movie or sound files with several streams */ int multicam_source; /* for multicam source selection */ - int clip_flag; /* MOVIECLIP render flags */ + int clip_flag; /* MOVIECLIP render flags */ Strip *strip; - struct Ipo *ipo DNA_DEPRECATED; /* old animation system, deprecated for 2.5 */ + struct Ipo *ipo DNA_DEPRECATED; /* old animation system, deprecated for 2.5 */ struct Scene *scene; struct Object *scene_camera; /* override scene camera */ struct anim *anim; /* for MOVIE strips */ struct MovieClip *clip; /* for MOVIECLIP strips */ + struct Mask *mask; /* for MASK strips */ float effect_fader; float speed_fader; @@ -139,16 +140,16 @@ typedef struct Sequence { /* pointers for effects: */ struct Sequence *seq1, *seq2, *seq3; - ListBase seqbase; /* list of strips for metastrips */ + ListBase seqbase; /* list of strips for metastrips */ - struct bSound *sound; /* the linked "bSound" object */ + struct bSound *sound; /* the linked "bSound" object */ void *scene_sound; float volume; - float pitch, pan; /* pitch (-0.1..10), pan -2..2 */ + float pitch, pan; /* pitch (-0.1..10), pan -2..2 */ float strobe; - void *effectdata; /* Struct pointer for effect settings */ + void *effectdata; /* Struct pointer for effect settings */ int anim_startofs; /* only use part of animation file */ int anim_endofs; /* is subtle different to startofs / endofs */ @@ -157,8 +158,8 @@ typedef struct Sequence { int blend_mode; float blend_opacity; - /* is sfra needed anymore? - it looks like its only used in one place */ - int sfra, pad; /* starting frame according to the timeline of the scene. */ + /* is sfra needed anymore? - it looks like its only used in one place */ + int sfra, pad; /* starting frame according to the timeline of the scene. */ } Sequence; typedef struct MetaStack { @@ -169,7 +170,7 @@ typedef struct MetaStack { typedef struct Editing { ListBase *seqbasep; /* pointer to the current list of seq's being edited (can be within a meta strip) */ - ListBase seqbase; /* pointer to the top-most seq's */ + ListBase seqbase; /* pointer to the top-most seq's */ ListBase metastack; /* Context vars, used to be static */ @@ -189,12 +190,12 @@ typedef struct WipeVars { } WipeVars; typedef struct GlowVars { - float fMini; /* Minimum intensity to trigger a glow */ + float fMini; /* Minimum intensity to trigger a glow */ float fClamp; - float fBoost; /* Amount to multiply glow intensity */ - float dDist; /* Radius of glow blurring */ - int dQuality; - int bNoComp; /* SHOW/HIDE glow buffer */ + float fBoost; /* Amount to multiply glow intensity */ + float dDist; /* Radius of glow blurring */ + int dQuality; + int bNoComp; /* SHOW/HIDE glow buffer */ } GlowVars; typedef struct TransformVars { @@ -214,7 +215,7 @@ typedef struct SolidColorVars { } SolidColorVars; typedef struct SpeedControlVars { - float * frameMap; + float *frameMap; float globalSpeed; int flags; int length; @@ -226,11 +227,11 @@ typedef struct SpeedControlVars { #define SELECT 1 /* Editor->over_flag */ -#define SEQ_EDIT_OVERLAY_SHOW 1 -#define SEQ_EDIT_OVERLAY_ABS 2 +#define SEQ_EDIT_OVERLAY_SHOW 1 +#define SEQ_EDIT_OVERLAY_ABS 2 -#define SEQ_STRIP_OFSBOTTOM 0.2f -#define SEQ_STRIP_OFSTOP 0.8f +#define SEQ_STRIP_OFSBOTTOM 0.2f +#define SEQ_STRIP_OFSTOP 0.8f /* SpeedControlVars->flags */ #define SEQ_SPEED_INTEGRATE 1 @@ -238,42 +239,42 @@ typedef struct SpeedControlVars { #define SEQ_SPEED_COMPRESS_IPO_Y 4 /* ***************** SEQUENCE ****************** */ -#define SEQ_NAME_MAXSTR 64 +#define SEQ_NAME_MAXSTR 64 /* seq->flag */ -#define SEQ_LEFTSEL (1<<1) -#define SEQ_RIGHTSEL (1<<2) -#define SEQ_OVERLAP (1<<3) -#define SEQ_FILTERY (1<<4) -#define SEQ_MUTE (1<<5) -#define SEQ_MAKE_PREMUL (1<<6) -#define SEQ_REVERSE_FRAMES (1<<7) -#define SEQ_IPO_FRAME_LOCKED (1<<8) -#define SEQ_EFFECT_NOT_LOADED (1<<9) -#define SEQ_FLAG_DELETE (1<<10) -#define SEQ_FLIPX (1<<11) -#define SEQ_FLIPY (1<<12) -#define SEQ_MAKE_FLOAT (1<<13) -#define SEQ_LOCK (1<<14) -#define SEQ_USE_PROXY (1<<15) -#define SEQ_USE_TRANSFORM (1<<16) -#define SEQ_USE_CROP (1<<17) -#define SEQ_USE_COLOR_BALANCE (1<<18) -#define SEQ_USE_PROXY_CUSTOM_DIR (1<<19) - -#define SEQ_USE_PROXY_CUSTOM_FILE (1<<21) -#define SEQ_USE_EFFECT_DEFAULT_FADE (1<<22) +#define SEQ_LEFTSEL (1 << 1) +#define SEQ_RIGHTSEL (1 << 2) +#define SEQ_OVERLAP (1 << 3) +#define SEQ_FILTERY (1 << 4) +#define SEQ_MUTE (1 << 5) +#define SEQ_MAKE_PREMUL (1 << 6) +#define SEQ_REVERSE_FRAMES (1 << 7) +#define SEQ_IPO_FRAME_LOCKED (1 << 8) +#define SEQ_EFFECT_NOT_LOADED (1 << 9) +#define SEQ_FLAG_DELETE (1 << 10) +#define SEQ_FLIPX (1 << 11) +#define SEQ_FLIPY (1 << 12) +#define SEQ_MAKE_FLOAT (1 << 13) +#define SEQ_LOCK (1 << 14) +#define SEQ_USE_PROXY (1 << 15) +#define SEQ_USE_TRANSFORM (1 << 16) +#define SEQ_USE_CROP (1 << 17) +#define SEQ_USE_COLOR_BALANCE (1 << 18) +#define SEQ_USE_PROXY_CUSTOM_DIR (1 << 19) + +#define SEQ_USE_PROXY_CUSTOM_FILE (1 << 21) +#define SEQ_USE_EFFECT_DEFAULT_FADE (1 << 22) // flags for whether those properties are animated or not -#define SEQ_AUDIO_VOLUME_ANIMATED (1<<24) -#define SEQ_AUDIO_PITCH_ANIMATED (1<<25) -#define SEQ_AUDIO_PAN_ANIMATED (1<<26) -#define SEQ_AUDIO_DRAW_WAVEFORM (1<<27) +#define SEQ_AUDIO_VOLUME_ANIMATED (1 << 24) +#define SEQ_AUDIO_PITCH_ANIMATED (1 << 25) +#define SEQ_AUDIO_PAN_ANIMATED (1 << 26) +#define SEQ_AUDIO_DRAW_WAVEFORM (1 << 27) -#define SEQ_INVALID_EFFECT (1<<31) +#define SEQ_INVALID_EFFECT (1 << 31) /* convenience define for all selection flags */ -#define SEQ_ALLSEL (SELECT+SEQ_LEFTSEL+SEQ_RIGHTSEL) +#define SEQ_ALLSEL (SELECT + SEQ_LEFTSEL + SEQ_RIGHTSEL) /* deprecated, don't use a flag anymore*/ /*#define SEQ_ACTIVE 1048576*/ @@ -296,51 +297,53 @@ typedef struct SpeedControlVars { #define SEQ_PROXY_TC_RECORD_RUN_NO_GAPS 8 #define SEQ_PROXY_TC_ALL 15 -/* seq->type WATCH IT: SEQ_EFFECT BIT is used to determine if this is an effect strip!!! */ -#define SEQ_IMAGE 0 -#define SEQ_META 1 -#define SEQ_SCENE 2 -#define SEQ_MOVIE 3 -#define SEQ_RAM_SOUND 4 -#define SEQ_HD_SOUND 5 -#define SEQ_SOUND 4 -#define SEQ_MOVIECLIP 6 - -#define SEQ_EFFECT 8 -#define SEQ_CROSS 8 -#define SEQ_ADD 9 -#define SEQ_SUB 10 -#define SEQ_ALPHAOVER 11 -#define SEQ_ALPHAUNDER 12 -#define SEQ_GAMCROSS 13 -#define SEQ_MUL 14 -#define SEQ_OVERDROP 15 -// #define SEQ_PLUGIN 24 /* Deprecated */ -#define SEQ_WIPE 25 -#define SEQ_GLOW 26 -#define SEQ_TRANSFORM 27 -#define SEQ_COLOR 28 -#define SEQ_SPEED 29 -#define SEQ_MULTICAM 30 -#define SEQ_ADJUSTMENT 31 -#define SEQ_EFFECT_MAX 31 +/* seq->type WATCH IT: SEQ_TYPE_EFFECT BIT is used to determine if this is an effect strip!!! */ +enum { + SEQ_TYPE_IMAGE = 0, + SEQ_TYPE_META = 1, + SEQ_TYPE_SCENE = 2, + SEQ_TYPE_MOVIE = 3, + SEQ_TYPE_SOUND_RAM = 4, + SEQ_TYPE_SOUND_HD = 5, + SEQ_TYPE_MOVIECLIP = 6, + SEQ_TYPE_MASK = 7, + + SEQ_TYPE_EFFECT = 8, + SEQ_TYPE_CROSS = 8, + SEQ_TYPE_ADD = 9, + SEQ_TYPE_SUB = 10, + SEQ_TYPE_ALPHAOVER = 11, + SEQ_TYPE_ALPHAUNDER = 12, + SEQ_TYPE_GAMCROSS = 13, + SEQ_TYPE_MUL = 14, + SEQ_TYPE_OVERDROP = 15, + /* SEQ_TYPE_PLUGIN = 24, */ /* Deprecated */ + SEQ_TYPE_WIPE = 25, + SEQ_TYPE_GLOW = 26, + SEQ_TYPE_TRANSFORM = 27, + SEQ_TYPE_COLOR = 28, + SEQ_TYPE_SPEED = 29, + SEQ_TYPE_MULTICAM = 30, + SEQ_TYPE_ADJUSTMENT = 31, + SEQ_TYPE_EFFECT_MAX = 31 +}; #define STRIPELEM_FAILED 0 #define STRIPELEM_OK 1 #define STRIPELEM_PREVIEW_DONE 1 -#define SEQ_MOVIECLIP_RENDER_UNDISTORTED (1<<0) -#define SEQ_MOVIECLIP_RENDER_STABILIZED (1<<1) +#define SEQ_MOVIECLIP_RENDER_UNDISTORTED (1 << 0) +#define SEQ_MOVIECLIP_RENDER_STABILIZED (1 << 1) #define SEQ_BLEND_REPLACE 0 -/* all other BLEND_MODEs are simple SEQ_EFFECT ids and therefore identical +/* all other BLEND_MODEs are simple SEQ_TYPE_EFFECT ids and therefore identical * to the table above. (Only those effects that handle _exactly_ two inputs, * otherwise, you can't really blend, right :) !) */ -#define SEQ_HAS_PATH(_seq) (ELEM4((_seq)->type, SEQ_MOVIE, SEQ_IMAGE, SEQ_RAM_SOUND, SEQ_HD_SOUND)) +#define SEQ_HAS_PATH(_seq) (ELEM4((_seq)->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) #endif diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 8f3062655b7..a315feed6c5 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -67,6 +67,7 @@ struct wmOperator; struct wmTimer; struct MovieClip; struct MovieClipScopes; +struct Mask; /* SpaceLink (Base) ==================================== */ @@ -998,7 +999,10 @@ typedef struct SpaceClip { * defined when drawing and used for mouse position calculation */ /* movie postprocessing */ - int postproc_flag, pad2; + int postproc_flag; + + /* grease pencil */ + short gpencil_src, pad2; void *draw_context; @@ -1006,7 +1010,14 @@ typedef struct SpaceClip { short dope_sort; /* sort order in dopesheet view */ short dope_flag; /* dopsheet view flags */ - int pad3; + int around; /* pivot point for transforms */ + + /* **** mask editing **** */ + struct Mask *mask; + /* draw options */ + char mask_draw_flag; + char mask_draw_type; + char pad3[6]; } SpaceClip; /* SpaceClip->flag */ @@ -1037,6 +1048,7 @@ typedef enum eSpaceClip_Mode { SC_MODE_TRACKING = 0, SC_MODE_RECONSTRUCTION, SC_MODE_DISTORTION, + SC_MODE_MASKEDIT, } eSpaceClip_Mode; /* SpaceClip->view */ @@ -1051,6 +1063,7 @@ typedef enum eSpaceClip_Dopesheet_Sort { SC_DOPE_SORT_NAME = 0, SC_DOPE_SORT_LONGEST, SC_DOPE_SORT_TOTAL, + SC_DOPE_SORT_AVERAGE_ERROR, } eSpaceClip_Dopesheet_Sort; /* SpaceClip->dope_flag */ @@ -1058,6 +1071,12 @@ typedef enum eSpaceClip_Dopesheet_Flag { SC_DOPE_SORT_INVERSE = (1 << 0), } eSpaceClip_Dopesheet_Flag; +/* SpaceClip->gpencil_src */ +typedef enum eSpaceClip_GPencil_Source { + SC_GPENCIL_SRC_CLIP = 0, + SC_GPENCIL_SRC_TRACK = 1, +} eSpaceClip_GPencil_Source; + /* **************** SPACE DEFINES ********************* */ /* headerbuttons: 450-499 */ diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index 6bf059c7ecb..c5b0174a3c9 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -35,10 +35,12 @@ #ifndef __DNA_TRACKING_TYPES_H__ #define __DNA_TRACKING_TYPES_H__ +#include "DNA_defs.h" #include "DNA_listBase.h" /* match-moving data */ +struct bGPdata; struct ImBuf; struct MovieReconstructedCamera; struct MovieTrackingCamera; @@ -68,6 +70,27 @@ typedef struct MovieTrackingCamera { typedef struct MovieTrackingMarker { float pos[2]; /* 2d position of marker on frame (in unified 0..1 space) */ + + /* corners of pattern in the following order: + * + * Y + * ^ + * | (3) --- (2) + * | | | + * | | | + * | | | + * | (0) --- (1) + * +-------------> X + * + * the coordinates are stored relative to pos. + */ + float pattern_corners[4][2]; + + /* positions of left-bottom and right-top corners of search area (in unified 0..1 units, + * relative to marker->pos + */ + float search_min[2], search_max[2]; + int framenr; /* number of frame marker is associated with */ int flag; /* Marker's flag (alive, ...) */ } MovieTrackingMarker; @@ -78,8 +101,19 @@ typedef struct MovieTrackingTrack { char name[64]; /* MAX_NAME */ /* ** setings ** */ - float pat_min[2], pat_max[2]; /* positions of left-bottom and right-top corners of pattern (in unified 0..1 space) */ - float search_min[2], search_max[2]; /* positions of left-bottom and right-top corners of search area (in unified 0..1 space) */ + + /* positions of left-bottom and right-top corners of pattern (in unified 0..1 units, + * relative to marker->pos) + * moved to marker's corners since planar tracking implementation + */ + float pat_min[2] DNA_DEPRECATED, pat_max[2] DNA_DEPRECATED; + + /* positions of left-bottom and right-top corners of search area (in unified 0..1 units, + * relative to marker->pos + * moved to marker since affine tracking implementation + */ + float search_min[2] DNA_DEPRECATED, search_max[2] DNA_DEPRECATED; + float offset[2]; /* offset to "parenting" point */ /* ** track ** */ @@ -95,33 +129,32 @@ typedef struct MovieTrackingTrack { int flag, pat_flag, search_flag; /* flags (selection, ...) */ float color[3]; /* custom color for track */ - /* tracking algorithm to use; can be KLT or SAD */ + /* ** control how tracking happens */ short frames_limit; /* number of frames to be tarcked during single tracking session (if TRACKING_FRAMES_LIMIT is set) */ short margin; /* margin from frame boundaries */ short pattern_match; /* re-adjust every N frames */ - short tracker; /* tracking algorithm used for this track */ - - /* ** KLT tracker settings ** */ - short pyramid_levels, pad2; /* number of pyramid levels to use for KLT tracking */ - - /* ** SAD tracker settings ** */ + /* tracking parameters */ + short motion_model; /* model of the motion for this track */ + int algorithm_flag; /* flags for the tracking algorithm (use brute, use esm, use pyramid, etc */ float minimum_correlation; /* minimal correlation which is still treated as successful tracking */ + + struct bGPdata *gpd; /* grease-pencil data */ } MovieTrackingTrack; typedef struct MovieTrackingSettings { int flag; /* ** default tracker settings */ - short default_tracker; /* tracking algorithm used by default */ - short default_pyramid_levels; /* number of pyramid levels to use for KLT tracking */ - float default_minimum_correlation; /* minimal correlation which is still treated as successful tracking */ - short default_pattern_size; /* size of pattern area for new tracks */ - short default_search_size; /* size of search area for new tracks */ - short default_frames_limit; /* number of frames to be tarcked during single tracking session (if TRACKING_FRAMES_LIMIT is set) */ - short default_margin; /* margin from frame boundaries */ - short default_pattern_match; /* re-adjust every N frames */ - short default_flag; /* default flags like color channels used by default */ + short default_motion_model; /* model of the motion for this track */ + short default_algorithm_flag; /* flags for the tracking algorithm (use brute, use esm, use pyramid, etc */ + float default_minimum_correlation; /* minimal correlation which is still treated as successful tracking */ + short default_pattern_size; /* size of pattern area for new tracks */ + short default_search_size; /* size of search area for new tracks */ + short default_frames_limit; /* number of frames to be tarcked during single tracking session (if TRACKING_FRAMES_LIMIT is set) */ + short default_margin; /* margin from frame boundaries */ + short default_pattern_match; /* re-adjust every N frames */ + short default_flag; /* default flags like color channels used by default */ short motion_flag; /* flags describes motion type */ @@ -255,10 +288,17 @@ enum { #define TRACK_PREVIEW_GRAYSCALE (1<<9) #define TRACK_DOPE_SEL (1<<10) -/* MovieTrackingTrack->tracker */ -#define TRACKER_KLT 0 -#define TRACKER_SAD 1 -#define TRACKER_HYBRID 2 +/* MovieTrackingTrack->motion_model */ +#define TRACK_MOTION_MODEL_TRANSLATION 0 +#define TRACK_MOTION_MODEL_TRANSLATION_ROTATION 1 +#define TRACK_MOTION_MODEL_TRANSLATION_SCALE 2 +#define TRACK_MOTION_MODEL_TRANSLATION_ROTATION_SCALE 3 +#define TRACK_MOTION_MODEL_AFFINE 4 +#define TRACK_MOTION_MODEL_HOMOGRAPHY 5 + +/* MovieTrackingTrack->algorithm_flag */ +#define TRACK_ALGORITHM_FLAG_USE_BRUTE 1 +#define TRACK_ALGORITHM_FLAG_USE_NORMALIZATION 2 /* MovieTrackingTrack->adjframes */ #define TRACK_MATCH_KEYFRAME 0 diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index f53cdf60d6d..6160af6eaf9 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -237,7 +237,7 @@ typedef struct ThemeSpace { char syntaxl[4], syntaxn[4], syntaxb[4]; // syntax for textwindow and nodes char syntaxv[4], syntaxc[4]; - char movie[4], movieclip[4], image[4], scene[4], audio[4]; // for sequence editor + char movie[4], movieclip[4], mask[4], image[4], scene[4], audio[4]; // for sequence editor char effect[4], hpad0[4], transition[4], meta[4]; char editmesh_active[4]; @@ -250,7 +250,7 @@ typedef struct ThemeSpace { char bundle_solid[4]; char path_before[4], path_after[4]; char camera_path[4]; - char hpad[7]; + char hpad[3]; char preview_back[4]; char preview_stitch_face[4]; @@ -264,8 +264,19 @@ typedef struct ThemeSpace { char selected_highlight[4]; /* outliner - selected item */ char skin_root[4]; /* Skin modifier root color */ - + int pad4; + + /* NLA */ + char anim_active[4]; /* Active Action + Summary Channel */ + char anim_non_active[4]; /* Active Action = NULL */ + + char nla_tweaking[4]; /* NLA 'Tweaking' action/strip */ + char nla_tweakdupli[4]; /* NLA - warning color for duplicate instances of tweaking strip */ + + char nla_transition[4], nla_transition_sel[4]; /* NLA "Transition" strips */ + char nla_meta[4], nla_meta_sel[4]; /* NLA "Meta" strips */ + char nla_sound[4], nla_sound_sel[4]; /* NLA "Sound" strips */ } ThemeSpace; diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 6b965b04685..177db545483 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -132,6 +132,7 @@ static const char *includefiles[] = { "DNA_movieclip_types.h", "DNA_tracking_types.h", "DNA_dynamicpaint_types.h", + "DNA_mask_types.h", "DNA_freestyle_types.h", "DNA_linestyle_types.h", @@ -1243,6 +1244,7 @@ int main(int argc, char **argv) #include "DNA_movieclip_types.h" #include "DNA_tracking_types.h" #include "DNA_dynamicpaint_types.h" +#include "DNA_mask_types.h" #include "DNA_freestyle_types.h" #include "DNA_linestyle_types.h" /* end of list */ diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index c683e980877..c15bf04796c 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -145,6 +145,7 @@ extern StructRNA RNA_CompositorNodeLumaMatte; extern StructRNA RNA_CompositorNodeMapUV; extern StructRNA RNA_CompositorNodeMapValue; extern StructRNA RNA_CompositorNodeMath; +extern StructRNA RNA_CompositorNodeMask; extern StructRNA RNA_CompositorNodeMixRGB; extern StructRNA RNA_CompositorNodeNormal; extern StructRNA RNA_CompositorNodeNormalize; @@ -329,6 +330,7 @@ extern StructRNA RNA_Macro; extern StructRNA RNA_MagicTexture; extern StructRNA RNA_MarbleTexture; extern StructRNA RNA_MaskModifier; +extern StructRNA RNA_MaskSequence; extern StructRNA RNA_Material; extern StructRNA RNA_MaterialHalo; extern StructRNA RNA_MaterialPhysics; @@ -339,6 +341,8 @@ extern StructRNA RNA_MaterialStrand; extern StructRNA RNA_MaterialSubsurfaceScattering; extern StructRNA RNA_MaterialTextureSlot; extern StructRNA RNA_MaterialVolume; +extern StructRNA RNA_Mask; +extern StructRNA RNA_MaskLayer; extern StructRNA RNA_Menu; extern StructRNA RNA_Mesh; extern StructRNA RNA_MeshColor; @@ -374,8 +378,10 @@ extern StructRNA RNA_MotionPathVert; extern StructRNA RNA_MouseSensor; extern StructRNA RNA_MovieSequence; extern StructRNA RNA_MovieClipSequence; +extern StructRNA RNA_MovieTracking; extern StructRNA RNA_MovieTrackingTrack; extern StructRNA RNA_MovieTrackingObject; +extern StructRNA RNA_MovieTrackingTrack; extern StructRNA RNA_MulticamSequence; extern StructRNA RNA_MultiresModifier; extern StructRNA RNA_MusgraveTexture; @@ -706,7 +712,7 @@ int RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test); const struct ListBase *RNA_struct_type_properties(StructRNA *srna); PropertyRNA *RNA_struct_type_find_property(StructRNA *srna, const char *identifier); -FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier); +FunctionRNA *RNA_struct_find_function(StructRNA *srna, const char *identifier); const struct ListBase *RNA_struct_type_functions(StructRNA *srna); char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, int *r_len); diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index 9e109487d65..d4138267041 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -149,6 +149,7 @@ EnumPropertyItem *RNA_scene_itemf(struct bContext *C, struct PointerRNA *ptr, st EnumPropertyItem *RNA_scene_local_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int *free); EnumPropertyItem *RNA_movieclip_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int *free); EnumPropertyItem *RNA_movieclip_local_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int *free); - +EnumPropertyItem *RNA_mask_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int *free); +EnumPropertyItem *RNA_mask_local_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int *free); #endif /* __RNA_ENUM_TYPES_H__ */ diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript index 371a0e32155..5379de52ca8 100644 --- a/source/blender/makesrna/SConscript +++ b/source/blender/makesrna/SConscript @@ -11,13 +11,16 @@ incs += ' ../windowmanager ../editors/include ../gpu ../imbuf ../ikplugin ../ble incs += ' ../render/extern/include #/intern/cycles/blender' incs += ' ../nodes' incs += ' #/extern/glew/include' +incs += ' #/intern/smoke/extern' incs += ' ../freestyle' incs += ' ../bmesh' - defs = [] +if env['WITH_BF_SMOKE']: + defs.append('WITH_SMOKE') + if env['WITH_BF_OPENEXR']: defs.append('WITH_OPENEXR') diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index 519e8aff823..24bf6ff4aa1 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -56,6 +56,7 @@ set(DEFSRC rna_lattice.c rna_linestyle.c rna_main.c + rna_mask.c rna_material.c rna_mesh.c rna_meta.c @@ -209,6 +210,10 @@ if(WITH_FFTW3) add_definitions(-DWITH_FFTW3) endif() +if(WITH_MOD_SMOKE) + add_definitions(-DWITH_SMOKE) +endif() + if(WITH_MOD_OCEANSIM) add_definitions(-DWITH_OCEANSIM) endif() @@ -254,6 +259,7 @@ blender_include_dirs( ../../../../intern/cycles/blender ../../../../intern/guardedalloc ../../../../intern/memutil + ../../../../intern/smoke/extern ) blender_include_dirs_sys( diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript index 99fab18b4bf..d26de50fae0 100644 --- a/source/blender/makesrna/intern/SConscript +++ b/source/blender/makesrna/intern/SConscript @@ -35,7 +35,11 @@ incs += ' ../../windowmanager ../../editors/include ../../blenfont' incs += ' ../../render/extern/include ../../bmesh' incs += ' #/intern/audaspace/intern #/intern/cycles/blender' incs += ' #/extern/glew/include ' +incs += ' #/intern/smoke/extern' +if env['WITH_BF_SMOKE']: + defs.append('WITH_SMOKE') + if env['WITH_BF_OPENEXR']: defs.append('WITH_OPENEXR') diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index c50dab50dba..2b3df4e0e3a 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -2682,6 +2682,7 @@ static RNAProcessItem PROCESS_ITEMS[] = { {"rna_world.c", NULL, RNA_def_world}, {"rna_movieclip.c", NULL, RNA_def_movieclip}, {"rna_tracking.c", NULL, RNA_def_tracking}, + {"rna_mask.c", NULL, RNA_def_mask}, {NULL, NULL} }; @@ -2961,12 +2962,12 @@ static void rna_generate_header_cpp(BlenderRNA *brna, FILE *f) fprintf(f, "class %s : public %s {\n", srna->identifier, (srna->base) ? srna->base->identifier : "Pointer"); fprintf(f, "public:\n"); - fprintf(f, "\t%s(const PointerRNA& ptr) :\n\t\t%s(ptr)", srna->identifier, + fprintf(f, "\t%s(const PointerRNA& ptr_arg) :\n\t\t%s(ptr_arg)", srna->identifier, (srna->base) ? srna->base->identifier : "Pointer"); for (dp = ds->cont.properties.first; dp; dp = dp->next) if (!(dp->prop->flag & (PROP_IDPROPERTY | PROP_BUILTIN))) if (dp->prop->type == PROP_COLLECTION) - fprintf(f, ",\n\t\t%s(ptr)", dp->prop->identifier); + fprintf(f, ",\n\t\t%s(ptr_arg)", dp->prop->identifier); fprintf(f, "\n\t\t{}\n\n"); for (dp = ds->cont.properties.first; dp; dp = dp->next) diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 905afaabe3a..e007db62f58 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -149,6 +149,7 @@ short RNA_type_to_ID_code(StructRNA *type) if (RNA_struct_is_a(type, &RNA_World)) return ID_WO; if (RNA_struct_is_a(type, &RNA_WindowManager)) return ID_WM; if (RNA_struct_is_a(type, &RNA_MovieClip)) return ID_MC; + if (RNA_struct_is_a(type, &RNA_Mask)) return ID_MSK; return 0; } @@ -185,6 +186,7 @@ StructRNA *ID_code_to_RNA_type(short idcode) case ID_WO: return &RNA_World; case ID_WM: return &RNA_WindowManager; case ID_MC: return &RNA_MovieClip; + case ID_MSK: return &RNA_Mask; default: return &RNA_ID; } } diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 6f26763fc0e..c8ca0be8ab7 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -664,12 +664,12 @@ PropertyRNA *RNA_struct_type_find_property(StructRNA *srna, const char *identifi return BLI_findstring_ptr(&srna->cont.properties, identifier, offsetof(PropertyRNA, identifier)); } -FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier) +FunctionRNA *RNA_struct_find_function(StructRNA *srna, const char *identifier) { #if 1 FunctionRNA *func; StructRNA *type; - for (type = ptr->type; type; type = type->base) { + for (type = srna; type; type = type->base) { func = (FunctionRNA *)BLI_findstring_ptr(&type->functions, identifier, offsetof(FunctionRNA, identifier)); if (func) { return func; @@ -683,7 +683,7 @@ FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier) PropertyRNA *iterprop; FunctionRNA *func; - RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr); + RNA_pointer_create(NULL, &RNA_Struct, srna, &tptr); iterprop = RNA_struct_find_property(&tptr, "functions"); func = NULL; @@ -1519,7 +1519,7 @@ void RNA_property_update_main(Main *bmain, Scene *scene, PointerRNA *ptr, Proper * * The cache is structured with a dual-layer structure * - L1 = PointerRNA used as key; id.data is used (it should always be defined, - * and most updates end up using just that anyways) + * and most updates end up using just that anyways) * - L2 = Update functions to be called on those PointerRNA's */ @@ -5132,7 +5132,7 @@ int RNA_function_call_lookup(bContext *C, ReportList *reports, PointerRNA *ptr, { FunctionRNA *func; - func = RNA_struct_find_function(ptr, identifier); + func = RNA_struct_find_function(ptr->type, identifier); if (func) return RNA_function_call(C, reports, ptr, func, parms); @@ -5160,7 +5160,7 @@ int RNA_function_call_direct_lookup(bContext *C, ReportList *reports, PointerRNA { FunctionRNA *func; - func = RNA_struct_find_function(ptr, identifier); + func = RNA_struct_find_function(ptr->type, identifier); if (func) { va_list args; @@ -5535,7 +5535,7 @@ int RNA_function_call_direct_va_lookup(bContext *C, ReportList *reports, Pointer { FunctionRNA *func; - func = RNA_struct_find_function(ptr, identifier); + func = RNA_struct_find_function(ptr->type, identifier); if (func) return RNA_function_call_direct_va(C, reports, ptr, func, format, args); diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index d14675b77c8..e96ed4f38d3 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -173,8 +173,8 @@ static int rna_SculptCapabilities_has_random_texture_angle_get(PointerRNA *ptr) { Brush *br = (Brush *)ptr->data; return (ELEM(br->mtex.brush_map_mode, - MTEX_MAP_MODE_VIEW, - MTEX_MAP_MODE_AREA) && + MTEX_MAP_MODE_VIEW, + MTEX_MAP_MODE_AREA) && !(br->flag & BRUSH_ANCHORED) && !ELEM4(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE, @@ -236,17 +236,17 @@ static int rna_SculptCapabilities_has_texture_angle_get(PointerRNA *ptr) { Brush *br = (Brush *)ptr->data; return ELEM3(br->mtex.brush_map_mode, - MTEX_MAP_MODE_VIEW, - MTEX_MAP_MODE_AREA, - MTEX_MAP_MODE_TILED); + MTEX_MAP_MODE_VIEW, + MTEX_MAP_MODE_AREA, + MTEX_MAP_MODE_TILED); } static int rna_SculptCapabilities_has_texture_angle_source_get(PointerRNA *ptr) { Brush *br = (Brush *)ptr->data; return ELEM(br->mtex.brush_map_mode, - MTEX_MAP_MODE_VIEW, - MTEX_MAP_MODE_AREA); + MTEX_MAP_MODE_VIEW, + MTEX_MAP_MODE_AREA); } static PointerRNA rna_Brush_sculpt_capabilities_get(PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c index 37795edb884..3b4f87d8b95 100644 --- a/source/blender/makesrna/intern/rna_cloth.c +++ b/source/blender/makesrna/intern/rna_cloth.c @@ -155,6 +155,25 @@ static void rna_ClothSettings_bend_vgroup_set(PointerRNA *ptr, const char *value rna_object_vgroup_name_index_set(ptr, value, &sim->vgroup_bend); } + +static void rna_CollSettings_selfcol_vgroup_get(PointerRNA *ptr, char *value) +{ + ClothCollSettings *coll = (ClothCollSettings *)ptr->data; + rna_object_vgroup_name_index_get(ptr, value, coll->vgroup_selfcol); +} + +static int rna_CollSettings_selfcol_vgroup_length(PointerRNA *ptr) +{ + ClothCollSettings *coll = (ClothCollSettings *)ptr->data; + return rna_object_vgroup_name_index_length(ptr, coll->vgroup_selfcol); +} + +static void rna_CollSettings_selfcol_vgroup_set(PointerRNA *ptr, const char *value) +{ + ClothCollSettings *coll = (ClothCollSettings *)ptr->data; + rna_object_vgroup_name_index_set(ptr, value, &coll->vgroup_selfcol); +} + static PointerRNA rna_ClothSettings_rest_shape_key_get(PointerRNA *ptr) { Object *ob = (Object *)ptr->id.data; @@ -523,6 +542,13 @@ static void rna_def_cloth_collision_settings(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Collision Group", "Limit colliders to this Group"); RNA_def_property_update(prop, 0, "rna_cloth_update"); + + prop = RNA_def_property(srna, "vertex_group_self_collisions", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs(prop, "rna_CollSettings_selfcol_vgroup_get", "rna_CollSettings_selfcol_vgroup_length", + "rna_CollSettings_selfcol_vgroup_set"); + RNA_def_property_ui_text(prop, "Selfcollision Vertex Group", + "Vertex group to define vertices which are not used during self collisions"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); } void RNA_def_cloth(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index f2700c065a9..a851911f49e 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -600,14 +600,15 @@ static void rna_def_histogram(BlenderRNA *brna) PropertyRNA *prop; static EnumPropertyItem prop_mode_items[] = { - {HISTO_MODE_LUMA, "LUMA", ICON_COLOR, "Luma", ""}, - {HISTO_MODE_RGB, "RGB", ICON_COLOR, "Red Green Blue", ""}, - {HISTO_MODE_R, "R", ICON_COLOR, "Red", ""}, - {HISTO_MODE_G, "G", ICON_COLOR, "Green", ""}, - {HISTO_MODE_B, "B", ICON_COLOR, "Blue", ""}, + {HISTO_MODE_LUMA, "LUMA", 0, "Luma", "Luma"}, + {HISTO_MODE_RGB, "RGB", 0, "RGB", "Red Green Blue"}, + {HISTO_MODE_R, "R", 0, "R", "Red"}, + {HISTO_MODE_G, "G", 0, "G", "Green"}, + {HISTO_MODE_B, "B", 0, "B", "Blue"}, + {HISTO_MODE_ALPHA, "A", 0, "A", "Alpha"}, {0, NULL, 0, NULL, NULL} }; - + srna = RNA_def_struct(brna, "Histogram", NULL); RNA_def_struct_ui_text(srna, "Histogram", "Statistical view of the levels of color in an image"); @@ -615,7 +616,11 @@ static void rna_def_histogram(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "mode"); RNA_def_property_enum_items(prop, prop_mode_items); RNA_def_property_ui_text(prop, "Mode", "Channels to display when drawing the histogram"); - + + prop = RNA_def_property(srna, "show_line", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", HISTO_FLAG_LINE); + RNA_def_property_ui_text(prop, "Show Line", "Displays lines rather then filled shapes"); + RNA_def_property_ui_icon(prop, ICON_IPO, 0); } static void rna_def_scopes(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index e1f1ab97726..8e29e5c2e79 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -44,6 +44,7 @@ #include "ED_object.h" #include "WM_types.h" +/* please keep the names in sync with constraint.c */ EnumPropertyItem constraint_type_items[] = { {0, "", 0, N_("Motion Tracking"), ""}, {CONSTRAINT_TYPE_CAMERASOLVER, "CAMERA_SOLVER", ICON_CONSTRAINT_DATA, "Camera Solver", ""}, diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 7d73de00b49..02d8cbef4a3 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -29,6 +29,7 @@ #include <limits.h> #include <stdio.h> #include <stdlib.h> +#include <stddef.h> #include <string.h> #include <ctype.h> @@ -38,6 +39,7 @@ #include "DNA_sdna_types.h" #include "BLI_utildefines.h" +#include "BLI_listbase.h" #include "BLI_ghash.h" #include "RNA_define.h" @@ -2631,6 +2633,11 @@ FunctionRNA *RNA_def_function(StructRNA *srna, const char *identifier, const cha FunctionRNA *func; FunctionDefRNA *dfunc; + if (BLI_findstring_ptr(&srna->functions, identifier, offsetof(FunctionRNA, identifier))) { + fprintf(stderr, "%s: %s.%s already defined.\n", __func__, srna->identifier, identifier); + return NULL; + } + func = rna_def_function(srna, identifier); if (!DefRNA.preprocess) { diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index daa307e77c2..a4582406c10 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -180,6 +180,7 @@ void RNA_def_wm(struct BlenderRNA *brna); void RNA_def_world(struct BlenderRNA *brna); void RNA_def_movieclip(struct BlenderRNA *brna); void RNA_def_tracking(struct BlenderRNA *brna); +void RNA_def_mask(struct BlenderRNA *brna); /* Common Define functions */ @@ -302,6 +303,7 @@ void RNA_def_main_actions(BlenderRNA *brna, PropertyRNA *cprop); void RNA_def_main_particles(BlenderRNA *brna, PropertyRNA *cprop); void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop); void RNA_def_main_movieclips(BlenderRNA *brna, PropertyRNA *cprop); +void RNA_def_main_masks(BlenderRNA *brna, PropertyRNA *cprop); void RNA_def_main_linestyles(BlenderRNA *brna, PropertyRNA *cprop); /* ID Properties */ diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c index 5b2d8ddbeee..6f8545099ea 100644 --- a/source/blender/makesrna/intern/rna_main.c +++ b/source/blender/makesrna/intern/rna_main.c @@ -253,6 +253,12 @@ static void rna_Main_movieclips_begin(CollectionPropertyIterator *iter, PointerR rna_iterator_listbase_begin(iter, &bmain->movieclip, NULL); } +static void rna_Main_masks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + Main *bmain= (Main*)ptr->data; + rna_iterator_listbase_begin(iter, &bmain->mask, NULL); +} + static void rna_Main_linestyle_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { Main *bmain= (Main*)ptr->data; @@ -322,6 +328,7 @@ void RNA_def_main(BlenderRNA *brna) {"particles", "ParticleSettings", "rna_Main_particle_begin", "Particles", "Particle datablocks", RNA_def_main_particles}, {"grease_pencil", "GreasePencil", "rna_Main_gpencil_begin", "Grease Pencil", "Grease Pencil datablocks", RNA_def_main_gpencil}, {"movieclips", "MovieClip", "rna_Main_movieclips_begin", "Movie Clips", "Movie Clip datablocks", RNA_def_main_movieclips}, + {"masks", "Mask", "rna_Main_masks_begin", "Masks", "Masks datablocks", RNA_def_main_masks}, {"linestyles", "FreestyleLineStyle", "rna_Main_linestyle_begin", "Line Styles", "Line Style datablocks", RNA_def_main_linestyles}, {NULL, NULL, NULL, NULL, NULL, NULL} }; diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 53cfe684203..ed45b378228 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -33,6 +33,8 @@ #include <stdio.h> #include <errno.h> +#include "DNA_ID.h" + #include "RNA_define.h" #include "RNA_access.h" #include "RNA_enum_types.h" @@ -67,6 +69,7 @@ #include "BKE_depsgraph.h" #include "BKE_speaker.h" #include "BKE_movieclip.h" +#include "BKE_mask.h" #include "BKE_linestyle.h" #include "DNA_armature_types.h" @@ -88,6 +91,7 @@ #include "DNA_vfont_types.h" #include "DNA_node_types.h" #include "DNA_movieclip_types.h" +#include "DNA_mask_types.h" #include "ED_screen.h" @@ -540,6 +544,22 @@ void rna_Main_movieclips_remove(Main *bmain, MovieClip *clip) /* XXX python now has invalid pointer? */ } +Mask *rna_Main_mask_new(Main *UNUSED(bmain), const char *name) +{ + Mask *mask; + + mask = BKE_mask_new("Mask"); + + return mask; +} + +void rna_Main_masks_remove(Main *bmain, Mask *mask) +{ + BKE_mask_unlink(bmain, mask); + BKE_libblock_free(&bmain->mask, mask); + /* XXX python now has invalid pointer? */ +} + FreestyleLineStyle *rna_Main_linestyles_new(Main *bmain, const char* name) { FreestyleLineStyle *linestyle = FRS_new_linestyle(name, bmain); @@ -587,6 +607,7 @@ void rna_Main_actions_tag(Main *bmain, int value) { tag_main_lb(&bmain->action, void rna_Main_particles_tag(Main *bmain, int value) { tag_main_lb(&bmain->particle, value); } void rna_Main_gpencil_tag(Main *bmain, int value) { tag_main_lb(&bmain->gpencil, value); } void rna_Main_movieclips_tag(Main *bmain, int value) { tag_main_lb(&bmain->movieclip, value); } +void rna_Main_masks_tag(Main *bmain, int value) { tag_main_lb(&bmain->mask, value); } void rna_Main_linestyle_tag(Main *bmain, int value) { tag_main_lb(&bmain->linestyle, value); } static int rna_Main_cameras_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_CA); } @@ -1539,6 +1560,36 @@ void RNA_def_main_movieclips(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_return(func, parm); } +void RNA_def_main_masks(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "BlendDataMasks"); + srna= RNA_def_struct(brna, "BlendDataMasks", NULL); + RNA_def_struct_sdna(srna, "Main"); + RNA_def_struct_ui_text(srna, "Main Masks", "Collection of masks"); + + func= RNA_def_function(srna, "tag", "rna_Main_masks_tag"); + parm= RNA_def_boolean(func, "value", 0, "Value", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + + /* new func */ + func = RNA_def_function(srna, "new", "rna_Main_mask_new"); + RNA_def_function_ui_description(func, "Add a new mask with a given name to the main database"); + parm = RNA_def_string_file_path(func, "name", "", MAX_ID_NAME - 2, "Mask", "Name of new mask datablock"); + /* return type */ + parm = RNA_def_pointer(func, "mask", "Mask", "", "New mask datablock"); + RNA_def_function_return(func, parm); + + /* remove func */ + func= RNA_def_function(srna, "remove", "rna_Main_masks_remove"); + RNA_def_function_ui_description(func, "Remove a masks from the current blendfile."); + parm= RNA_def_pointer(func, "mask", "Mask", "", "Mask to remove"); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL); +} + void RNA_def_main_linestyles(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c new file mode 100644 index 00000000000..64f1663a524 --- /dev/null +++ b/source/blender/makesrna/intern/rna_mask.c @@ -0,0 +1,696 @@ +/* + * ***** 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. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/makesrna/intern/rna_mask.c + * \ingroup RNA + */ + + +#include <stdlib.h> +#include <limits.h> + +#include "MEM_guardedalloc.h" + +#include "BKE_movieclip.h" +#include "BKE_tracking.h" + +#include "RNA_define.h" + +#include "rna_internal.h" + +#include "DNA_mask_types.h" +#include "DNA_object_types.h" /* SELECT */ +#include "DNA_scene_types.h" + +#include "WM_types.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#ifdef RNA_RUNTIME + +#include "DNA_mask_types.h" + +#include "BKE_depsgraph.h" +#include "BKE_mask.h" + +#include "RNA_access.h" + +#include "WM_api.h" + +static void rna_Mask_update_data(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + Mask *mask = ptr->id.data; + + WM_main_add_notifier(NC_MASK|ND_DATA, mask); + DAG_id_tag_update( &mask->id, 0); +} + +/* note: this function exists only to avoid id refcounting */ +static void rna_MaskParent_id_set(PointerRNA *ptr, PointerRNA value) +{ + MaskParent *mpar = (MaskParent*) ptr->data; + + mpar->id = value.data; +} + +static StructRNA *rna_MaskParent_id_typef(PointerRNA *ptr) +{ + MaskParent *mpar = (MaskParent*) ptr->data; + + return ID_code_to_RNA_type(mpar->id_type); +} + +static void rna_MaskParent_id_type_set(PointerRNA *ptr, int value) +{ + MaskParent *mpar = (MaskParent*) ptr->data; + + /* change ID-type to the new type */ + mpar->id_type = value; + + /* clear the id-block if the type is invalid */ + if ((mpar->id) && (GS(mpar->id->name) != mpar->id_type)) + mpar->id = NULL; +} + +static void rna_Mask_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + Mask *mask = (Mask *)ptr->id.data; + + rna_iterator_listbase_begin(iter, &mask->masklayers, NULL); +} + +static int rna_Mask_layer_active_index_get(PointerRNA *ptr) +{ + Mask *mask = (Mask *)ptr->id.data; + + return mask->masklay_act; +} + +static void rna_Mask_layer_active_index_set(PointerRNA *ptr, int value) +{ + Mask *mask = (Mask *)ptr->id.data; + + mask->masklay_act = value; +} + +static void rna_Mask_layer_active_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax) +{ + Mask *mask = (Mask *)ptr->id.data; + + *min = 0; + *max = mask->masklay_tot - 1; + *max = MAX2(0, *max); + + *softmin = *min; + *softmax = *max; +} + +static char *rna_MaskLayer_path(PointerRNA *ptr) +{ + return BLI_sprintfN("layers[\"%s\"]", ((MaskLayer *)ptr->data)->name); +} + +static PointerRNA rna_Mask_layer_active_get(PointerRNA *ptr) +{ + Mask *mask = (Mask *)ptr->id.data; + MaskLayer *masklay = BKE_mask_layer_active(mask); + + return rna_pointer_inherit_refine(ptr, &RNA_MaskLayer, masklay); +} + +static void rna_Mask_layer_active_set(PointerRNA *ptr, PointerRNA value) +{ + Mask *mask = (Mask *)ptr->id.data; + MaskLayer *masklay = (MaskLayer *)value.data; + + BKE_mask_layer_active_set(mask, masklay); +} + +static void rna_MaskLayer_splines_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + MaskLayer *masklay = (MaskLayer *)ptr->data; + + rna_iterator_listbase_begin(iter, &masklay->splines, NULL); +} + +void rna_MaskLayer_name_set(PointerRNA *ptr, const char *value) +{ + Mask *mask = (Mask *)ptr->id.data; + MaskLayer *masklay = (MaskLayer *)ptr->data; + + BLI_strncpy(masklay->name, value, sizeof(masklay->name)); + + BKE_mask_layer_unique_name(mask, masklay); +} + +static PointerRNA rna_MaskLayer_active_spline_get(PointerRNA *ptr) +{ + MaskLayer *masklay = (MaskLayer *)ptr->data; + + return rna_pointer_inherit_refine(ptr, &RNA_MaskSpline, masklay->act_spline); +} + +static void rna_MaskLayer_active_spline_set(PointerRNA *ptr, PointerRNA value) +{ + MaskLayer *masklay = (MaskLayer *)ptr->data; + MaskSpline *spline = (MaskSpline *)value.data; + int index = BLI_findindex(&masklay->splines, spline); + + if (index >= 0) + masklay->act_spline = spline; + else + masklay->act_spline = NULL; +} + +static PointerRNA rna_MaskLayer_active_spline_point_get(PointerRNA *ptr) +{ + MaskLayer *masklay = (MaskLayer *)ptr->data; + + return rna_pointer_inherit_refine(ptr, &RNA_MaskSplinePoint, masklay->act_point); +} + +static void rna_MaskLayer_active_spline_point_set(PointerRNA *ptr, PointerRNA value) +{ + MaskLayer *masklay = (MaskLayer *)ptr->data; + MaskSpline *spline; + MaskSplinePoint *point = (MaskSplinePoint *)value.data; + + masklay->act_point = NULL; + + for (spline = masklay->splines.first; spline; spline = spline->next) { + if (point >= spline->points && point < spline->points + spline->tot_point) { + masklay->act_point = point; + + break; + } + } +} + +static void rna_MaskSplinePoint_handle1_get(PointerRNA *ptr, float *values) +{ + MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + BezTriple *bezt = &point->bezt; + + values[0] = bezt->vec[0][0]; + values[1] = bezt->vec[0][1]; + values[2] = bezt->vec[0][2]; +} + +static void rna_MaskSplinePoint_handle1_set(PointerRNA *ptr, const float *values) +{ + MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + BezTriple *bezt = &point->bezt; + + bezt->vec[0][0] = values[0]; + bezt->vec[0][1] = values[1]; + bezt->vec[0][2] = values[2]; +} + +static void rna_MaskSplinePoint_handle2_get(PointerRNA *ptr, float *values) +{ + MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + BezTriple *bezt = &point->bezt; + + values[0] = bezt->vec[2][0]; + values[1] = bezt->vec[2][1]; + values[2] = bezt->vec[2][2]; +} + +static void rna_MaskSplinePoint_handle2_set(PointerRNA *ptr, const float *values) +{ + MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + BezTriple *bezt = &point->bezt; + + bezt->vec[2][0] = values[0]; + bezt->vec[2][1] = values[1]; + bezt->vec[2][2] = values[2]; +} + +static void rna_MaskSplinePoint_ctrlpoint_get(PointerRNA *ptr, float *values) +{ + MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + BezTriple *bezt = &point->bezt; + + values[0] = bezt->vec[1][0]; + values[1] = bezt->vec[1][1]; + values[2] = bezt->vec[1][2]; +} + +static void rna_MaskSplinePoint_ctrlpoint_set(PointerRNA *ptr, const float *values) +{ + MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + BezTriple *bezt = &point->bezt; + + bezt->vec[1][0] = values[0]; + bezt->vec[1][1] = values[1]; + bezt->vec[1][2] = values[2]; +} + +static int rna_MaskSplinePoint_handle_type_get(PointerRNA *ptr) +{ + MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + BezTriple *bezt = &point->bezt; + + return bezt->h1; +} + +static void rna_MaskSplinePoint_handle_type_set(PointerRNA *ptr, int value) +{ + MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + BezTriple *bezt = &point->bezt; + + bezt->h1 = bezt->h2 = value; +} + +/* ** API ** */ + +static MaskLayer *rna_Mask_layer_new(Mask *mask, const char *name) +{ + MaskLayer *masklay = BKE_mask_layer_new(mask, name); + + WM_main_add_notifier(NC_MASK|NA_EDITED, mask); + + return masklay; +} + +void rna_Mask_layer_remove(Mask *mask, MaskLayer *masklay) +{ + BKE_mask_layer_remove(mask, masklay); + + WM_main_add_notifier(NC_MASK|NA_EDITED, mask); +} + +static void rna_MaskLayer_spline_add(ID *id, MaskLayer *masklay, int number) +{ + Mask *mask = (Mask*) id; + int i; + + for (i = 0; i < number; i++) + BKE_mask_spline_add(masklay); + + WM_main_add_notifier(NC_MASK|NA_EDITED, mask); +} + +static void rna_Mask_start_frame_set(PointerRNA *ptr, int value) +{ + Mask *data = (Mask *)ptr->data; + /* MINFRAME not MINAFRAME, since some output formats can't taken negative frames */ + CLAMP(value, MINFRAME, MAXFRAME); + data->sfra = value; + + if (data->sfra >= data->efra) { + data->efra = MIN2(data->sfra, MAXFRAME); + } +} + +static void rna_Mask_end_frame_set(PointerRNA *ptr, int value) +{ + Mask *data = (Mask *)ptr->data; + CLAMP(value, MINFRAME, MAXFRAME); + data->efra = value; + + if (data->sfra >= data->efra) { + data->sfra = MAX2(data->efra, MINFRAME); + } +} + +#else + +static void rna_def_maskParent(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem mask_id_type_items[] = { + {ID_MC, "MOVIECLIP", ICON_SEQUENCE, "Movie Clip", ""}, + {0, NULL, 0, NULL, NULL}}; + + srna = RNA_def_struct(brna, "MaskParent", NULL); + RNA_def_struct_ui_text(srna, "Mask Parent", "Parenting settings for masking element"); + + /* Target Properties - ID-block to Drive */ + prop = RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "ID"); + RNA_def_property_flag(prop, PROP_EDITABLE); + // RNA_def_property_editable_func(prop, "rna_maskSpline_id_editable"); + /* note: custom set function is ONLY to avoid rna setting a user for this. */ + RNA_def_property_pointer_funcs(prop, NULL, "rna_MaskParent_id_set", "rna_MaskParent_id_typef", NULL); + RNA_def_property_ui_text(prop, "ID", "ID-block to which masking element would be parented to or to it's property"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + prop = RNA_def_property(srna, "id_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "id_type"); + RNA_def_property_enum_items(prop, mask_id_type_items); + RNA_def_property_enum_default(prop, ID_MC); + RNA_def_property_enum_funcs(prop, NULL, "rna_MaskParent_id_type_set", NULL); + //RNA_def_property_editable_func(prop, "rna_MaskParent_id_type_editable"); + RNA_def_property_ui_text(prop, "ID Type", "Type of ID-block that can be used"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* parent */ + prop = RNA_def_property(srna, "parent", PROP_STRING, PROP_NONE); + RNA_def_property_ui_text(prop, "Parent", "Name of parent object in specified data block to which parenting happens"); + RNA_def_property_string_maxlength(prop, MAX_ID_NAME - 2); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* sub_parent */ + prop = RNA_def_property(srna, "sub_parent", PROP_STRING, PROP_NONE); + RNA_def_property_ui_text(prop, "Sub Parent", "Name of parent sub-object in specified data block to which parenting happens"); + RNA_def_property_string_maxlength(prop, MAX_ID_NAME - 2); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); +} + +static void rna_def_maskSplinePointUW(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "MaskSplinePointUW", NULL); + RNA_def_struct_ui_text(srna, "Mask Spline UW Point", "Single point in spline segment defining feather"); + + /* u */ + prop = RNA_def_property(srna, "u", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "u"); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_ui_text(prop, "U", "U coordinate of point along spline segment"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* weight */ + prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "w"); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_ui_text(prop, "Weight", "Weight of feather point"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* select */ + prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT); + RNA_def_property_ui_text(prop, "Select", "Selection status"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); +} + +static void rna_def_maskSplinePoint(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem handle_type_items[] = { + {HD_AUTO, "AUTO", 0, "Auto", ""}, + {HD_VECT, "VECTOR", 0, "Vector", ""}, + {HD_ALIGN, "ALIGNED", 0, "Aligned", ""}, + {0, NULL, 0, NULL, NULL}}; + + rna_def_maskSplinePointUW(brna); + + srna = RNA_def_struct(brna, "MaskSplinePoint", NULL); + RNA_def_struct_ui_text(srna, "Mask Spline Point", "Single point in spline used for defining mask"); + + /* Vector values */ + prop = RNA_def_property(srna, "handle_left", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_array(prop, 3); + RNA_def_property_float_funcs(prop, "rna_MaskSplinePoint_handle1_get", "rna_MaskSplinePoint_handle1_set", NULL); + RNA_def_property_ui_text(prop, "Handle 1", "Coordinates of the first handle"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + prop = RNA_def_property(srna, "co", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_array(prop, 3); + RNA_def_property_float_funcs(prop, "rna_MaskSplinePoint_ctrlpoint_get", "rna_MaskSplinePoint_ctrlpoint_set", NULL); + RNA_def_property_ui_text(prop, "Control Point", "Coordinates of the control point"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + prop = RNA_def_property(srna, "handle_right", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_array(prop, 3); + RNA_def_property_float_funcs(prop, "rna_MaskSplinePoint_handle2_get", "rna_MaskSplinePoint_handle2_set", NULL); + RNA_def_property_ui_text(prop, "Handle 2", "Coordinates of the second handle"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* handle_type */ + prop = RNA_def_property(srna, "handle_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_funcs(prop, "rna_MaskSplinePoint_handle_type_get", "rna_MaskSplinePoint_handle_type_set", NULL); + RNA_def_property_enum_items(prop, handle_type_items); + RNA_def_property_ui_text(prop, "Handle Type", "Handle type"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* select */ + prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "bezt.f1", SELECT); + RNA_def_property_ui_text(prop, "Select", "Selection status"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* parent */ + prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MaskParent"); + + /* feather points */ + prop = RNA_def_property(srna, "feather_points", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "MaskSplinePointUW"); + RNA_def_property_collection_sdna(prop, NULL, "uw", "tot_uw"); + RNA_def_property_ui_text(prop, "Feather Points", "Points defining feather"); +} + +static void rna_def_mask_splines(BlenderRNA *brna) +{ + StructRNA *srna; + FunctionRNA *func; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "MaskSplines", NULL); + RNA_def_struct_sdna(srna, "MaskLayer"); + RNA_def_struct_ui_text(srna, "Mask Splines", "Collection of masking splines"); + + func = RNA_def_function(srna, "add", "rna_MaskLayer_spline_add"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID); + RNA_def_function_ui_description(func, "Add a number of splines to mask layer"); + RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of splines to add to the layer", 0, INT_MAX); + + /* active spline */ + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MaskSpline"); + RNA_def_property_pointer_funcs(prop, "rna_MaskLayer_active_spline_get", "rna_MaskLayer_active_spline_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); + RNA_def_property_ui_text(prop, "Active Spline", "Active spline of masking layer"); + + /* active point */ + prop = RNA_def_property(srna, "active_point", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MaskSplinePoint"); + RNA_def_property_pointer_funcs(prop, "rna_MaskLayer_active_spline_point_get", "rna_MaskLayer_active_spline_point_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); + RNA_def_property_ui_text(prop, "Active Spline", "Active spline of masking layer"); +} + +static void rna_def_maskSpline(BlenderRNA *brna) +{ + static EnumPropertyItem spline_interpolation_items[] = { + {MASK_SPLINE_INTERP_LINEAR, "LINEAR", 0, "Linear", ""}, + {MASK_SPLINE_INTERP_EASE, "EASE", 0, "Ease", ""}, + {0, NULL, 0, NULL, NULL} + }; + + StructRNA *srna; + PropertyRNA *prop; + + rna_def_maskSplinePoint(brna); + + srna = RNA_def_struct(brna, "MaskSpline", NULL); + RNA_def_struct_ui_text(srna, "Mask spline", "Single spline used for defining mask shape"); + + /* weight interpolation */ + prop = RNA_def_property(srna, "weight_interpolation", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "weight_interp"); + RNA_def_property_enum_items(prop, spline_interpolation_items); + RNA_def_property_ui_text(prop, "Weight Interpolation", "The type of weight interpolation for spline"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* cyclic */ + prop = RNA_def_property(srna, "use_cyclic", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MASK_SPLINE_CYCLIC); + RNA_def_property_ui_text(prop, "Cyclic", "Make this spline a closed loop"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); +} + +static void rna_def_mask_layer(BlenderRNA *brna) +{ + static EnumPropertyItem masklay_blend_mode_items[] = { + {MASK_BLEND_ADD, "ADD", 0, "Add", ""}, + {MASK_BLEND_SUBTRACT, "SUBTRACT", 0, "Subtract", ""}, + {0, NULL, 0, NULL, NULL} + }; + + StructRNA *srna; + PropertyRNA *prop; + + rna_def_maskSpline(brna); + rna_def_mask_splines(brna); + + srna = RNA_def_struct(brna, "MaskLayer", NULL); + RNA_def_struct_ui_text(srna, "Mask Layer", "Single layer used for masking pixels"); + RNA_def_struct_path_func(srna, "rna_MaskLayer_path"); + + /* name */ + prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_ui_text(prop, "Name", "Unique name of layer"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MaskLayer_name_set"); + RNA_def_property_string_maxlength(prop, MAX_ID_NAME - 2); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + RNA_def_struct_name_property(srna, prop); + + /* splines */ + prop = RNA_def_property(srna, "splines", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_funcs(prop, "rna_MaskLayer_splines_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); + RNA_def_property_struct_type(prop, "MaskSpline"); + RNA_def_property_ui_text(prop, "Splines", "Collection of splines which defines this layer"); + RNA_def_property_srna(prop, "MaskSplines"); + + /* restrict */ + prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", MASK_RESTRICT_VIEW); + RNA_def_property_ui_text(prop, "Restrict View", "Restrict visibility in the viewport"); + RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 1); + RNA_def_property_update(prop, NC_MASK | ND_DRAW, NULL); + + prop = RNA_def_property(srna, "hide_select", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", MASK_RESTRICT_SELECT); + RNA_def_property_ui_text(prop, "Restrict Select", "Restrict selection in the viewport"); + RNA_def_property_ui_icon(prop, ICON_RESTRICT_SELECT_OFF, 1); + RNA_def_property_update(prop, NC_MASK | ND_DRAW, NULL); + + prop = RNA_def_property(srna, "hide_render", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", MASK_RESTRICT_RENDER); + RNA_def_property_ui_text(prop, "Restrict Render", "Restrict renderability"); + RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 1); + RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL); + + /* select (for dopesheet)*/ + prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MASK_LAYERFLAG_SELECT); + RNA_def_property_ui_text(prop, "Select", "Layer is selected for editing in the DopeSheet"); +// RNA_def_property_update(prop, NC_SCREEN | ND_MASK, NULL); + + /* render settings */ + prop = RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "alpha"); + RNA_def_property_range(prop, 0.0, 1.0f); + RNA_def_property_ui_text(prop, "Opacity", "Render Opacity"); + RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL); + + /* weight interpolation */ + prop = RNA_def_property(srna, "blend", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "blend"); + RNA_def_property_enum_items(prop, masklay_blend_mode_items); + RNA_def_property_ui_text(prop, "Blend", "Method of blending mask layers"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL); + + prop = RNA_def_property(srna, "invert", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "blend_flag", MASK_BLENDFLAG_INVERT); + RNA_def_property_ui_text(prop, "Restrict View", "Invert the mask black/white"); + RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL); + +} + +static void rna_def_masklayers(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + PropertyRNA *prop; + + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "MaskLayers"); + srna = RNA_def_struct(brna, "MaskLayers", NULL); + RNA_def_struct_sdna(srna, "Mask"); + RNA_def_struct_ui_text(srna, "Mask Layers", "Collection of layers used by mask"); + + func = RNA_def_function(srna, "new", "rna_Mask_layer_new"); + RNA_def_function_ui_description(func, "Add layer to this mask"); + RNA_def_string(func, "name", "", 0, "Name", "Name of new layer"); + parm = RNA_def_pointer(func, "layer", "MaskLayer", "", "New mask layer"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "remove", "rna_Mask_layer_remove"); + RNA_def_function_ui_description(func, "Remove layer from this mask"); + RNA_def_pointer(func, "layer", "MaskLayer", "", "Shape to be removed"); + + /* active layer */ + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MaskLayer"); + RNA_def_property_pointer_funcs(prop, "rna_Mask_layer_active_get", "rna_Mask_layer_active_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); + RNA_def_property_ui_text(prop, "Active Shape", "Active layer in this mask"); +} + +static void rna_def_mask(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + rna_def_mask_layer(brna); + + srna = RNA_def_struct(brna, "Mask", "ID"); + RNA_def_struct_ui_text(srna, "Mask", "Mask datablock defining mask for compositing"); + RNA_def_struct_ui_icon(srna, ICON_MOD_MASK); + + /* mask layers */ + prop = RNA_def_property(srna, "layers", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_funcs(prop, "rna_Mask_layers_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); + RNA_def_property_struct_type(prop, "MaskLayer"); + RNA_def_property_ui_text(prop, "Layers", "Collection of layers which defines this mask"); + rna_def_masklayers(brna, prop); + + /* active masklay index */ + prop = RNA_def_property(srna, "active_layer_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "masklay_act"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_int_funcs(prop, "rna_Mask_layer_active_index_get", "rna_Mask_layer_active_index_set", "rna_Mask_layer_active_index_range"); + RNA_def_property_ui_text(prop, "Active Shape Index", "Index of active layer in list of all mask's layers"); + + /* frame range */ + prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_int_sdna(prop, NULL, "sfra"); + RNA_def_property_int_funcs(prop, NULL, "rna_Mask_start_frame_set", NULL); + RNA_def_property_range(prop, MINFRAME, MAXFRAME); + RNA_def_property_ui_text(prop, "Start Frame", "First frame of the mask (used for sequencer)"); + RNA_def_property_update(prop, NC_SCENE | ND_FRAME_RANGE, NULL); + + prop = RNA_def_property(srna, "frame_end", PROP_INT, PROP_TIME); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_int_sdna(prop, NULL, "efra"); + RNA_def_property_int_funcs(prop, NULL, "rna_Mask_end_frame_set", NULL); + RNA_def_property_range(prop, MINFRAME, MAXFRAME); + RNA_def_property_ui_text(prop, "End Frame", "Final frame of the mask (used for sequencer)"); + RNA_def_property_update(prop, NC_SCENE | ND_FRAME_RANGE, NULL); + + /* pointers */ + rna_def_animdata_common(srna); +} + +void RNA_def_mask(BlenderRNA *brna) +{ + rna_def_maskParent(brna); + rna_def_mask(brna); +} + +#endif diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 21a01cf43a8..eb31d83fce8 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -477,6 +477,15 @@ static void rna_WeightVGModifier_mask_uvlayer_set(PointerRNA *ptr, const char *v } } +static void rna_MultiresModifier_type_set(PointerRNA *ptr, int value) +{ + Object *ob = (Object *)ptr->id.data; + MultiresModifierData *mmd = (MultiresModifierData *)ptr->data; + + multires_force_update(ob); + mmd->simple = value; +} + static void rna_MultiresModifier_level_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax) { MultiresModifierData *mmd = (MultiresModifierData *)ptr->data; @@ -739,7 +748,7 @@ static void rna_BevelModifier_angle_limit_set(PointerRNA *ptr, float value) #else -static void rna_def_property_subdivision_common(StructRNA *srna, const char type[]) +static PropertyRNA *rna_def_property_subdivision_common(StructRNA *srna, const char type[]) { static EnumPropertyItem prop_subdivision_type_items[] = { {0, "CATMULL_CLARK", 0, "Catmull-Clark", ""}, @@ -752,6 +761,8 @@ static void rna_def_property_subdivision_common(StructRNA *srna, const char type RNA_def_property_enum_items(prop, prop_subdivision_type_items); RNA_def_property_ui_text(prop, "Subdivision Type", "Select type of subdivision algorithm"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + return prop; } static void rna_def_modifier_subsurf(BlenderRNA *brna) @@ -901,7 +912,8 @@ static void rna_def_modifier_multires(BlenderRNA *brna) RNA_def_struct_sdna(srna, "MultiresModifierData"); RNA_def_struct_ui_icon(srna, ICON_MOD_MULTIRES); - rna_def_property_subdivision_common(srna, "simple"); + prop = rna_def_property_subdivision_common(srna, "simple"); + RNA_def_property_enum_funcs(prop, NULL, "rna_MultiresModifier_type_set", NULL); prop = RNA_def_property(srna, "levels", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "lvl"); diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c index 2cbe6946485..a4b7516a930 100644 --- a/source/blender/makesrna/intern/rna_movieclip.c +++ b/source/blender/makesrna/intern/rna_movieclip.c @@ -284,6 +284,13 @@ static void rna_def_movieclip(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "GreasePencil"); RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this movie clip"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); + + /* frame offset */ + prop = RNA_def_property(srna, "start_frame", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "start_frame"); + RNA_def_property_ui_text(prop, "Start Frame", "Global scene frame number at which this movie starts playing"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_MovieClip_reload_update"); } void RNA_def_movieclip(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 466a9b80c50..65d572c6c11 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -71,6 +71,16 @@ EnumPropertyItem node_quality_items[] = { {0, NULL, 0, NULL, NULL} }; +EnumPropertyItem node_chunksize_items[] = { + {NTREE_CHUNCKSIZE_32, "32", 0, "32x32", "Chunksize of 32x32"}, + {NTREE_CHUNCKSIZE_64, "64", 0, "64x64", "Chunksize of 64x64"}, + {NTREE_CHUNCKSIZE_128, "128", 0, "128x128", "Chunksize of 128x128"}, + {NTREE_CHUNCKSIZE_256, "256", 0, "256x256", "Chunksize of 256x256"}, + {NTREE_CHUNCKSIZE_512, "512", 0, "512x512", "Chunksize of 512x512"}, + {NTREE_CHUNCKSIZE_1024, "1024", 0, "1024x1024", "Chunksize of 1024x1024"}, + {0, NULL, 0, NULL, NULL} +}; + EnumPropertyItem node_socket_type_items[] = { {SOCK_FLOAT, "VALUE", 0, "Value", ""}, {SOCK_VECTOR, "VECTOR", 0, "Vector", ""}, @@ -1429,6 +1439,12 @@ static void def_sh_tex_environment(StructRNA *srna) RNA_def_property_ui_text(prop, "Projection", "Projection of the input image"); RNA_def_property_update(prop, 0, "rna_Node_update"); + prop = RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "iuser"); + RNA_def_property_ui_text(prop, "Image User", + "Parameters defining which layer, pass and frame of the image is displayed"); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_sh_tex_image(StructRNA *srna) @@ -1458,6 +1474,13 @@ static void def_sh_tex_image(StructRNA *srna) RNA_def_property_enum_items(prop, prop_color_space_items); RNA_def_property_ui_text(prop, "Color Space", "Image file color space"); RNA_def_property_update(prop, 0, "rna_Node_update"); + + prop = RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "iuser"); + RNA_def_property_ui_text(prop, "Image User", + "Parameters defining which layer, pass and frame of the image is displayed"); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_sh_tex_gradient(StructRNA *srna) @@ -1830,29 +1853,10 @@ static void def_cmp_levels(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } -static void def_cmp_image(StructRNA *srna) +static void def_node_image_user(StructRNA *srna) { PropertyRNA *prop; - -#if 0 - static EnumPropertyItem type_items[] = { - {IMA_SRC_FILE, "IMAGE", 0, "Image", ""}, - {IMA_SRC_MOVIE, "MOVIE", "Movie", ""}, - {IMA_SRC_SEQUENCE, "SEQUENCE", "Sequence", ""}, - {IMA_SRC_GENERATED, "GENERATED", "Generated", ""}, - {0, NULL, 0, NULL, NULL} - }; -#endif - - prop = RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "id"); - RNA_def_property_struct_type(prop, "Image"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Image", ""); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); - - RNA_def_struct_sdna_from(srna, "ImageUser", "storage"); - + prop = RNA_def_property(srna, "frame_duration", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "frames"); RNA_def_property_range(prop, 0, MAXFRAMEF); @@ -1893,6 +1897,31 @@ static void def_cmp_image(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_image_layer_update"); } +static void def_cmp_image(StructRNA *srna) +{ + PropertyRNA *prop; + +#if 0 + static EnumPropertyItem type_items[] = { + {IMA_SRC_FILE, "IMAGE", 0, "Image", ""}, + {IMA_SRC_MOVIE, "MOVIE", "Movie", ""}, + {IMA_SRC_SEQUENCE, "SEQUENCE", "Sequence", ""}, + {IMA_SRC_GENERATED, "GENERATED", "Generated", ""}, + {0, NULL, 0, NULL, NULL} + }; +#endif + + prop = RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "id"); + RNA_def_property_struct_type(prop, "Image"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Image", ""); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + RNA_def_struct_sdna_from(srna, "ImageUser", "storage"); + def_node_image_user(srna); +} + static void def_cmp_render_layers(StructRNA *srna) { PropertyRNA *prop; @@ -3030,6 +3059,18 @@ static void def_cmp_moviedistortion(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } +static void def_cmp_mask(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "id"); + RNA_def_property_struct_type(prop, "Mask"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Mask", ""); +} + + static void dev_cmd_transform(StructRNA *srna) { PropertyRNA *prop; @@ -3153,6 +3194,25 @@ static void def_cmp_ellipsemask(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } +static void def_cmp_bokehblur(StructRNA *srna) +{ + PropertyRNA *prop; + prop = RNA_def_property(srna, "f_stop", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "custom3"); + RNA_def_property_range(prop, 0.0f, 128.0f); + RNA_def_property_ui_text(prop, "fStop", + "Amount of focal blur, 128=infinity=perfect focus, half the value doubles " + "the blur radius"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "blur_max", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "custom4"); + RNA_def_property_range(prop, 0.0f, 10000.0f); + RNA_def_property_ui_text(prop, "Max Blur", "Blur limit, maximum CoC radius"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + +} + static void def_cmp_bokehimage(StructRNA *srna) { PropertyRNA *prop; @@ -3442,7 +3502,7 @@ static void def_tex_image(StructRNA *srna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Image", ""); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); - + /* is this supposed to be exposed? not sure.. */ #if 0 prop = RNA_def_property(srna, "settings", PROP_POINTER, PROP_NONE); @@ -3998,11 +4058,11 @@ static void rna_def_composite_nodetree(BlenderRNA *brna) RNA_def_property_enum_items(prop, node_quality_items); RNA_def_property_ui_text(prop, "Edit Quality", "Quality when editing"); - prop = RNA_def_property(srna, "chunk_size", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "chunksize"); + prop = RNA_def_property(srna, "chunk_size", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "chunksize"); + RNA_def_property_enum_items(prop, node_chunksize_items); RNA_def_property_ui_text(prop, "Chunksize", "Max size of a tile (smaller values gives better distribution " "of multiple threads, but more overhead)"); - RNA_def_property_range(prop, 32, 1024); prop = RNA_def_property(srna, "use_opencl", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", NTREE_COM_OPENCL); diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h index 351c6d93514..3981afe5349 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -80,6 +80,7 @@ DefNode( ShaderNode, SH_NODE_NEW_GEOMETRY, 0, "NE DefNode( ShaderNode, SH_NODE_LIGHT_PATH, 0, "LIGHT_PATH", LightPath, "Light Path", "" ) DefNode( ShaderNode, SH_NODE_LIGHT_FALLOFF, 0, "LIGHT_FALLOFF", LightFalloff, "Light Falloff", "" ) DefNode( ShaderNode, SH_NODE_OBJECT_INFO, 0, "OBJECT_INFO", ObjectInfo, "Object Info", "" ) +DefNode( ShaderNode, SH_NODE_PARTICLE_INFO, 0, "PARTICLE_INFO", ParticleInfo, "Particle Info", "" ) DefNode( ShaderNode, SH_NODE_TEX_IMAGE, def_sh_tex_image, "TEX_IMAGE", TexImage, "Image Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_ENVIRONMENT, def_sh_tex_environment, "TEX_ENVIRONMENT", TexEnvironment, "Environment Texture","" ) DefNode( ShaderNode, SH_NODE_TEX_SKY, def_sh_tex_sky, "TEX_SKY", TexSky, "Sky Texture", "" ) @@ -163,8 +164,10 @@ DefNode( CompositorNode, CMP_NODE_MOVIEDISTORTION,def_cmp_moviedistortion,"MOVIE DefNode( CompositorNode, CMP_NODE_MASK_BOX, def_cmp_boxmask, "BOXMASK" ,BoxMask, "Box mask", "" ) DefNode( CompositorNode, CMP_NODE_MASK_ELLIPSE, def_cmp_ellipsemask, "ELLIPSEMASK" ,EllipseMask, "Ellipse mask", "" ) DefNode( CompositorNode, CMP_NODE_BOKEHIMAGE, def_cmp_bokehimage, "BOKEHIMAGE" ,BokehImage, "Bokeh image", "" ) +DefNode( CompositorNode, CMP_NODE_BOKEHBLUR, def_cmp_bokehblur, "BOKEHBLUR" ,BokehBlur, "Bokeh Blur", "" ) DefNode( CompositorNode, CMP_NODE_SWITCH, def_cmp_switch, "SWITCH" ,Switch, "Switch", "" ) DefNode( CompositorNode, CMP_NODE_COLORCORRECTION,def_cmp_colorcorrection,"COLORCORRECTION",ColorCorrection, "ColorCorrection", "" ) +DefNode( CompositorNode, CMP_NODE_MASK, def_cmp_mask, "MASK", Mask, "Mask", "" ) DefNode( TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" ) DefNode( TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" ) diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 7e3b368aa64..0399a8ee60d 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -2545,6 +2545,16 @@ static void rna_def_dupli_object(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_ui_text(prop, "Hide", "Don't show dupli object in viewport or render"); + prop = RNA_def_property(srna, "index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "index"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Index", "Index in the lowest-level dupli list"); + + prop = RNA_def_property(srna, "particle_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "particle_index"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Particle Index", "Index in the lowest-level particle dupli list"); + /* TODO: DupliObject has more properties that can be wrapped */ } diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 70c5f22b9fa..3769b8d6c42 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1612,6 +1612,12 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_ui_icon(prop, ICON_PROP_OFF, 1); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */ + prop = RNA_def_property(srna, "use_proportional_edit_mask", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "proportional_mask", 0); + RNA_def_property_ui_text(prop, "Proportional Editing Objects", "Proportional editing mask mode"); + RNA_def_property_ui_icon(prop, ICON_PROP_OFF, 1); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */ + prop = RNA_def_property(srna, "proportional_edit_falloff", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "prop_mode"); RNA_def_property_enum_items(prop, proportional_falloff_items); @@ -4096,6 +4102,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) prop = RNA_def_property(srna, "use_compositing", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_DOCOMP); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Compositing", "Process the render result through the compositing pipeline, " "if compositing nodes are enabled"); @@ -4103,6 +4110,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) prop = RNA_def_property(srna, "use_sequencer", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_DOSEQ); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Sequencer", "Process the render (and composited) result through the video sequence " "editor pipeline, if sequencer strips exist"); diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index 09e0428058a..b2ff36285e6 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -90,11 +90,14 @@ static void rna_Scene_collada_export( const char *filepath, int selected, int apply_modifiers, + int include_armatures, int include_bone_children, int use_object_instantiation, int second_life) { - collada_export(scene, filepath, selected, apply_modifiers, include_bone_children, use_object_instantiation, second_life); + collada_export(scene, filepath, selected, apply_modifiers, + include_armatures, include_bone_children, + use_object_instantiation, second_life); } #endif @@ -124,6 +127,7 @@ void RNA_api_scene(StructRNA *srna) RNA_def_property_subtype(parm, PROP_FILEPATH); /* allow non utf8 */ parm = RNA_def_boolean(func, "selected", 0, "Selection Only", "Export only selected elements"); parm = RNA_def_boolean(func, "apply_modifiers", 0, "Apply Modifiers", "Apply modifiers (in Preview resolution)"); + parm = RNA_def_boolean(func, "include_armatures", 0, "Include Armatures", "Include armature(s) used by the exported objects"); parm = RNA_def_boolean(func, "include_bone_children", 0, "Include Bone Children", "Include all objects attached to bones of selected Armature(s)"); parm = RNA_def_boolean(func, "use_object_instantiation", 1, "Use Object Instantiation", "Instantiate multiple Objects from same Data"); parm = RNA_def_boolean(func, "second_life", 0, "Export for Second Life", "Compatibility mode for Second Life"); diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 9082bb42be5..fb8ba2f863e 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -64,7 +64,7 @@ static void meta_tmp_ref(Sequence *seq_par, Sequence *seq) { for (; seq; seq = seq->next) { seq->tmp = seq_par; - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { meta_tmp_ref(seq, seq->seqbase.first); } } @@ -396,47 +396,49 @@ static StructRNA *rna_Sequence_refine(struct PointerRNA *ptr) Sequence *seq = (Sequence *)ptr->data; switch (seq->type) { - case SEQ_IMAGE: + case SEQ_TYPE_IMAGE: return &RNA_ImageSequence; - case SEQ_META: + case SEQ_TYPE_META: return &RNA_MetaSequence; - case SEQ_SCENE: + case SEQ_TYPE_SCENE: return &RNA_SceneSequence; - case SEQ_MOVIE: + case SEQ_TYPE_MOVIE: return &RNA_MovieSequence; - case SEQ_MOVIECLIP: + case SEQ_TYPE_MOVIECLIP: return &RNA_MovieClipSequence; - case SEQ_SOUND: + case SEQ_TYPE_MASK: + return &RNA_MaskSequence; + case SEQ_TYPE_SOUND_RAM: return &RNA_SoundSequence; - case SEQ_CROSS: + case SEQ_TYPE_CROSS: return &RNA_CrossSequence; - case SEQ_ADD: + case SEQ_TYPE_ADD: return &RNA_AddSequence; - case SEQ_SUB: + case SEQ_TYPE_SUB: return &RNA_SubtractSequence; - case SEQ_ALPHAOVER: + case SEQ_TYPE_ALPHAOVER: return &RNA_AlphaOverSequence; - case SEQ_ALPHAUNDER: + case SEQ_TYPE_ALPHAUNDER: return &RNA_AlphaUnderSequence; - case SEQ_GAMCROSS: + case SEQ_TYPE_GAMCROSS: return &RNA_GammaCrossSequence; - case SEQ_MUL: + case SEQ_TYPE_MUL: return &RNA_MultiplySequence; - case SEQ_OVERDROP: + case SEQ_TYPE_OVERDROP: return &RNA_OverDropSequence; - case SEQ_MULTICAM: + case SEQ_TYPE_MULTICAM: return &RNA_MulticamSequence; - case SEQ_ADJUSTMENT: + case SEQ_TYPE_ADJUSTMENT: return &RNA_AdjustmentSequence; - case SEQ_WIPE: + case SEQ_TYPE_WIPE: return &RNA_WipeSequence; - case SEQ_GLOW: + case SEQ_TYPE_GLOW: return &RNA_GlowSequence; - case SEQ_TRANSFORM: + case SEQ_TYPE_TRANSFORM: return &RNA_TransformSequence; - case SEQ_COLOR: + case SEQ_TYPE_COLOR: return &RNA_ColorSequence; - case SEQ_SPEED: + case SEQ_TYPE_SPEED: return &RNA_SpeedControlSequence; default: return &RNA_Sequence; @@ -469,7 +471,7 @@ static void rna_Sequence_filepath_set(PointerRNA *ptr, const char *value) { Sequence *seq = (Sequence *)(ptr->data); - if (seq->type == SEQ_SOUND && seq->sound) { + if (seq->type == SEQ_TYPE_SOUND_RAM && seq->sound) { /* for sound strips we need to update the sound as well. * arguably, this could load in a new sound rather than modify an existing one. * but while using the sequencer its most likely your not using the sound in the game engine too. @@ -967,14 +969,14 @@ static void rna_def_strip_color_balance(BlenderRNA *brna) EnumPropertyItem blend_mode_items[] = { {SEQ_BLEND_REPLACE, "REPLACE", 0, "Replace", ""}, - {SEQ_CROSS, "CROSS", 0, "Cross", ""}, - {SEQ_ADD, "ADD", 0, "Add", ""}, - {SEQ_SUB, "SUBTRACT", 0, "Subtract", ""}, - {SEQ_ALPHAOVER, "ALPHA_OVER", 0, "Alpha Over", ""}, - {SEQ_ALPHAUNDER, "ALPHA_UNDER", 0, "Alpha Under", ""}, - {SEQ_GAMCROSS, "GAMMA_CROSS", 0, "Gamma Cross", ""}, - {SEQ_MUL, "MULTIPLY", 0, "Multiply", ""}, - {SEQ_OVERDROP, "OVER_DROP", 0, "Over Drop", ""}, + {SEQ_TYPE_CROSS, "CROSS", 0, "Cross", ""}, + {SEQ_TYPE_ADD, "ADD", 0, "Add", ""}, + {SEQ_TYPE_SUB, "SUBTRACT", 0, "Subtract", ""}, + {SEQ_TYPE_ALPHAOVER, "ALPHA_OVER", 0, "Alpha Over", ""}, + {SEQ_TYPE_ALPHAUNDER, "ALPHA_UNDER", 0, "Alpha Under", ""}, + {SEQ_TYPE_GAMCROSS, "GAMMA_CROSS", 0, "Gamma Cross", ""}, + {SEQ_TYPE_MUL, "MULTIPLY", 0, "Multiply", ""}, + {SEQ_TYPE_OVERDROP, "OVER_DROP", 0, "Over Drop", ""}, {0, NULL, 0, NULL, NULL} }; @@ -984,27 +986,28 @@ static void rna_def_sequence(BlenderRNA *brna) PropertyRNA *prop; static const EnumPropertyItem seq_type_items[] = { - {SEQ_IMAGE, "IMAGE", 0, "Image", ""}, - {SEQ_META, "META", 0, "Meta", ""}, - {SEQ_SCENE, "SCENE", 0, "Scene", ""}, - {SEQ_MOVIE, "MOVIE", 0, "Movie", ""}, - {SEQ_MOVIECLIP, "MOVIECLIP", 0, "Clip", ""}, - {SEQ_SOUND, "SOUND", 0, "Sound", ""}, - {SEQ_CROSS, "CROSS", 0, "Cross", ""}, - {SEQ_ADD, "ADD", 0, "Add", ""}, - {SEQ_SUB, "SUBTRACT", 0, "Subtract", ""}, - {SEQ_ALPHAOVER, "ALPHA_OVER", 0, "Alpha Over", ""}, - {SEQ_ALPHAUNDER, "ALPHA_UNDER", 0, "Alpha Under", ""}, - {SEQ_GAMCROSS, "GAMMA_CROSS", 0, "Gamma Cross", ""}, - {SEQ_MUL, "MULTIPLY", 0, "Multiply", ""}, - {SEQ_OVERDROP, "OVER_DROP", 0, "Over Drop", ""}, - {SEQ_WIPE, "WIPE", 0, "Wipe", ""}, - {SEQ_GLOW, "GLOW", 0, "Glow", ""}, - {SEQ_TRANSFORM, "TRANSFORM", 0, "Transform", ""}, - {SEQ_COLOR, "COLOR", 0, "Color", ""}, - {SEQ_SPEED, "SPEED", 0, "Speed", ""}, - {SEQ_MULTICAM, "MULTICAM", 0, "Multicam Selector", ""}, - {SEQ_ADJUSTMENT, "ADJUSTMENT", 0, "Adjustment Layer", ""}, + {SEQ_TYPE_IMAGE, "IMAGE", 0, "Image", ""}, + {SEQ_TYPE_META, "META", 0, "Meta", ""}, + {SEQ_TYPE_SCENE, "SCENE", 0, "Scene", ""}, + {SEQ_TYPE_MOVIE, "MOVIE", 0, "Movie", ""}, + {SEQ_TYPE_MOVIECLIP, "MOVIECLIP", 0, "Clip", ""}, + {SEQ_TYPE_MASK, "MASK", 0, "Mask", ""}, + {SEQ_TYPE_SOUND_RAM, "SOUND", 0, "Sound", ""}, + {SEQ_TYPE_CROSS, "CROSS", 0, "Cross", ""}, + {SEQ_TYPE_ADD, "ADD", 0, "Add", ""}, + {SEQ_TYPE_SUB, "SUBTRACT", 0, "Subtract", ""}, + {SEQ_TYPE_ALPHAOVER, "ALPHA_OVER", 0, "Alpha Over", ""}, + {SEQ_TYPE_ALPHAUNDER, "ALPHA_UNDER", 0, "Alpha Under", ""}, + {SEQ_TYPE_GAMCROSS, "GAMMA_CROSS", 0, "Gamma Cross", ""}, + {SEQ_TYPE_MUL, "MULTIPLY", 0, "Multiply", ""}, + {SEQ_TYPE_OVERDROP, "OVER_DROP", 0, "Over Drop", ""}, + {SEQ_TYPE_WIPE, "WIPE", 0, "Wipe", ""}, + {SEQ_TYPE_GLOW, "GLOW", 0, "Glow", ""}, + {SEQ_TYPE_TRANSFORM, "TRANSFORM", 0, "Transform", ""}, + {SEQ_TYPE_COLOR, "COLOR", 0, "Color", ""}, + {SEQ_TYPE_SPEED, "SPEED", 0, "Speed", ""}, + {SEQ_TYPE_MULTICAM, "MULTICAM", 0, "Multicam Selector", ""}, + {SEQ_TYPE_ADJUSTMENT, "ADJUSTMENT", 0, "Adjustment Layer", ""}, {0, NULL, 0, NULL, NULL} }; @@ -1505,6 +1508,8 @@ static void rna_def_movieclip(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "MovieClip Sequence", "Sequence strip to load a video from the clip editor"); RNA_def_struct_sdna(srna, "Sequence"); + /* TODO - add clip property? */ + prop = RNA_def_property(srna, "undistort", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "clip_flag", SEQ_MOVIECLIP_RENDER_UNDISTORTED); RNA_def_property_ui_text(prop, "Undistort Clip", "Use the undistorted version of the clip"); @@ -1519,6 +1524,23 @@ static void rna_def_movieclip(BlenderRNA *brna) rna_def_input(srna); } +static void rna_def_mask(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "MaskSequence", "Sequence"); + RNA_def_struct_ui_text(srna, "Mask Sequence", "Sequence strip to load a video from a mask"); + RNA_def_struct_sdna(srna, "Sequence"); + + prop = RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Mask", "Mask that this sequence uses"); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); + + rna_def_filter_video(srna); + rna_def_input(srna); +} static void rna_def_sound(BlenderRNA *brna) { @@ -1883,6 +1905,7 @@ void RNA_def_sequencer(BlenderRNA *brna) rna_def_scene(brna); rna_def_movie(brna); rna_def_movieclip(brna); + rna_def_mask(brna); rna_def_sound(brna); rna_def_effect(brna); rna_def_effects(brna); diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index bdbd153b1e2..3a534cd22b4 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -45,6 +45,7 @@ extern EnumPropertyItem blend_mode_items[]; #include "DNA_image_types.h" #include "DNA_scene_types.h" #include "DNA_sequence_types.h" +#include "DNA_mask_types.h" #include "DNA_sound_types.h" #include "BLI_path_util.h" /* BLI_split_dirfile */ @@ -52,6 +53,7 @@ extern EnumPropertyItem blend_mode_items[]; #include "BKE_image.h" #include "BKE_library.h" /* id_us_plus */ #include "BKE_movieclip.h" +#include "BKE_mask.h" #include "BKE_report.h" #include "BKE_sequencer.h" @@ -104,7 +106,7 @@ static Sequence *rna_Sequences_new_clip(ID *id, Editing *ed, ReportList *reports Scene *scene = (Scene *)id; Sequence *seq; - seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_MOVIECLIP, clip->name); + seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MOVIECLIP, clip->name); seq->clip = clip; seq->len = BKE_movieclip_get_duration(clip); id_us_plus((ID *)clip); @@ -116,6 +118,25 @@ static Sequence *rna_Sequences_new_clip(ID *id, Editing *ed, ReportList *reports return seq; } +static Sequence *rna_Sequences_new_mask(ID *id, Editing *ed, ReportList *reports, + const char *name, Mask *mask, int channel, + int start_frame) +{ + Scene *scene = (Scene *)id; + Sequence *seq; + + seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MASK, mask->id.name); + seq->mask = mask; + seq->len = BKE_mask_get_duration(mask); + id_us_plus((ID *)mask); + + calc_sequence_disp(scene, seq); + + WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene); + + return seq; +} + static Sequence *rna_Sequences_new_scene(ID *id, Editing *ed, ReportList *reports, const char *name, Scene *sce_seq, int channel, int start_frame) @@ -123,7 +144,7 @@ static Sequence *rna_Sequences_new_scene(ID *id, Editing *ed, ReportList *report Scene *scene = (Scene *)id; Sequence *seq; - seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_SCENE, NULL); + seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_SCENE, NULL); seq->scene = sce_seq; seq->len = sce_seq->r.efra - sce_seq->r.sfra + 1; seq->scene_sound = sound_scene_add_scene_sound(scene, seq, start_frame, start_frame + seq->len, 0); @@ -143,7 +164,7 @@ static Sequence *rna_Sequences_new_image(ID *id, Editing *ed, ReportList *report Scene *scene = (Scene *)id; Sequence *seq; - seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_IMAGE, file); + seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_IMAGE, file); seq->len = 1; if (seq->strip->stripdata->name[0] == '\0') { @@ -174,7 +195,7 @@ static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *report return NULL; } - seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_MOVIE, file); + seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MOVIE, file); seq->anim = an; seq->anim_preseek = IMB_anim_get_preseek(an); seq->len = IMB_anim_get_duration(an, IMB_TC_RECORD_RUN); @@ -200,7 +221,7 @@ static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, Repor return NULL; } - seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_SOUND, sound->name); + seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_SOUND_RAM, sound->name); seq->sound = sound; seq->len = ceil((double)sound_get_length(sound) * FPS); @@ -318,7 +339,6 @@ static StripElem *rna_SequenceElements_push(ID *id, Sequence *seq, const char *f static void rna_SequenceElements_pop(ID *id, Sequence *seq, ReportList *reports, int index) { - int i; Scene *scene = (Scene *)id; StripElem *new_seq, *se; @@ -327,7 +347,12 @@ static void rna_SequenceElements_pop(ID *id, Sequence *seq, ReportList *reports, return; } - if (seq->len <= index) { + /* python style negative indexing */ + if (index < 0) { + index += seq->len; + } + + if (seq->len <= index || index < 0) { BKE_report(reports, RPT_ERROR, "SequenceElements.pop: index out of range"); return; } @@ -335,11 +360,12 @@ static void rna_SequenceElements_pop(ID *id, Sequence *seq, ReportList *reports, new_seq = MEM_callocN(sizeof(StripElem) * (seq->len - 1), "SequenceElements_pop"); seq->len--; - for (i = 0, se = seq->strip->stripdata; i < seq->len; i++, se++) { - if (i == index) - se++; - BLI_strncpy(new_seq[i].name, se->name, sizeof(se->name)); - } + se = seq->strip->stripdata; + if (index > 0) + memcpy(new_seq, se, sizeof(StripElem) * index); + + if (index < seq->len) + memcpy(&new_seq[index], &se[index + 1], sizeof(StripElem) * (seq->len - index)); MEM_freeN(seq->strip->stripdata); seq->strip->stripdata = new_seq; @@ -394,7 +420,7 @@ void RNA_api_sequence_elements(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "pop", "rna_SequenceElements_pop"); RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Pop an image off the collection"); - parm = RNA_def_int(func, "index", 0, 0, INT_MAX, "", "Index of image to remove", 0, INT_MAX); + parm = RNA_def_int(func, "index", -1, INT_MIN, INT_MAX, "", "Index of image to remove", INT_MIN, INT_MAX); RNA_def_property_flag(parm, PROP_REQUIRED); } @@ -405,21 +431,21 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) FunctionRNA *func; static EnumPropertyItem seq_effect_items[] = { - {SEQ_CROSS, "CROSS", 0, "Cross", ""}, - {SEQ_ADD, "ADD", 0, "Add", ""}, - {SEQ_SUB, "SUBTRACT", 0, "Subtract", ""}, - {SEQ_ALPHAOVER, "ALPHA_OVER", 0, "Alpha Over", ""}, - {SEQ_ALPHAUNDER, "ALPHA_UNDER", 0, "Alpha Under", ""}, - {SEQ_GAMCROSS, "GAMMA_CROSS", 0, "Gamma Cross", ""}, - {SEQ_MUL, "MULTIPLY", 0, "Multiply", ""}, - {SEQ_OVERDROP, "OVER_DROP", 0, "Over Drop", ""}, - {SEQ_WIPE, "WIPE", 0, "Wipe", ""}, - {SEQ_GLOW, "GLOW", 0, "Glow", ""}, - {SEQ_TRANSFORM, "TRANSFORM", 0, "Transform", ""}, - {SEQ_COLOR, "COLOR", 0, "Color", ""}, - {SEQ_SPEED, "SPEED", 0, "Speed", ""}, - {SEQ_MULTICAM, "MULTICAM", 0, "Multicam Selector", ""}, - {SEQ_ADJUSTMENT, "ADJUSTMENT", 0, "Adjustment Layer", ""}, + {SEQ_TYPE_CROSS, "CROSS", 0, "Cross", ""}, + {SEQ_TYPE_ADD, "ADD", 0, "Add", ""}, + {SEQ_TYPE_SUB, "SUBTRACT", 0, "Subtract", ""}, + {SEQ_TYPE_ALPHAOVER, "ALPHA_OVER", 0, "Alpha Over", ""}, + {SEQ_TYPE_ALPHAUNDER, "ALPHA_UNDER", 0, "Alpha Under", ""}, + {SEQ_TYPE_GAMCROSS, "GAMMA_CROSS", 0, "Gamma Cross", ""}, + {SEQ_TYPE_MUL, "MULTIPLY", 0, "Multiply", ""}, + {SEQ_TYPE_OVERDROP, "OVER_DROP", 0, "Over Drop", ""}, + {SEQ_TYPE_WIPE, "WIPE", 0, "Wipe", ""}, + {SEQ_TYPE_GLOW, "GLOW", 0, "Glow", ""}, + {SEQ_TYPE_TRANSFORM, "TRANSFORM", 0, "Transform", ""}, + {SEQ_TYPE_COLOR, "COLOR", 0, "Color", ""}, + {SEQ_TYPE_SPEED, "SPEED", 0, "Speed", ""}, + {SEQ_TYPE_MULTICAM, "MULTICAM", 0, "Multicam Selector", ""}, + {SEQ_TYPE_ADJUSTMENT, "ADJUSTMENT", 0, "Adjustment Layer", ""}, {0, NULL, 0, NULL, NULL} }; @@ -445,6 +471,23 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_pointer(func, "sequence", "Sequence", "", "New Sequence"); RNA_def_function_return(func, parm); + func = RNA_def_function(srna, "new_mask", "rna_Sequences_new_mask"); + RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID); + RNA_def_function_ui_description(func, "Add a new movie clip sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_pointer(func, "mask", "Mask", "", "Mask to add"); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", + "The channel for the new sequence", 0, MAXSEQ - 1); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + "The start frame for the new sequence", -MAXFRAME, MAXFRAME); + RNA_def_property_flag(parm, PROP_REQUIRED); + /* return type */ + parm = RNA_def_pointer(func, "sequence", "Sequence", "", "New Sequence"); + RNA_def_function_return(func, parm); + func = RNA_def_function(srna, "new_scene", "rna_Sequences_new_scene"); RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Add a new scene sequence"); diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c index 19925546de3..c0efff2d179 100644 --- a/source/blender/makesrna/intern/rna_smoke.c +++ b/source/blender/makesrna/intern/rna_smoke.c @@ -51,6 +51,8 @@ #include "BKE_depsgraph.h" #include "BKE_particle.h" +#include "smoke_API.h" + static void rna_Smoke_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { @@ -111,6 +113,35 @@ static char *rna_SmokeCollSettings_path(PointerRNA *ptr) return BLI_sprintfN("modifiers[\"%s\"].coll_settings", md->name); } +static int rna_SmokeModifier_density_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION]) +{ + SmokeDomainSettings *settings = (SmokeDomainSettings *)ptr->data; + + if (settings->fluid) + { + float *density = smoke_get_density(settings->fluid); + unsigned int size = settings->res[0] * settings->res[1] * settings->res[2]; + + if(density) + length[0] = size; + else + length[0] = 0; + } + else + length[0] = 0; // No smoke domain created yet + + return length[0]; +} + +static void rna_SmokeModifier_density_get(PointerRNA *ptr, float *values) +{ + SmokeDomainSettings *settings = (SmokeDomainSettings *)ptr->data; + float *density = smoke_get_density(settings->fluid); + unsigned int size = settings->res[0] * settings->res[1] * settings->res[2]; + + memcpy(values, density, size * sizeof(float)); +} + #else static void rna_def_smoke_domain_settings(BlenderRNA *brna) @@ -282,6 +313,33 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Vorticity", "Amount of turbulence/rotation in fluid"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + prop = RNA_def_property(srna, "density", PROP_FLOAT, PROP_NONE); + RNA_def_property_array(prop, 32); + RNA_def_property_flag(prop, PROP_DYNAMIC); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_dynamic_array_funcs(prop, "rna_SmokeModifier_density_get_length"); + RNA_def_property_float_funcs(prop, "rna_SmokeModifier_density_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Density", "Smoke density"); + + prop = RNA_def_property(srna, "cell_size", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "dx"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "dx", "Cell Size"); + + prop = RNA_def_property(srna, "start_point", PROP_FLOAT, PROP_XYZ); + RNA_def_property_float_sdna(prop, NULL, "p0"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "p0", "Start point"); + + prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "scale"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "scale", "Domain scale factor"); + + prop = RNA_def_property(srna, "domain_resolution", PROP_INT, PROP_XYZ); + RNA_def_property_int_sdna(prop, NULL, "res"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "res", "Smoke Grid Resolution"); } static void rna_def_smoke_flow_settings(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 9b4dcd03c79..cafe8ebefad 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -45,6 +45,7 @@ #include "DNA_object_types.h" #include "DNA_space_types.h" #include "DNA_sequence_types.h" +#include "DNA_mask_types.h" #include "DNA_view3d_types.h" #include "WM_api.h" @@ -120,6 +121,7 @@ EnumPropertyItem viewport_shade_items[] = { #ifdef RNA_RUNTIME #include "DNA_anim_types.h" +#include "DNA_mask_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" @@ -1037,6 +1039,13 @@ static void rna_SpaceClipEditor_clip_set(PointerRNA *ptr, PointerRNA value) ED_space_clip_set(NULL, screen, sc, (MovieClip *)value.data); } +static void rna_SpaceClipEditor_mask_set(PointerRNA *ptr, PointerRNA value) +{ + SpaceClip *sc= (SpaceClip*)(ptr->data); + + ED_space_clip_set_mask(NULL, sc, (Mask*)value.data); +} + static void rna_SpaceClipEditor_clip_mode_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { SpaceClip *sc = (SpaceClip *)(ptr->data); @@ -1060,6 +1069,14 @@ static void rna_SpaceClipEditor_view_type_update(Main *UNUSED(bmain), Scene *UNU #else +static EnumPropertyItem dt_uv_items[] = { + {SI_UVDT_OUTLINE, "OUTLINE", 0, "Outline", "Draw white edges with black outline"}, + {SI_UVDT_DASH, "DASH", 0, "Dash", "Draw dashed black-white edges"}, + {SI_UVDT_BLACK, "BLACK", 0, "Black", "Draw black edges"}, + {SI_UVDT_WHITE, "WHITE", 0, "White", "Draw white edges"}, + {0, NULL, 0, NULL, NULL} +}; + static void rna_def_space(BlenderRNA *brna) { StructRNA *srna; @@ -1091,14 +1108,6 @@ static void rna_def_space_image_uv(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; - static EnumPropertyItem dt_uv_items[] = { - {SI_UVDT_OUTLINE, "OUTLINE", 0, "Outline", "Draw white edges with black outline"}, - {SI_UVDT_DASH, "DASH", 0, "Dash", "Draw dashed black-white edges"}, - {SI_UVDT_BLACK, "BLACK", 0, "Black", "Draw black edges"}, - {SI_UVDT_WHITE, "WHITE", 0, "White", "Draw white edges"}, - {0, NULL, 0, NULL, NULL} - }; - static EnumPropertyItem dt_uvstretch_items[] = { {SI_UVDT_STRETCH_ANGLE, "ANGLE", 0, "Angle", "Angular distortion between UV and 3D angles"}, {SI_UVDT_STRETCH_AREA, "AREA", 0, "Area", "Area distortion between UV and 3D faces"}, @@ -2220,6 +2229,7 @@ static void rna_def_space_dopesheet(BlenderRNA *brna) {SACTCONT_ACTION, "ACTION", ICON_OBJECT_DATA, "Action Editor", "Action Editor"}, {SACTCONT_SHAPEKEY, "SHAPEKEY", ICON_SHAPEKEY_DATA, "ShapeKey Editor", "ShapeKey Editor"}, {SACTCONT_GPENCIL, "GPENCIL", ICON_GREASEPENCIL, "Grease Pencil", "Grease Pencil"}, + {SACTCONT_MASK, "MASK", ICON_MOD_MASK, "Mask", "Mask Editor"}, {0, NULL, 0, NULL, NULL} }; @@ -2974,6 +2984,7 @@ static void rna_def_space_clip(BlenderRNA *brna) {SC_MODE_RECONSTRUCTION, "RECONSTRUCTION", ICON_SNAP_FACE, "Reconstruction", "Show tracking/reconstruction tools"}, {SC_MODE_DISTORTION, "DISTORTION", ICON_GRID, "Distortion", "Show distortion tools"}, + {SC_MODE_MASKEDIT, "MASKEDIT", ICON_MOD_MASK, "Mask editing", "Show mask editing tools"}, {0, NULL, 0, NULL, NULL} }; @@ -2988,6 +2999,23 @@ static void rna_def_space_clip(BlenderRNA *brna) {SC_DOPE_SORT_NAME, "NAME", 0, "Name", "Sort channels by their names"}, {SC_DOPE_SORT_LONGEST, "LONGEST", 0, "Longest", "Sort channels by longest tracked segment"}, {SC_DOPE_SORT_TOTAL, "TOTAL", 0, "Total", "Sort channels by overall amount of tracked segments"}, + {SC_DOPE_SORT_AVERAGE_ERROR, "AVERAGE_ERROR", 0, "Average Error", "Sort channels by average reprojection error of tracks after solve"}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem gpencil_source_items[] = { + {SC_GPENCIL_SRC_CLIP, "CLIP", 0, "Clip", "Show grease pencil datablock which belongs to movie clip"}, + {SC_GPENCIL_SRC_TRACK, "TRACK", 0, "Track", "Show grease pencil datablock which belongs to active track"}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem pivot_items[] = { + {V3D_CENTER, "BOUNDING_BOX_CENTER", ICON_ROTATE, "Bounding Box Center", + "Pivot around bounding box center of selected object(s)"}, + {V3D_LOCAL, "INDIVIDUAL_ORIGINS", ICON_ROTATECOLLECTION, + "Individual Origins", "Pivot around each object's own origin"}, + {V3D_CENTROID, "MEDIAN_POINT", ICON_ROTATECENTER, "Median Point", + "Pivot around the median point of selected objects"}, {0, NULL, 0, NULL, NULL} }; @@ -3011,6 +3039,26 @@ static void rna_def_space_clip(BlenderRNA *brna) "Parameters defining which frame of the movie clip is displayed"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); + /* mask */ + prop= RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Mask", "Mask displayed and edited in this space"); + RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceClipEditor_mask_set", NULL, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); + + /* mask drawing */ + prop = RNA_def_property(srna, "mask_draw_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "mask_draw_type"); + RNA_def_property_enum_items(prop, dt_uv_items); + RNA_def_property_ui_text(prop, "Edge Draw Type", "Draw type for mask splines"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); + + prop = RNA_def_property(srna, "show_mask_smooth", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "mask_draw_flag", MASK_DRAWFLAG_SMOOTH); + RNA_def_property_ui_text(prop, "Draw Smooth Splines", ""); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); + + /* mode */ prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "mode"); @@ -3170,6 +3218,20 @@ static void rna_def_space_clip(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames"); RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); + /* grease pencil source */ + prop = RNA_def_property(srna, "grease_pencil_source", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "gpencil_src"); + RNA_def_property_enum_items(prop, gpencil_source_items); + RNA_def_property_ui_text(prop, "Grease Pencil Source", "Where the grease pencil comes from"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); + + /* pivot point */ + prop = RNA_def_property(srna, "pivot_point", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "around"); + RNA_def_property_enum_items(prop, pivot_items); + RNA_def_property_ui_text(prop, "Pivot Point", "Pivot center for rotation/scaling"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); + /* ** dopesheet ** */ /* dopesheet sort */ diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 7a6753ad588..aaa96fc4d95 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -59,20 +59,6 @@ static char *rna_tracking_path(PointerRNA *UNUSED(ptr)) return BLI_sprintfN("tracking"); } -static void rna_tracking_defaultSettings_levelsUpdate(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) -{ - MovieClip *clip = (MovieClip*)ptr->id.data; - MovieTracking *tracking = &clip->tracking; - MovieTrackingSettings *settings = &tracking->settings; - - if (settings->default_tracker == TRACKER_KLT) { - int max_pyramid_level_factor = 1 << (settings->default_pyramid_levels - 1); - float search_ratio = 2.3f * max_pyramid_level_factor; - - settings->default_search_size = settings->default_pattern_size*search_ratio; - } -} - static void rna_tracking_defaultSettings_patternUpdate(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { MovieClip *clip = (MovieClip*)ptr->id.data; @@ -209,37 +195,6 @@ static void rna_trackingTrack_select_set(PointerRNA *ptr, int value) } } -static void rna_tracking_trackerPattern_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) -{ - MovieTrackingTrack *track = (MovieTrackingTrack *)ptr->data; - - BKE_tracking_clamp_track(track, CLAMP_PAT_DIM); -} - -static void rna_tracking_trackerSearch_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) -{ - MovieTrackingTrack *track = (MovieTrackingTrack *)ptr->data; - - BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM); -} - -static void rna_tracking_trackerAlgorithm_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) -{ - MovieTrackingTrack *track = (MovieTrackingTrack *)ptr->data; - - if (track->tracker == TRACKER_KLT) - BKE_tracking_clamp_track(track, CLAMP_PYRAMID_LEVELS); - else - BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM); -} - -static void rna_tracking_trackerPyramid_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) -{ - MovieTrackingTrack *track = (MovieTrackingTrack *)ptr->data; - - BKE_tracking_clamp_track(track, CLAMP_PYRAMID_LEVELS); -} - static char *rna_trackingCamera_path(PointerRNA *UNUSED(ptr)) { return BLI_sprintfN("tracking.camera"); @@ -338,6 +293,20 @@ static void rna_trackingObject_tracks_begin(CollectionPropertyIterator *iter, Po } } +static PointerRNA rna_trackingObject_reconstruction_get(PointerRNA *ptr) +{ + MovieTrackingObject *object = (MovieTrackingObject* )ptr->data; + + if (object->flag & TRACKING_OBJECT_CAMERA) { + MovieClip *clip = (MovieClip*)ptr->id.data; + + return rna_pointer_inherit_refine(ptr, &RNA_MovieTrackingReconstruction, &clip->tracking.reconstruction); + } + else { + return rna_pointer_inherit_refine(ptr, &RNA_MovieTrackingReconstruction, &object->reconstruction); + } +} + static PointerRNA rna_tracking_active_object_get(PointerRNA *ptr) { MovieClip *clip = (MovieClip*)ptr->id.data; @@ -399,6 +368,20 @@ static void rna_trackingMarker_frame_set(PointerRNA *ptr, int value) } } +static void rna_tracking_markerPattern_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + MovieTrackingMarker *marker = (MovieTrackingMarker *)ptr->data; + + BKE_tracking_clamp_marker(marker, CLAMP_PAT_DIM); +} + +static void rna_tracking_markerSearch_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + MovieTrackingMarker *marker = (MovieTrackingMarker *)ptr->data; + + BKE_tracking_clamp_marker(marker, CLAMP_SEARCH_DIM); +} + /* API */ static void add_tracks_to_base(MovieClip *clip, MovieTracking *tracking, ListBase *tracksbase, int frame, int number) @@ -484,11 +467,19 @@ void rna_trackingMarkers_delete_frame(MovieTrackingTrack *track, int framenr) #else -static EnumPropertyItem tracker_items[] = { - {TRACKER_KLT, "KLT", 0, "KLT", - "Kanade–Lucas–Tomasi tracker which works with most of video clips, a bit slower than SAD"}, - {TRACKER_SAD, "SAD", 0, "SAD", "Sum of Absolute Differences tracker which can be used when KLT tracker fails"}, - {TRACKER_HYBRID, "Hybrid", 0, "Hybrid", "A hybrid tracker that uses SAD for rough tracking, KLT for refinement."}, +static EnumPropertyItem tracker_motion_model[] = { + {TRACK_MOTION_MODEL_HOMOGRAPHY, "Perspective", 0, "Perspective", + "Search for markers that are perspectively deformed (homography) between frames."}, + {TRACK_MOTION_MODEL_AFFINE, "Affine", 0, "Affine", + "Search for markers that are affine-deformed (t, r, k, and skew) between frames."}, + {TRACK_MOTION_MODEL_TRANSLATION_ROTATION_SCALE, "LocRotScale", 0, "LocRotScale", + "Search for markers that are translated, rotated, and scaled between frames."}, + {TRACK_MOTION_MODEL_TRANSLATION_SCALE, "LocScale", 0, "LocScale", + "Search for markers that are translated and scaled between frames."}, + {TRACK_MOTION_MODEL_TRANSLATION_ROTATION, "LocRot", 0, "LocRot", + "Search for markers that are translated and rotated between frames."}, + {TRACK_MOTION_MODEL_TRANSLATION, "Loc", 0, "Loc", + "Search for markers that are translated between frames."}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem pattern_match_items[] = { @@ -497,6 +488,7 @@ static EnumPropertyItem pattern_match_items[] = { {0, NULL, 0, NULL, NULL}}; static int rna_matrix_dimsize_4x4[] = {4, 4}; +static int rna_matrix_dimsize_4x2[] = {4, 2}; static void rna_def_trackingSettings(BlenderRNA *brna) { @@ -613,14 +605,14 @@ static void rna_def_trackingSettings(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "motion_flag", TRACKING_MOTION_TRIPOD); RNA_def_property_ui_text(prop, "Tripod Motion", "Use special solver to track a stable camera position, such as a tripod"); - /* limit frames */ + /* default_limit_frames */ prop = RNA_def_property(srna, "default_frames_limit", PROP_INT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_int_sdna(prop, NULL, "default_frames_limit"); RNA_def_property_range(prop, 0, SHRT_MAX); RNA_def_property_ui_text(prop, "Frames Limit", "Every tracking cycle, this number of frames are tracked"); - /* pattern match */ + /* default_pattern_match */ prop = RNA_def_property(srna, "default_pattern_match", PROP_ENUM, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_enum_sdna(prop, NULL, "default_pattern_match"); @@ -628,40 +620,42 @@ static void rna_def_trackingSettings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Pattern Match", "Track pattern from given frame when tracking marker to next frame"); - /* margin */ + /* default_margin */ prop = RNA_def_property(srna, "default_margin", PROP_INT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_int_sdna(prop, NULL, "default_margin"); RNA_def_property_range(prop, 0, 300); RNA_def_property_ui_text(prop, "Margin", "Default distance from image boudary at which marker stops tracking"); - /* tracking algorithm */ - prop = RNA_def_property(srna, "default_tracker", PROP_ENUM, PROP_NONE); + /* default_tracking_motion_model */ + prop = RNA_def_property(srna, "default_motion_model", PROP_ENUM, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_enum_items(prop, tracker_items); - RNA_def_property_update(prop, 0, "rna_tracking_defaultSettings_levelsUpdate"); - RNA_def_property_ui_text(prop, "Tracker", "Default tracking algorithm to use"); + RNA_def_property_enum_items(prop, tracker_motion_model); + RNA_def_property_ui_text(prop, "Motion model", "Default motion model to use for tracking"); - /* pyramid level for pyramid klt tracking */ - prop = RNA_def_property(srna, "default_pyramid_levels", PROP_INT, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_int_sdna(prop, NULL, "default_pyramid_levels"); - RNA_def_property_range(prop, 1, 16); - RNA_def_property_update(prop, 0, "rna_tracking_defaultSettings_levelsUpdate"); - RNA_def_property_ui_text(prop, "Pyramid levels", "Default number of pyramid levels (increase on blurry footage)"); + /* use_brute */ + prop = RNA_def_property(srna, "default_use_brute", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_BRUTE); + RNA_def_property_ui_text(prop, "Prepass", "Use a brute-force translation-only initialization when tracking"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* default use_normalization */ + prop = RNA_def_property(srna, "default_use_normalization", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_NORMALIZATION); + RNA_def_property_ui_text(prop, "Normalize", "Normalize light intensities while tracking. Slower"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); - /* minmal correlation - only used for SAD tracker */ + /* default minmal correlation */ prop = RNA_def_property(srna, "default_correlation_min", PROP_FLOAT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_float_sdna(prop, NULL, "default_minimum_correlation"); - RNA_def_property_range(prop, -1.0f, 1.0f); - RNA_def_property_ui_range(prop, -1.0f, 1.0f, 0.1, 3); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.05, 3); RNA_def_property_ui_text(prop, "Correlation", - "Default minimal value of correlation between matched pattern and reference " - "which is still treated as successful tracking"); + "Default minimum value of correlation between matched pattern and reference " + "that is still treated as successful tracking"); /* default pattern size */ prop = RNA_def_property(srna, "default_pattern_size", PROP_INT, PROP_NONE); @@ -679,19 +673,19 @@ static void rna_def_trackingSettings(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_tracking_defaultSettings_searchUpdate"); RNA_def_property_ui_text(prop, "Search Size", "Size of search area for newly created tracks"); - /* use_red_channel */ + /* default use_red_channel */ prop = RNA_def_property(srna, "use_default_red_channel", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "default_flag", TRACK_DISABLE_RED); RNA_def_property_ui_text(prop, "Use Red Channel", "Use red channel from footage for tracking"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); - /* use_green_channel */ + /* default_use_green_channel */ prop = RNA_def_property(srna, "use_default_green_channel", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "default_flag", TRACK_DISABLE_GREEN); RNA_def_property_ui_text(prop, "Use Green Channel", "Use green channel from footage for tracking"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); - /* use_blue_channel */ + /* default_use_blue_channel */ prop = RNA_def_property(srna, "use_default_blue_channel", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "default_flag", TRACK_DISABLE_BLUE); RNA_def_property_ui_text(prop, "Use Blue Channel", "Use blue channel from footage for tracking"); @@ -825,6 +819,38 @@ static void rna_def_trackingMarker(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", MARKER_DISABLED); RNA_def_property_ui_text(prop, "Mode", "Is marker muted for current frame"); RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + + /* pattern */ + prop = RNA_def_property(srna, "pattern_corners", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_float_sdna(prop, NULL, "pattern_corners"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x2); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); + RNA_def_property_ui_text(prop, "Pattern Corners", + "Array of coordinates which represents patter's corners in " + " normalized coordinates relative to marker position"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_markerPattern_update"); + + /* search */ + prop = RNA_def_property(srna, "search_min", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); + RNA_def_property_float_sdna(prop, NULL, "search_min"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Search Min", + "Left-bottom corner of search area in normalized coordinates relative " + "to marker position"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_markerSearch_update"); + + prop = RNA_def_property(srna, "search_max", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); + RNA_def_property_float_sdna(prop, NULL, "search_max"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Search Max", + "Right-bottom corner of search area in normalized coordinates relative " + "to marker position"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_markerSearch_update"); } static void rna_def_trackingMarkers(BlenderRNA *brna, PropertyRNA *cprop) @@ -885,48 +911,6 @@ static void rna_def_trackingTrack(BlenderRNA *brna) RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); RNA_def_struct_name_property(srna, prop); - /* Pattern */ - prop = RNA_def_property(srna, "pattern_min", PROP_FLOAT, PROP_TRANSLATION); - RNA_def_property_array(prop, 2); - RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); - RNA_def_property_float_sdna(prop, NULL, "pat_min"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Pattern Min", - "Left-bottom corner of pattern area in normalized coordinates relative " - "to marker position"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerPattern_update"); - - prop = RNA_def_property(srna, "pattern_max", PROP_FLOAT, PROP_TRANSLATION); - RNA_def_property_array(prop, 2); - RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); - RNA_def_property_float_sdna(prop, NULL, "pat_max"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Pattern Max", - "Right-bottom corner of pattern area in normalized coordinates relative " - "to marker position"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerPattern_update"); - - /* Search */ - prop = RNA_def_property(srna, "search_min", PROP_FLOAT, PROP_TRANSLATION); - RNA_def_property_array(prop, 2); - RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); - RNA_def_property_float_sdna(prop, NULL, "search_min"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Search Min", - "Left-bottom corner of search area in normalized coordinates relative " - "to marker position"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerSearch_update"); - - prop = RNA_def_property(srna, "search_max", PROP_FLOAT, PROP_TRANSLATION); - RNA_def_property_array(prop, 2); - RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); - RNA_def_property_float_sdna(prop, NULL, "search_max"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Search Max", - "Right-bottom corner of search area in normalized coordinates relative " - "to marker position"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerSearch_update"); - /* limit frames */ prop = RNA_def_property(srna, "frames_limit", PROP_INT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); @@ -952,32 +936,36 @@ static void rna_def_trackingTrack(BlenderRNA *brna) RNA_def_property_range(prop, 0, 300); RNA_def_property_ui_text(prop, "Margin", "Distance from image boudary at which marker stops tracking"); - /* tracking algorithm */ - prop = RNA_def_property(srna, "tracker", PROP_ENUM, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_enum_items(prop, tracker_items); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Tracker", "Tracking algorithm to use"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerAlgorithm_update"); - - /* pyramid level for pyramid klt tracking */ - prop = RNA_def_property(srna, "pyramid_levels", PROP_INT, PROP_NONE); + /* tracking motion model */ + prop = RNA_def_property(srna, "motion_model", PROP_ENUM, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_int_sdna(prop, NULL, "pyramid_levels"); + RNA_def_property_enum_items(prop, tracker_motion_model); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_range(prop, 1, 16); - RNA_def_property_ui_text(prop, "Pyramid levels", "Number of pyramid levels (increase on blurry footage)"); - RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerPyramid_update"); + RNA_def_property_ui_text(prop, "Motion model", "Default motion model to use for tracking"); - /* minmal correlation - only used for SAD tracker */ + /* minimum correlation */ prop = RNA_def_property(srna, "correlation_min", PROP_FLOAT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_float_sdna(prop, NULL, "minimum_correlation"); - RNA_def_property_range(prop, -1.0f, 1.0f); - RNA_def_property_ui_range(prop, -1.0f, 1.0f, 0.1, 3); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.05, 3); RNA_def_property_ui_text(prop, "Correlation", "Minimal value of correlation between matched pattern and reference " - "which is still treated as successful tracking"); + "that is still treated as successful tracking"); + + /* use_brute */ + prop = RNA_def_property(srna, "use_brute", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "algorithm_flag", TRACK_ALGORITHM_FLAG_USE_BRUTE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Prepass", "Use a brute-force translation only pre-track before refinement"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* use_brute */ + prop = RNA_def_property(srna, "use_normalization", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "algorithm_flag", TRACK_ALGORITHM_FLAG_USE_NORMALIZATION); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Normalize", "Normalize light intensities while tracking. Slower"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); /* markers */ prop = RNA_def_property(srna, "markers", PROP_COLLECTION, PROP_NONE); @@ -1088,6 +1076,14 @@ static void rna_def_trackingTrack(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "error"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Average Error", "Average error of re-projection"); + + /* grease pencil */ + prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "gpd"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this track"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); } static void rna_def_trackingStabilization(BlenderRNA *brna) @@ -1330,6 +1326,7 @@ static void rna_def_trackingObject(BlenderRNA *brna) /* reconstruction */ prop = RNA_def_property(srna, "reconstruction", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MovieTrackingReconstruction"); + RNA_def_property_pointer_funcs(prop, "rna_trackingObject_reconstruction_get", NULL, NULL, NULL); /* scale */ prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 6fbd83df3c0..792d3b88d73 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -1929,6 +1929,12 @@ static void rna_def_userdef_theme_space_action(BlenderRNA *brna) RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "DopeSheet Sub-Channel", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "summary", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "anim_active"); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Summary", "Color of summary channel"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_nla(BlenderRNA *brna) @@ -1957,28 +1963,79 @@ static void rna_def_userdef_theme_space_nla(BlenderRNA *brna) RNA_def_property_ui_text(prop, "View Sliders", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "bars", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_float_sdna(prop, NULL, "shade2"); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Bars", ""); + prop = RNA_def_property(srna, "active_action", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "anim_active"); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Active Action", "Animation data block has active action"); RNA_def_property_update(prop, 0, "rna_userdef_update"); - - prop = RNA_def_property(srna, "bars_selected", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_float_sdna(prop, NULL, "hilite"); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Bars Selected", ""); + + prop = RNA_def_property(srna, "active_action_unset", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "anim_non_active"); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "No Active Action", "Animation data block doesn't have active action"); RNA_def_property_update(prop, 0, "rna_userdef_update"); - + prop = RNA_def_property(srna, "strips", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "strip"); RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Strips", ""); + RNA_def_property_ui_text(prop, "Strips", "Action-Clip Strip - Unselected"); RNA_def_property_update(prop, 0, "rna_userdef_update"); - + prop = RNA_def_property(srna, "strips_selected", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "strip_select"); RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Strips Selected", ""); + RNA_def_property_ui_text(prop, "Strips Selected", "Action-Clip Strip - Selected"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "transition_strips", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "nla_transition"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Transitions", "Transition Strip - Unselected"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "transition_strips_selected", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "nla_transition_sel"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Transitions Selected", "Transition Strip - Selected"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "meta_strips", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "nla_meta"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Meta Strips", "Meta Strip - Unselected (for grouping related strips)"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "meta_strips_selected", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "nla_meta_sel"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Meta Strips Selected", "Meta Strip - Selected (for grouping related strips)"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "sound_strips", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "nla_sound"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Sound Strips", + "Sound Strip - Unselected (for timing speaker sounds)"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "sound_strips_selected", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "nla_sound_sel"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Sound Strips Selected", + "Sound Strip - Selected (for timing speaker sounds)"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "tweak", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "nla_tweaking"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Tweak", "Color for strip/action being 'tweaked' or edited"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "tweak_duplicate", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "nla_tweakdupli"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Tweak Duplicate Flag", + "Warning/error indicator color for strips referencing the strip being tweaked"); RNA_def_property_update(prop, 0, "rna_userdef_update"); prop = RNA_def_property(srna, "frame_current", PROP_FLOAT, PROP_COLOR_GAMMA); @@ -2937,7 +2994,7 @@ static void rna_def_userdef_system(BlenderRNA *brna) {10, "CATALAN", 0, "Catalan (Català )", "ca_AD"}, {16, "CROATIAN", 0, "Croatian (Hrvatski)", "hr_HR"}, {11, "CZECH", 0, "Czech (Český)", "cs_CZ"}, -/* { 3, "DUTCH", 0, "Dutch (Nederlandse taal)", "nl_NL"}, */ /* XXX No po's yet. */ + { 3, "DUTCH", 0, "Dutch (Nederlandse taal)", "nl_NL"}, { 6, "FINNISH", 0, "Finnish (Suomi)", "fi_FI"}, { 5, "GERMAN", 0, "German (Deutsch)", "de_DE"}, {23, "GREEK", 0, "Greek (Ελληνικά)", "el_GR"}, diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c index eb3334d31ce..1b3e3c16486 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -79,7 +79,11 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj if ((l1 = e->l) && (l2 = e->l->radial_next) != l1) { - if (dot_v3v3(l1->f->no, l2->f->no) < threshold) { + if (/* 3+ faces on thsi edge, always split */ + UNLIKELY(l1 != l2->radial_next) || + /* 2 face edge - check angle*/ + (dot_v3v3(l1->f->no, l2->f->no) < threshold)) + { BMO_elem_flag_enable(bm, e, EDGE_MARK); } } diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index b69f167f876..b9593353288 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -205,12 +205,12 @@ static MFace *get_dface(DerivedMesh *dm, DerivedMesh *split, int cur, int i, MFa return df; } -#define SET_VERTS(a, b, c, d) \ - v[0] = mf->v##a; uv[0] = a - 1; \ - v[1] = mf->v##b; uv[1] = b - 1; \ - v[2] = mf->v##c; uv[2] = c - 1; \ - v[3] = mf->v##d; uv[3] = d - 1; \ - (void)0 +#define SET_VERTS(a, b, c, d) { \ + v[0] = mf->v##a; uv[0] = a - 1; \ + v[1] = mf->v##b; uv[1] = b - 1; \ + v[2] = mf->v##c; uv[2] = c - 1; \ + v[3] = mf->v##d; uv[3] = d - 1; \ + } (void)0 #define GET_ES(v1, v2) edgecut_get(eh, v1, v2) #define INT_UV(uvf, c0, c1) interp_v2_v2v2(uvf, mf->uv[c0], mf->uv[c1], 0.5f) diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c index 57966b5824b..2b55471be3d 100644 --- a/source/blender/modifiers/intern/MOD_remesh.c +++ b/source/blender/modifiers/intern/MOD_remesh.c @@ -87,6 +87,7 @@ static void init_dualcon_mesh(DualConInput *mesh, DerivedMesh *dm) mesh->face_stride = sizeof(MFace); mesh->totface = dm->getNumTessFaces(dm); + INIT_MINMAX(mesh->min, mesh->max); dm->getMinMax(dm, mesh->min, mesh->max); } diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c index 99a5dcb5ef5..545e2135344 100644 --- a/source/blender/modifiers/intern/MOD_smooth.c +++ b/source/blender/modifiers/intern/MOD_smooth.c @@ -118,8 +118,14 @@ static void smoothModifier_do( fac = smd->fac; facm = 1 - fac; - medges = dm->getEdgeArray(dm); - numDMEdges = dm->getNumEdges(dm); + if (dm->getNumVerts(dm) == numVerts) { + medges = dm->getEdgeArray(dm); + numDMEdges = dm->getNumEdges(dm); + } + else { + medges = NULL; + numDMEdges = 0; + } modifier_get_vgroup(ob, dm, smd->defgrp_name, &dvert, &defgrp_index); @@ -244,6 +250,7 @@ ModifierTypeInfo modifierType_Smooth = { /* structSize */ sizeof(SmoothModifierData), /* type */ eModifierTypeType_OnlyDeform, /* flags */ eModifierTypeFlag_AcceptsMesh | + eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode, /* copyData */ copyData, diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 745cf1304bd..6f8e65a6e8e 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -435,7 +435,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, if (ofs_orig != 0.0f) { scalar_short = scalar_short_vgroup = ofs_orig / 32767.0f; - mv = mvert + (((ofs_new >= ofs_orig) == do_flip) ? 0 : numVerts); /* as above but swapped, intentional use 'ofs_new' */ + mv = mvert + (((ofs_new >= ofs_orig) == do_flip) ? 0 : numVerts); /* as above but swapped */ dv = dvert; for (i = 0; i < numVerts; i++, mv++) { if (dv) { diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 6bae6cdd473..8b2a5ebd263 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -82,6 +82,7 @@ set(SRC composite/nodes/node_composite_mapUV.c composite/nodes/node_composite_mapValue.c composite/nodes/node_composite_math.c + composite/nodes/node_composite_mask.c composite/nodes/node_composite_mixrgb.c composite/nodes/node_composite_movieclip.c composite/nodes/node_composite_moviedistortion.c @@ -158,6 +159,7 @@ set(SRC shader/nodes/node_shader_light_path.c shader/nodes/node_shader_light_falloff.c shader/nodes/node_shader_object_info.c + shader/nodes/node_shader_particle_info.c shader/nodes/node_shader_mix_shader.c shader/nodes/node_shader_add_shader.c shader/nodes/node_shader_output_lamp.c diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h index ca925c82afd..f850ea91f12 100644 --- a/source/blender/nodes/NOD_composite.h +++ b/source/blender/nodes/NOD_composite.h @@ -50,6 +50,7 @@ void register_node_type_cmp_value(struct bNodeTreeType *ttype); void register_node_type_cmp_rgb(struct bNodeTreeType *ttype); void register_node_type_cmp_curve_time(struct bNodeTreeType *ttype); void register_node_type_cmp_movieclip(struct bNodeTreeType *ttype); +void register_node_type_cmp_usermask(struct bNodeTreeType *ttype); void register_node_type_cmp_composite(struct bNodeTreeType *ttype); void register_node_type_cmp_viewer(struct bNodeTreeType *ttype); @@ -115,6 +116,7 @@ void register_node_type_cmp_mapuv(struct bNodeTreeType *ttype); void register_node_type_cmp_transform(struct bNodeTreeType *ttype); void register_node_type_cmp_stabilize2d(struct bNodeTreeType *ttype); void register_node_type_cmp_moviedistortion(struct bNodeTreeType *ttype); +void register_node_type_cmp_mask(struct bNodeTreeType *ttype); void register_node_type_cmp_glare(struct bNodeTreeType *ttype); void register_node_type_cmp_tonemap(struct bNodeTreeType *ttype); diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h index dd6d25380b4..6b000181953 100644 --- a/source/blender/nodes/NOD_shader.h +++ b/source/blender/nodes/NOD_shader.h @@ -78,6 +78,7 @@ void register_node_type_sh_object_info(struct bNodeTreeType *ttype); void register_node_type_sh_fresnel(struct bNodeTreeType *ttype); void register_node_type_sh_layer_weight(struct bNodeTreeType *ttype); void register_node_type_sh_tex_coord(struct bNodeTreeType *ttype); +void register_node_type_sh_particle_info(struct bNodeTreeType *ttype); void register_node_type_sh_background(struct bNodeTreeType *ttype); void register_node_type_sh_bsdf_diffuse(struct bNodeTreeType *ttype); diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index 8f8f702e8ae..457322929b0 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -890,6 +890,10 @@ int ntreeCompositTagAnimated(bNodeTree *ntree) nodeUpdate(ntree, node); tagged= 1; } + else if (node->type==CMP_NODE_MASK) { + nodeUpdate(ntree, node); + tagged= 1; + } } return tagged; diff --git a/source/blender/nodes/composite/node_composite_util.c b/source/blender/nodes/composite/node_composite_util.c index 3806cf4543a..ff223ac83cf 100644 --- a/source/blender/nodes/composite/node_composite_util.c +++ b/source/blender/nodes/composite/node_composite_util.c @@ -568,6 +568,22 @@ CompBuf *valbuf_from_rgbabuf(CompBuf *cbuf, int channel) return valbuf; } +void valbuf_to_rgbabuf(CompBuf *valbuf, CompBuf *cbuf, int channel) +{ + float *valf, *rectf; + int tot; + + valf= valbuf->rect; + + /* defaults to returning alpha channel */ + if ((channel < CHAN_R) || (channel > CHAN_A)) channel = CHAN_A; + + rectf = cbuf->rect + channel; + + for (tot= cbuf->x*cbuf->y; tot>0; tot--, valf++, rectf+=4) + *rectf = *valf; +} + static CompBuf *generate_procedural_preview(CompBuf *cbuf, int newx, int newy) { CompBuf *outbuf; diff --git a/source/blender/nodes/composite/node_composite_util.h b/source/blender/nodes/composite/node_composite_util.h index 8f42a9bbe47..cab60caaae7 100644 --- a/source/blender/nodes/composite/node_composite_util.h +++ b/source/blender/nodes/composite/node_composite_util.h @@ -157,6 +157,7 @@ void composit4_pixel_processor(bNode *node, CompBuf *out, CompBuf *src1_buf, flo int src1_type, int fac1_type, int src2_type, int fac2_type); CompBuf *valbuf_from_rgbabuf(CompBuf *cbuf, int channel); +void valbuf_to_rgbabuf(CompBuf *valbuf, CompBuf *cbuf, int channel); void generate_preview(void *data, bNode *node, CompBuf *stackbuf); void do_copy_rgba(bNode *node, float *out, float *in); diff --git a/source/blender/nodes/composite/nodes/node_composite_bokehblur.c b/source/blender/nodes/composite/nodes/node_composite_bokehblur.c index ab679b9242f..6b24bdb5c52 100644 --- a/source/blender/nodes/composite/nodes/node_composite_bokehblur.c +++ b/source/blender/nodes/composite/nodes/node_composite_bokehblur.c @@ -28,7 +28,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_blur.c +/** \file blender/nodes/composite/nodes/node_composite_bokehblur.c * \ingroup cmpnodes */ @@ -39,7 +39,7 @@ static bNodeSocketTemplate cmp_node_bokehblur_in[]= { { SOCK_RGBA, 1, N_("Image"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_RGBA, 1, N_("Bokeh"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_FLOAT, 1, N_("Size"), 0.01f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f}, + { SOCK_FLOAT, 1, N_("Size"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 10.0f}, { SOCK_FLOAT, 1, N_("Bounding box"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f}, { -1, 0, "" } }; @@ -49,6 +49,12 @@ static bNodeSocketTemplate cmp_node_bokehblur_out[]= { { -1, 0, "" } }; +static void node_composit_init_bokehblur(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) +{ + node->custom3 = 4.0f; + node->custom4 = 16.0f; +} + void register_node_type_cmp_bokehblur(bNodeTreeType *ttype) { static bNodeType ntype; @@ -56,5 +62,7 @@ void register_node_type_cmp_bokehblur(bNodeTreeType *ttype) node_type_base(ttype, &ntype, CMP_NODE_BOKEHBLUR, "Bokeh Blur", NODE_CLASS_OP_FILTER, NODE_OPTIONS); node_type_socket_templates(&ntype, cmp_node_bokehblur_in, cmp_node_bokehblur_out); node_type_size(&ntype, 120, 80, 200); + node_type_init(&ntype, node_composit_init_bokehblur); + nodeRegisterType(ttype, &ntype); } diff --git a/source/blender/nodes/composite/nodes/node_composite_bokehimage.c b/source/blender/nodes/composite/nodes/node_composite_bokehimage.c index b46e7e646de..24378c4d5b7 100644 --- a/source/blender/nodes/composite/nodes/node_composite_bokehimage.c +++ b/source/blender/nodes/composite/nodes/node_composite_bokehimage.c @@ -28,7 +28,7 @@ */ -/** \file blender/nodes/intern/CMP_nodes/CMP_gamma.c +/** \file blender/nodes/composite/nodes/node_composite_bokehimage.c * \ingroup cmpnodes */ diff --git a/source/blender/nodes/composite/nodes/node_composite_boxmask.c b/source/blender/nodes/composite/nodes/node_composite_boxmask.c index 4bd6ab4698b..81c13980f22 100644 --- a/source/blender/nodes/composite/nodes/node_composite_boxmask.c +++ b/source/blender/nodes/composite/nodes/node_composite_boxmask.c @@ -27,7 +27,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_math.c +/** \file blender/nodes/composite/nodes/node_composite_boxmask.c * \ingroup cmpnodes */ diff --git a/source/blender/nodes/composite/nodes/node_composite_ellipsemask.c b/source/blender/nodes/composite/nodes/node_composite_ellipsemask.c index 7a1e82ddd9b..18a86680245 100644 --- a/source/blender/nodes/composite/nodes/node_composite_ellipsemask.c +++ b/source/blender/nodes/composite/nodes/node_composite_ellipsemask.c @@ -27,7 +27,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_math.c +/** \file blender/nodes/composite/nodes/node_composite_ellipsemask.c * \ingroup cmpnodes */ diff --git a/source/blender/nodes/composite/nodes/node_composite_mask.c b/source/blender/nodes/composite/nodes/node_composite_mask.c new file mode 100644 index 00000000000..01461aec08d --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_mask.c @@ -0,0 +1,101 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_mask.c + * \ingroup cmpnodes + */ + +#include "BLF_translation.h" + +#include "DNA_mask_types.h" + +#include "BKE_mask.h" + +#include "node_composite_util.h" + +/* **************** Translate ******************** */ + +static bNodeSocketTemplate cmp_node_mask_in[] = { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate cmp_node_mask_out[] = { + { SOCK_RGBA, 0, "Image"}, + { -1, 0, "" } +}; + +static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + if (node->id) { + Mask *mask = (Mask *)node->id; + CompBuf *stackbuf; + RenderData *rd = data; + float *res; + int sx, sy; + + if (!out[0]->hasoutput) { + /* the node's output socket is not connected to anything... + * do not execute any further, just exit the node immediately + */ + return; + } + + if (in[0]->hasinput && in[0]->data) { + CompBuf *cbuf = typecheck_compbuf(in[0]->data, CB_RGBA); + + sx = cbuf->x; + sy = cbuf->y; + } + else { + sx = (rd->size * rd->xsch) / 100; + sy = (rd->size * rd->ysch) / 100; + } + + /* allocate the output buffer */ + stackbuf = alloc_compbuf(sx, sy, CB_VAL, TRUE); + res = stackbuf->rect; + + BKE_mask_rasterize(mask, sx, sy, res, TRUE, TRUE); + + /* pass on output and free */ + out[0]->data = stackbuf; + } +} + +void register_node_type_cmp_mask(bNodeTreeType *ttype) +{ + static bNodeType ntype; + + node_type_base(ttype, &ntype, CMP_NODE_MASK, "Mask", NODE_CLASS_INPUT, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_mask_in, cmp_node_mask_out); + node_type_size(&ntype, 140, 100, 320); + node_type_exec(&ntype, exec); + + nodeRegisterType(ttype, &ntype); +} diff --git a/source/blender/nodes/composite/nodes/node_composite_math.c b/source/blender/nodes/composite/nodes/node_composite_math.c index 9ceee3feab1..7cf337f2f88 100644 --- a/source/blender/nodes/composite/nodes/node_composite_math.c +++ b/source/blender/nodes/composite/nodes/node_composite_math.c @@ -180,12 +180,12 @@ static void node_composit_exec_math(void *UNUSED(data), bNode *node, bNodeStack return; } - /*create output based on first input */ + /* create output based on first input */ if (cbuf) { stackbuf=alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); } /* and if it doesn't exist use the second input since we - know that one of them must exist at this point*/ + * know that one of them must exist at this point*/ else { stackbuf=alloc_compbuf(cbuf2->x, cbuf2->y, CB_VAL, 1); } diff --git a/source/blender/nodes/composite/nodes/node_composite_switch.c b/source/blender/nodes/composite/nodes/node_composite_switch.c index 8c2c2746593..258fac18c11 100644 --- a/source/blender/nodes/composite/nodes/node_composite_switch.c +++ b/source/blender/nodes/composite/nodes/node_composite_switch.c @@ -27,7 +27,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/nodes/intern/CMP_nodes/CMP_switch.c +/** \file blender/nodes/composite/nodes/node_composite_switch.c * \ingroup cmpnodes */ diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index 9f458678ae0..3d1b656fc4e 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -857,7 +857,7 @@ ListBase node_reroute_internal_connect(bNodeTree *ntree, bNode *node) ret.first = ret.last = NULL; /* Security check! */ - if(!ntree) + if (!ntree) return ret; link = MEM_callocN(sizeof(bNodeLink), "internal node link"); diff --git a/source/blender/nodes/shader/nodes/node_shader_particle_info.c b/source/blender/nodes/shader/nodes/node_shader_particle_info.c new file mode 100644 index 00000000000..6456742e22b --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_particle_info.c @@ -0,0 +1,48 @@ +/* + * ***** 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) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../node_shader_util.h" + +static bNodeSocketTemplate outputs[] = { + { SOCK_FLOAT, 0, "Age" }, + { SOCK_FLOAT, 0, "Lifetime" }, + { -1, 0, "" } +}; + +/* node type definition */ +void register_node_type_sh_particle_info(bNodeTreeType *ttype) +{ + static bNodeType ntype; + + node_type_base(ttype, &ntype, SH_NODE_PARTICLE_INFO, "Particle Info", NODE_CLASS_INPUT, 0); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_socket_templates(&ntype, NULL, outputs); + node_type_size(&ntype, 150, 60, 200); + + nodeRegisterType(ttype, &ntype); +} + diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c index e5dc64aca05..e3300c89a01 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c @@ -46,6 +46,10 @@ static void node_shader_init_tex_environment(bNodeTree *UNUSED(ntree), bNode* no default_color_mapping(&tex->base.color_mapping); tex->color_space = SHD_COLORSPACE_COLOR; tex->projection = SHD_PROJ_EQUIRECTANGULAR; + tex->iuser.frames= 1; + tex->iuser.sfra= 1; + tex->iuser.fie_ima= 2; + tex->iuser.ok= 1; node->storage = tex; } diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c index db1c9081471..d4d43c1430c 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c @@ -46,6 +46,10 @@ static void node_shader_init_tex_image(bNodeTree *UNUSED(ntree), bNode* node, bN default_tex_mapping(&tex->base.tex_mapping); default_color_mapping(&tex->base.color_mapping); tex->color_space = SHD_COLORSPACE_COLOR; + tex->iuser.frames= 1; + tex->iuser.sfra= 1; + tex->iuser.fie_ima= 2; + tex->iuser.ok= 1; node->storage = tex; } diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 6ca4ad15859..053dac71fe6 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -2099,7 +2099,7 @@ static struct PyMethodDef bpy_bmesh_methods[] = { {"select_flush_mode", (PyCFunction)bpy_bmesh_select_flush_mode, METH_NOARGS, bpy_bmesh_select_flush_mode_doc}, {"select_flush", (PyCFunction)bpy_bmesh_select_flush, METH_O, bpy_bmesh_select_flush_doc}, {"normal_update", (PyCFunction)bpy_bmesh_normal_update, METH_VARARGS, bpy_bmesh_normal_update_doc}, - {"transform", (PyCFunction)bpy_bmesh_transform, METH_VARARGS|METH_KEYWORDS, bpy_bmesh_transform_doc}, + {"transform", (PyCFunction)bpy_bmesh_transform, METH_VARARGS | METH_KEYWORDS, bpy_bmesh_transform_doc}, {NULL, NULL, 0, NULL} }; @@ -2141,7 +2141,7 @@ static struct PyMethodDef bpy_bmface_methods[] = { {"copy_from", (PyCFunction)bpy_bm_elem_copy_from, METH_O, bpy_bm_elem_copy_from_doc}, {"copy_from_face_interp", (PyCFunction)bpy_bmface_copy_from_face_interp, METH_O, bpy_bmface_copy_from_face_interp_doc}, - {"copy", (PyCFunction)bpy_bmface_copy, METH_VARARGS|METH_KEYWORDS, bpy_bmface_copy_doc}, + {"copy", (PyCFunction)bpy_bmface_copy, METH_VARARGS | METH_KEYWORDS, bpy_bmface_copy_doc}, {"calc_area", (PyCFunction)bpy_bmface_calc_area, METH_NOARGS, bpy_bmface_calc_area_doc}, {"calc_perimeter", (PyCFunction)bpy_bmface_calc_perimeter, METH_NOARGS, bpy_bmface_calc_perimeter_doc}, diff --git a/source/blender/python/bmesh/bmesh_py_utils.c b/source/blender/python/bmesh/bmesh_py_utils.c index 9fecc0cdeda..374a01c51f8 100644 --- a/source/blender/python/bmesh/bmesh_py_utils.c +++ b/source/blender/python/bmesh/bmesh_py_utils.c @@ -23,7 +23,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/python/bmesh/bmesh_py_api.c +/** \file blender/python/bmesh/bmesh_py_utils.c * \ingroup pybmesh * * This file defines the 'bmesh.utils' module. diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 0c88c7d9c81..ac9ff4c8ef5 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -421,7 +421,7 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, fclose(fp); - pystring = MEM_mallocN(strlen(fn) + 36, "pystring"); + pystring = MEM_mallocN(strlen(fn) + 37, "pystring"); pystring[0] = '\0'; sprintf(pystring, "f=open(r'%s');exec(f.read());f.close()", fn); py_result = PyRun_String(pystring, Py_file_input, py_dict, py_dict); @@ -537,7 +537,12 @@ int BPY_button_exec(bContext *C, const char *expr, double *value, const short ve val = 0.0; for (i = 0; i < PyTuple_GET_SIZE(retval); i++) { - val += PyFloat_AsDouble(PyTuple_GET_ITEM(retval, i)); + const double val_item = PyFloat_AsDouble(PyTuple_GET_ITEM(retval, i)); + if (val_item == -1 && PyErr_Occurred()) { + val = -1; + break; + } + val += val_item; } } else { diff --git a/source/blender/python/intern/bpy_library.c b/source/blender/python/intern/bpy_library.c index 1d02acbe983..d34bdfe9448 100644 --- a/source/blender/python/intern/bpy_library.c +++ b/source/blender/python/intern/bpy_library.c @@ -170,18 +170,18 @@ static PyTypeObject bpy_lib_Type = { }; PyDoc_STRVAR(bpy_lib_load_doc, - ".. method:: load(filepath, link=False, relative=False)\n" - "\n" - " Returns a context manager which exposes 2 library objects on entering.\n" - " Each object has attributes matching bpy.data which are lists of strings to be linked.\n" - "\n" - " :arg filepath: The path to a blend file.\n" - " :type filepath: string\n" - " :arg link: When False reference to the original file is lost.\n" - " :type link: bool\n" - " :arg relative: When True the path is stored relative to the open blend file.\n" - " :type relative: bool\n" - ); +".. method:: load(filepath, link=False, relative=False)\n" +"\n" +" Returns a context manager which exposes 2 library objects on entering.\n" +" Each object has attributes matching bpy.data which are lists of strings to be linked.\n" +"\n" +" :arg filepath: The path to a blend file.\n" +" :type filepath: string\n" +" :arg link: When False reference to the original file is lost.\n" +" :type link: bool\n" +" :arg relative: When True the path is stored relative to the open blend file.\n" +" :type relative: bool\n" +); static PyObject *bpy_lib_load(PyObject *UNUSED(self), PyObject *args, PyObject *kwds) { static const char *kwlist[] = {"filepath", "link", "relative", NULL}; diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 6ad1874297f..04f9a90f0d2 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -591,7 +591,7 @@ static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_ /* note that PROP_NONE is included as a vector subtype. this is because its handy to * have x/y access to fcurve keyframes and other fixed size float arrays of length 2-4. */ #define PROP_ALL_VECTOR_SUBTYPES \ - PROP_COORDS: \ + PROP_COORDS: \ case PROP_TRANSLATION: \ case PROP_DIRECTION: \ case PROP_VELOCITY: \ @@ -3467,7 +3467,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) ret = pyrna_prop_to_py(&self->ptr, prop); } /* RNA function only if callback is declared (no optional functions) */ - else if ((func = RNA_struct_find_function(&self->ptr, name)) && RNA_function_defined(func)) { + else if ((func = RNA_struct_find_function(self->ptr.type, name)) && RNA_function_defined(func)) { ret = pyrna_func_to_py(&self->ptr, func); } else if (self->ptr.type == &RNA_Context) { @@ -3780,7 +3780,7 @@ static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject return ret; } - else if ((func = RNA_struct_find_function(&r_ptr, name))) { + else if ((func = RNA_struct_find_function(r_ptr.type, name))) { PyObject *self_collection = pyrna_struct_CreatePyObject(&r_ptr); ret = pyrna_func_to_py(&((BPy_DummyPointerRNA *)self_collection)->ptr, func); Py_DECREF(self_collection); diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c index c6bfeff1651..4d05b837952 100644 --- a/source/blender/python/mathutils/mathutils_geometry.c +++ b/source/blender/python/mathutils/mathutils_geometry.c @@ -807,6 +807,7 @@ PyDoc_STRVAR(M_Geometry_intersect_point_quad_2d_doc, "\n" " Takes 5 vectors (using only the x and y coordinates): one is the point and the next 4 define the quad, \n" " only the x and y are used from the vectors. Returns 1 if the point is within the quad, otherwise 0.\n" +" Works only with convex quads without singular edges." "\n" " :arg pt: Point\n" " :type pt: :class:`mathutils.Vector`\n" diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index cf9e6f7966f..26a1b9908b3 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -45,8 +45,7 @@ typedef struct TexResult { } TexResult; /* localized shade result data */ -typedef struct ShadeResult -{ +typedef struct ShadeResult { float combined[4]; float col[4]; float alpha, mist, z; @@ -95,8 +94,7 @@ typedef struct ShadeInputCol { } ShadeInputCol; /* localized renderloop data */ -typedef struct ShadeInput -{ +typedef struct ShadeInput { /* copy from face, also to extract tria from quad */ /* note it mirrors a struct above for quick copy */ diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 406c8e08f0d..c8c8eb1fc06 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -65,16 +65,14 @@ struct Main; #define TABLEINITSIZE 1024 #define LAMPINITSIZE 256 -typedef struct SampleTables -{ +typedef struct SampleTables { float centLut[16]; float *fmask1[9], *fmask2[9]; char cmask[256], *centmask; } SampleTables; -typedef struct QMCSampler -{ +typedef struct QMCSampler { struct QMCSampler *next, *prev; int type; int tot; @@ -88,8 +86,7 @@ typedef struct QMCSampler #define SAMP_TYPE_HAMMERSLEY 2 /* this is handed over to threaded hiding/passes/shading engine */ -typedef struct RenderPart -{ +typedef struct RenderPart { struct RenderPart *next, *prev; RenderResult *result; /* result of part rendering */ @@ -349,8 +346,7 @@ typedef struct ObjectInstanceRen { /* ------------------------------------------------------------------------- */ -typedef struct VertRen -{ +typedef struct VertRen { float co[3]; float n[3]; float *orco; @@ -387,8 +383,7 @@ typedef struct VlakRen { int index; } VlakRen; -typedef struct HaloRen -{ +typedef struct HaloRen { short miny, maxy; float alfa, xs, ys, rad, radsq, sin, cos, co[3], no[3]; float hard, b, g, r; @@ -459,8 +454,7 @@ typedef struct StrandRen { /* ------------------------------------------------------------------------- */ -typedef struct VolumeOb -{ +typedef struct VolumeOb { struct VolumeOb *next, *prev; struct Material *ma; struct ObjectRen *obr; @@ -472,8 +466,7 @@ typedef struct MatInside { struct ObjectInstanceRen *obi; } MatInside; -typedef struct VolPrecachePart -{ +typedef struct VolPrecachePart { struct VolPrecachePart *next, *prev; struct RayObject *tree; struct ShadeInput *shi; @@ -489,8 +482,7 @@ typedef struct VolPrecachePart struct Render *re; } VolPrecachePart; -typedef struct VolumePrecache -{ +typedef struct VolumePrecache { int res[3]; float *bbmin, *bbmax; float *data_r; diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h index 284b386ca33..0fbbf52e613 100644 --- a/source/blender/render/intern/include/rendercore.h +++ b/source/blender/render/intern/include/rendercore.h @@ -46,16 +46,14 @@ struct RayObject; /* ------------------------------------------------------------------------- */ -typedef struct PixStr -{ +typedef struct PixStr { struct PixStr *next; int obi, facenr, z, maskz; unsigned short mask; short shadfac; } PixStr; -typedef struct PixStrMain -{ +typedef struct PixStrMain { struct PixStrMain *next, *prev; struct PixStr *ps; int counter; diff --git a/source/blender/render/intern/include/sunsky.h b/source/blender/render/intern/include/sunsky.h index 0afd9246150..4bb7d99ba16 100644 --- a/source/blender/render/intern/include/sunsky.h +++ b/source/blender/render/intern/include/sunsky.h @@ -31,8 +31,7 @@ #define SPECTRUM_START 350.0 #define SPECTRUM_END 800.0 -typedef struct SunSky -{ +typedef struct SunSky { short effect_type, skyblendtype, sky_colorspace; float turbidity; float theta, phi; diff --git a/source/blender/render/intern/include/voxeldata.h b/source/blender/render/intern/include/voxeldata.h index 63620331c85..dd2262e0357 100644 --- a/source/blender/render/intern/include/voxeldata.h +++ b/source/blender/render/intern/include/voxeldata.h @@ -35,8 +35,7 @@ struct Render; struct TexResult; -typedef struct VoxelDataHeader -{ +typedef struct VoxelDataHeader { int resolX, resolY, resolZ; int frames; } VoxelDataHeader; diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h index 77cee59a83a..cdf171443d7 100644 --- a/source/blender/render/intern/include/zbuf.h +++ b/source/blender/render/intern/include/zbuf.h @@ -80,8 +80,7 @@ typedef struct APixstrand { struct APixstrand *next; } APixstrand; -typedef struct APixstrMain -{ +typedef struct APixstrMain { struct APixstrMain *next, *prev; void *ps; } APixstrMain; diff --git a/source/blender/render/intern/raytrace/rayobject_instance.cpp b/source/blender/render/intern/raytrace/rayobject_instance.cpp index ce88bac1587..92a412103ba 100644 --- a/source/blender/render/intern/raytrace/rayobject_instance.cpp +++ b/source/blender/render/intern/raytrace/rayobject_instance.cpp @@ -62,8 +62,7 @@ static RayObjectAPI instance_api = RE_rayobject_instance_hint_bb }; -typedef struct InstanceRayObject -{ +typedef struct InstanceRayObject { RayObject rayobj; RayObject *target; diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp index dc7b6dd6e8d..538c5493282 100644 --- a/source/blender/render/intern/raytrace/rayobject_octree.cpp +++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp @@ -51,18 +51,15 @@ #define BRANCH_ARRAY 1024 #define NODE_ARRAY 4096 -typedef struct Branch -{ +typedef struct Branch { struct Branch *b[8]; } Branch; -typedef struct OcVal -{ +typedef struct OcVal { short ocx, ocy, ocz; } OcVal; -typedef struct Node -{ +typedef struct Node { struct RayFace *v[8]; struct OcVal ov[8]; struct Node *next; @@ -73,7 +70,7 @@ typedef struct Octree { struct Branch **adrbranch; struct Node **adrnode; - float ocsize; /* ocsize: mult factor, max size octree */ + float ocsize; /* ocsize: mult factor, max size octree */ float ocfacx, ocfacy, ocfacz; float min[3], max[3]; int ocres; @@ -121,8 +118,8 @@ static RayObjectAPI octree_api = /* **************** ocval method ******************* */ /* within one octree node, a set of 3x15 bits defines a 'boundbox' to OR with */ -#define OCVALRES 15 -#define BROW16(min, max) (((max)>=OCVALRES? 0xFFFF: (1<<(max+1))-1) - ((min>0)? ((1<<(min))-1):0) ) +#define OCVALRES 15 +#define BROW16(min, max) (((max) >= OCVALRES ? 0xFFFF : (1 << (max + 1)) - 1) - ((min > 0) ? ((1 << (min)) - 1) : 0)) static void calc_ocval_face(float *v1, float *v2, float *v3, float *v4, short x, short y, short z, OcVal *ov) { @@ -137,17 +134,17 @@ static void calc_ocval_face(float *v1, float *v2, float *v3, float *v4, short x, DO_MINMAX(v4, min, max); } - ocmin= OCVALRES*(min[0]-x); - ocmax= OCVALRES*(max[0]-x); - ov->ocx= BROW16(ocmin, ocmax); - - ocmin= OCVALRES*(min[1]-y); - ocmax= OCVALRES*(max[1]-y); - ov->ocy= BROW16(ocmin, ocmax); - - ocmin= OCVALRES*(min[2]-z); - ocmax= OCVALRES*(max[2]-z); - ov->ocz= BROW16(ocmin, ocmax); + ocmin = OCVALRES * (min[0] - x); + ocmax = OCVALRES * (max[0] - x); + ov->ocx = BROW16(ocmin, ocmax); + + ocmin = OCVALRES * (min[1] - y); + ocmax = OCVALRES * (max[1] - y); + ov->ocy = BROW16(ocmin, ocmax); + + ocmin = OCVALRES * (min[2] - z); + ocmax = OCVALRES * (max[2] - z); + ov->ocz = BROW16(ocmin, ocmax); } @@ -155,35 +152,35 @@ static void calc_ocval_ray(OcVal *ov, float xo, float yo, float zo, float *vec1, { int ocmin, ocmax; - if (vec1[0]<vec2[0]) { - ocmin= OCVALRES*(vec1[0] - xo); - ocmax= OCVALRES*(vec2[0] - xo); + if (vec1[0] < vec2[0]) { + ocmin = OCVALRES * (vec1[0] - xo); + ocmax = OCVALRES * (vec2[0] - xo); } else { - ocmin= OCVALRES*(vec2[0] - xo); - ocmax= OCVALRES*(vec1[0] - xo); + ocmin = OCVALRES * (vec2[0] - xo); + ocmax = OCVALRES * (vec1[0] - xo); } - ov->ocx= BROW16(ocmin, ocmax); + ov->ocx = BROW16(ocmin, ocmax); - if (vec1[1]<vec2[1]) { - ocmin= OCVALRES*(vec1[1] - yo); - ocmax= OCVALRES*(vec2[1] - yo); + if (vec1[1] < vec2[1]) { + ocmin = OCVALRES * (vec1[1] - yo); + ocmax = OCVALRES * (vec2[1] - yo); } else { - ocmin= OCVALRES*(vec2[1] - yo); - ocmax= OCVALRES*(vec1[1] - yo); + ocmin = OCVALRES * (vec2[1] - yo); + ocmax = OCVALRES * (vec1[1] - yo); } - ov->ocy= BROW16(ocmin, ocmax); + ov->ocy = BROW16(ocmin, ocmax); - if (vec1[2]<vec2[2]) { - ocmin= OCVALRES*(vec1[2] - zo); - ocmax= OCVALRES*(vec2[2] - zo); + if (vec1[2] < vec2[2]) { + ocmin = OCVALRES * (vec1[2] - zo); + ocmax = OCVALRES * (vec2[2] - zo); } else { - ocmin= OCVALRES*(vec2[2] - zo); - ocmax= OCVALRES*(vec1[2] - zo); + ocmin = OCVALRES * (vec2[2] - zo); + ocmax = OCVALRES * (vec1[2] - zo); } - ov->ocz= BROW16(ocmin, ocmax); + ov->ocz = BROW16(ocmin, ocmax); } /* ************* octree ************** */ @@ -195,17 +192,17 @@ static Branch *addbranch(Octree *oc, Branch *br, short ocb) if (br->b[ocb]) return br->b[ocb]; oc->branchcount++; - index= oc->branchcount>>12; + index = oc->branchcount >> 12; - if (oc->adrbranch[index]==NULL) - oc->adrbranch[index]= (Branch*)MEM_callocN(4096*sizeof(Branch), "new oc branch"); + if (oc->adrbranch[index] == NULL) + oc->adrbranch[index] = (Branch *)MEM_callocN(4096 * sizeof(Branch), "new oc branch"); - if (oc->branchcount>= BRANCH_ARRAY*4096) { + if (oc->branchcount >= BRANCH_ARRAY * 4096) { printf("error; octree branches full\n"); - oc->branchcount=0; + oc->branchcount = 0; } - return br->b[ocb]= oc->adrbranch[index]+(oc->branchcount & 4095); + return br->b[ocb] = oc->adrbranch[index] + (oc->branchcount & 4095); } static Node *addnode(Octree *oc) @@ -213,17 +210,17 @@ static Node *addnode(Octree *oc) int index; oc->nodecount++; - index= oc->nodecount>>12; + index = oc->nodecount >> 12; - if (oc->adrnode[index]==NULL) - oc->adrnode[index]= (Node*)MEM_callocN(4096*sizeof(Node), "addnode"); + if (oc->adrnode[index] == NULL) + oc->adrnode[index] = (Node *)MEM_callocN(4096 * sizeof(Node), "addnode"); - if (oc->nodecount> NODE_ARRAY*NODE_ARRAY) { + if (oc->nodecount > NODE_ARRAY * NODE_ARRAY) { printf("error; octree nodes full\n"); - oc->nodecount=0; + oc->nodecount = 0; } - return oc->adrnode[index]+(oc->nodecount & 4095); + return oc->adrnode[index] + (oc->nodecount & 4095); } static int face_in_node(RayFace *face, short x, short y, short z, float rtf[][3]) @@ -234,33 +231,33 @@ static int face_in_node(RayFace *face, short x, short y, short z, float rtf[][3] // init static vars if (face) { normal_tri_v3(nor, rtf[0], rtf[1], rtf[2]); - d= -nor[0]*rtf[0][0] - nor[1]*rtf[0][1] - nor[2]*rtf[0][2]; + d = -nor[0] * rtf[0][0] - nor[1] * rtf[0][1] - nor[2] * rtf[0][2]; return 0; } - fx= x; - fy= y; - fz= z; - - if ((fx)*nor[0] + (fy)*nor[1] + (fz)*nor[2] + d > 0.0f) { - if ((fx+1)*nor[0] + (fy )*nor[1] + (fz )*nor[2] + d < 0.0f) return 1; - if ((fx )*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d < 0.0f) return 1; - if ((fx+1)*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d < 0.0f) return 1; - - if ((fx )*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1; - if ((fx+1)*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1; - if ((fx )*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1; - if ((fx+1)*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1; + fx = x; + fy = y; + fz = z; + + if ((fx) * nor[0] + (fy) * nor[1] + (fz) * nor[2] + d > 0.0f) { + if ((fx + 1) * nor[0] + (fy ) * nor[1] + (fz ) * nor[2] + d < 0.0f) return 1; + if ((fx ) * nor[0] + (fy + 1) * nor[1] + (fz ) * nor[2] + d < 0.0f) return 1; + if ((fx + 1) * nor[0] + (fy + 1) * nor[1] + (fz ) * nor[2] + d < 0.0f) return 1; + + if ((fx ) * nor[0] + (fy ) * nor[1] + (fz + 1) * nor[2] + d < 0.0f) return 1; + if ((fx + 1) * nor[0] + (fy ) * nor[1] + (fz + 1) * nor[2] + d < 0.0f) return 1; + if ((fx ) * nor[0] + (fy + 1) * nor[1] + (fz + 1) * nor[2] + d < 0.0f) return 1; + if ((fx + 1) * nor[0] + (fy + 1) * nor[1] + (fz + 1) * nor[2] + d < 0.0f) return 1; } else { - if ((fx+1)*nor[0] + (fy )*nor[1] + (fz )*nor[2] + d > 0.0f) return 1; - if ((fx )*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d > 0.0f) return 1; - if ((fx+1)*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d > 0.0f) return 1; - - if ((fx )*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1; - if ((fx+1)*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1; - if ((fx )*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1; - if ((fx+1)*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1; + if ((fx + 1) * nor[0] + (fy ) * nor[1] + (fz ) * nor[2] + d > 0.0f) return 1; + if ((fx ) * nor[0] + (fy + 1) * nor[1] + (fz ) * nor[2] + d > 0.0f) return 1; + if ((fx + 1) * nor[0] + (fy + 1) * nor[1] + (fz ) * nor[2] + d > 0.0f) return 1; + + if ((fx ) * nor[0] + (fy ) * nor[1] + (fz + 1) * nor[2] + d > 0.0f) return 1; + if ((fx + 1) * nor[0] + (fy ) * nor[1] + (fz + 1) * nor[2] + d > 0.0f) return 1; + if ((fx ) * nor[0] + (fy + 1) * nor[1] + (fz + 1) * nor[2] + d > 0.0f) return 1; + if ((fx + 1) * nor[0] + (fy + 1) * nor[1] + (fz + 1) * nor[2] + d > 0.0f) return 1; } return 0; @@ -272,163 +269,163 @@ static void ocwrite(Octree *oc, RayFace *face, int quad, short x, short y, short Node *no; short a, oc0, oc1, oc2, oc3, oc4, oc5; - x<<=2; - y<<=1; + x <<= 2; + y <<= 1; - br= oc->adrbranch[0]; + br = oc->adrbranch[0]; - if (oc->ocres==512) { - oc0= ((x & 1024)+(y & 512)+(z & 256))>>8; - br= addbranch(oc, br, oc0); + if (oc->ocres == 512) { + oc0 = ((x & 1024) + (y & 512) + (z & 256)) >> 8; + br = addbranch(oc, br, oc0); } - if (oc->ocres>=256) { - oc0= ((x & 512)+(y & 256)+(z & 128))>>7; - br= addbranch(oc, br, oc0); + if (oc->ocres >= 256) { + oc0 = ((x & 512) + (y & 256) + (z & 128)) >> 7; + br = addbranch(oc, br, oc0); } - if (oc->ocres>=128) { - oc0= ((x & 256)+(y & 128)+(z & 64))>>6; - br= addbranch(oc, br, oc0); + if (oc->ocres >= 128) { + oc0 = ((x & 256) + (y & 128) + (z & 64)) >> 6; + br = addbranch(oc, br, oc0); } - oc0= ((x & 128)+(y & 64)+(z & 32))>>5; - oc1= ((x & 64)+(y & 32)+(z & 16))>>4; - oc2= ((x & 32)+(y & 16)+(z & 8))>>3; - oc3= ((x & 16)+(y & 8)+(z & 4))>>2; - oc4= ((x & 8)+(y & 4)+(z & 2))>>1; - oc5= ((x & 4)+(y & 2)+(z & 1)); - - br= addbranch(oc, br, oc0); - br= addbranch(oc, br, oc1); - br= addbranch(oc, br, oc2); - br= addbranch(oc, br, oc3); - br= addbranch(oc, br, oc4); - no= (Node *)br->b[oc5]; - if (no==NULL) br->b[oc5]= (Branch *)(no= addnode(oc)); + oc0 = ((x & 128) + (y & 64) + (z & 32)) >> 5; + oc1 = ((x & 64) + (y & 32) + (z & 16)) >> 4; + oc2 = ((x & 32) + (y & 16) + (z & 8)) >> 3; + oc3 = ((x & 16) + (y & 8) + (z & 4)) >> 2; + oc4 = ((x & 8) + (y & 4) + (z & 2)) >> 1; + oc5 = ((x & 4) + (y & 2) + (z & 1)); + + br = addbranch(oc, br, oc0); + br = addbranch(oc, br, oc1); + br = addbranch(oc, br, oc2); + br = addbranch(oc, br, oc3); + br = addbranch(oc, br, oc4); + no = (Node *)br->b[oc5]; + if (no == NULL) br->b[oc5] = (Branch *)(no = addnode(oc)); while (no->next) no = no->next; - a= 0; - if (no->v[7]) { /* node full */ - no->next= addnode(oc); - no= no->next; + a = 0; + if (no->v[7]) { /* node full */ + no->next = addnode(oc); + no = no->next; } else { while (no->v[a] != NULL) a++; } - no->v[a]= (RayFace*) RE_rayobject_align(face); + no->v[a] = (RayFace *) RE_rayobject_align(face); if (quad) - calc_ocval_face(rtf[0], rtf[1], rtf[2], rtf[3], x>>2, y>>1, z, &no->ov[a]); + calc_ocval_face(rtf[0], rtf[1], rtf[2], rtf[3], x >> 2, y >> 1, z, &no->ov[a]); else - calc_ocval_face(rtf[0], rtf[1], rtf[2], NULL, x>>2, y>>1, z, &no->ov[a]); + calc_ocval_face(rtf[0], rtf[1], rtf[2], NULL, x >> 2, y >> 1, z, &no->ov[a]); } static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocface, short rts[][3], float rtf[][3]) { int ocx1, ocx2, ocy1, ocy2; - int x, y, dx=0, dy=0; + int x, y, dx = 0, dy = 0; float ox1, ox2, oy1, oy2; float labda, labdao, labdax, labday, ldx, ldy; - ocx1= rts[b1][c1]; - ocy1= rts[b1][c2]; - ocx2= rts[b2][c1]; - ocy2= rts[b2][c2]; + ocx1 = rts[b1][c1]; + ocy1 = rts[b1][c2]; + ocx2 = rts[b2][c1]; + ocy2 = rts[b2][c2]; - if (ocx1==ocx2 && ocy1==ocy2) { - ocface[oc->ocres*ocx1+ocy1]= 1; + if (ocx1 == ocx2 && ocy1 == ocy2) { + ocface[oc->ocres * ocx1 + ocy1] = 1; return; } - ox1= rtf[b1][c1]; - oy1= rtf[b1][c2]; - ox2= rtf[b2][c1]; - oy2= rtf[b2][c2]; + ox1 = rtf[b1][c1]; + oy1 = rtf[b1][c2]; + ox2 = rtf[b2][c1]; + oy2 = rtf[b2][c2]; - if (ox1!=ox2) { - if (ox2-ox1>0.0f) { - labdax= (ox1-ocx1-1.0f)/(ox1-ox2); - ldx= -1.0f/(ox1-ox2); - dx= 1; + if (ox1 != ox2) { + if (ox2 - ox1 > 0.0f) { + labdax = (ox1 - ocx1 - 1.0f) / (ox1 - ox2); + ldx = -1.0f / (ox1 - ox2); + dx = 1; } else { - labdax= (ox1-ocx1)/(ox1-ox2); - ldx= 1.0f/(ox1-ox2); - dx= -1; + labdax = (ox1 - ocx1) / (ox1 - ox2); + ldx = 1.0f / (ox1 - ox2); + dx = -1; } } else { - labdax=1.0f; - ldx=0; + labdax = 1.0f; + ldx = 0; } - if (oy1!=oy2) { - if (oy2-oy1>0.0f) { - labday= (oy1-ocy1-1.0f)/(oy1-oy2); - ldy= -1.0f/(oy1-oy2); - dy= 1; + if (oy1 != oy2) { + if (oy2 - oy1 > 0.0f) { + labday = (oy1 - ocy1 - 1.0f) / (oy1 - oy2); + ldy = -1.0f / (oy1 - oy2); + dy = 1; } else { - labday= (oy1-ocy1)/(oy1-oy2); - ldy= 1.0f/(oy1-oy2); - dy= -1; + labday = (oy1 - ocy1) / (oy1 - oy2); + ldy = 1.0f / (oy1 - oy2); + dy = -1; } } else { - labday=1.0f; - ldy=0; + labday = 1.0f; + ldy = 0; } - x=ocx1; y=ocy1; - labda= MIN2(labdax, labday); + x = ocx1; y = ocy1; + labda = MIN2(labdax, labday); while (TRUE) { - if (x<0 || y<0 || x>=oc->ocres || y>=oc->ocres); - else ocface[oc->ocres*x+y]= 1; + if (x < 0 || y < 0 || x >= oc->ocres || y >= oc->ocres) ; + else ocface[oc->ocres * x + y] = 1; - labdao=labda; - if (labdax==labday) { - labdax+=ldx; - x+=dx; - labday+=ldy; - y+=dy; + labdao = labda; + if (labdax == labday) { + labdax += ldx; + x += dx; + labday += ldy; + y += dy; } else { - if (labdax<labday) { - labdax+=ldx; - x+=dx; + if (labdax < labday) { + labdax += ldx; + x += dx; } else { - labday+=ldy; - y+=dy; + labday += ldy; + y += dy; } } - labda=MIN2(labdax, labday); - if (labda==labdao) break; - if (labda>=1.0f) break; + labda = MIN2(labdax, labday); + if (labda == labdao) break; + if (labda >= 1.0f) break; } - ocface[oc->ocres*ocx2+ocy2]=1; + ocface[oc->ocres * ocx2 + ocy2] = 1; } static void filltriangle(Octree *oc, short c1, short c2, char *ocface, short *ocmin, short *ocmax) { int a, x, y, y1, y2; - for (x=ocmin[c1];x<=ocmax[c1];x++) { - a= oc->ocres*x; - for (y=ocmin[c2];y<=ocmax[c2];y++) { - if (ocface[a+y]) { + for (x = ocmin[c1]; x <= ocmax[c1]; x++) { + a = oc->ocres * x; + for (y = ocmin[c2]; y <= ocmax[c2]; y++) { + if (ocface[a + y]) { y++; - while (ocface[a+y] && y!=ocmax[c2]) y++; - for (y1=ocmax[c2];y1>y;y1--) { - if (ocface[a+y1]) { - for (y2=y;y2<=y1;y2++) ocface[a+y2]=1; - y1=0; + while (ocface[a + y] && y != ocmax[c2]) y++; + for (y1 = ocmax[c2]; y1 > y; y1--) { + if (ocface[a + y1]) { + for (y2 = y; y2 <= y1; y2++) ocface[a + y2] = 1; + y1 = 0; } } - y=ocmax[c2]; + y = ocmax[c2]; } } } @@ -436,7 +433,7 @@ static void filltriangle(Octree *oc, short c1, short c2, char *ocface, short *oc static void RE_rayobject_octree_free(RayObject *tree) { - Octree *oc= (Octree*)tree; + Octree *oc = (Octree *)tree; #if 0 printf("branches %d nodes %d\n", oc->branchcount, oc->nodecount); @@ -448,28 +445,28 @@ static void RE_rayobject_octree_free(RayObject *tree) MEM_freeN(oc->ocface); if (oc->adrbranch) { - int a= 0; + int a = 0; while (oc->adrbranch[a]) { MEM_freeN(oc->adrbranch[a]); - oc->adrbranch[a]= NULL; + oc->adrbranch[a] = NULL; a++; } MEM_freeN(oc->adrbranch); - oc->adrbranch= NULL; + oc->adrbranch = NULL; } - oc->branchcount= 0; + oc->branchcount = 0; if (oc->adrnode) { - int a= 0; + int a = 0; while (oc->adrnode[a]) { MEM_freeN(oc->adrnode[a]); - oc->adrnode[a]= NULL; + oc->adrnode[a] = NULL; a++; } MEM_freeN(oc->adrnode); - oc->adrnode= NULL; + oc->adrnode = NULL; } - oc->nodecount= 0; + oc->nodecount = 0; MEM_freeN(oc); } @@ -477,29 +474,29 @@ static void RE_rayobject_octree_free(RayObject *tree) RayObject *RE_rayobject_octree_create(int ocres, int size) { - Octree *oc= (Octree*)MEM_callocN(sizeof(Octree), "Octree"); - assert( RE_rayobject_isAligned(oc) ); /* RayObject API assumes real data to be 4-byte aligned */ + Octree *oc = (Octree *)MEM_callocN(sizeof(Octree), "Octree"); + assert(RE_rayobject_isAligned(oc) ); /* RayObject API assumes real data to be 4-byte aligned */ oc->rayobj.api = &octree_api; oc->ocres = ocres; - oc->ro_nodes = (RayFace**)MEM_callocN(sizeof(RayFace*)*size, "octree rayobject nodes"); + oc->ro_nodes = (RayFace **)MEM_callocN(sizeof(RayFace *) * size, "octree rayobject nodes"); oc->ro_nodes_size = size; oc->ro_nodes_used = 0; - return RE_rayobject_unalignRayAPI((RayObject*) oc); + return RE_rayobject_unalignRayAPI((RayObject *) oc); } static void RE_rayobject_octree_add(RayObject *tree, RayObject *node) { - Octree *oc = (Octree*)tree; + Octree *oc = (Octree *)tree; - assert( RE_rayobject_isRayFace(node) ); - assert( oc->ro_nodes_used < oc->ro_nodes_size ); - oc->ro_nodes[ oc->ro_nodes_used++ ] = (RayFace*)RE_rayobject_align(node); + assert(RE_rayobject_isRayFace(node) ); + assert(oc->ro_nodes_used < oc->ro_nodes_size); + oc->ro_nodes[oc->ro_nodes_used++] = (RayFace *)RE_rayobject_align(node); } static void octree_fill_rayface(Octree *oc, RayFace *face) @@ -508,14 +505,14 @@ static void octree_fill_rayface(Octree *oc, RayFace *face) float co1[3], co2[3], co3[3], co4[3]; short rts[4][3]; short ocmin[3], ocmax[3]; - char *ocface= oc->ocface; // front, top, size view of face, to fill in + char *ocface = oc->ocface; // front, top, size view of face, to fill in int a, b, c, oc1, oc2, oc3, oc4, x, y, z, ocres2; - ocfac[0]= oc->ocfacx; - ocfac[1]= oc->ocfacy; - ocfac[2]= oc->ocfacz; + ocfac[0] = oc->ocfacx; + ocfac[1] = oc->ocfacy; + ocfac[2] = oc->ocfacz; - ocres2= oc->ocres*oc->ocres; + ocres2 = oc->ocres * oc->ocres; copy_v3_v3(co1, face->v1); copy_v3_v3(co2, face->v2); @@ -523,7 +520,7 @@ static void octree_fill_rayface(Octree *oc, RayFace *face) if (face->v4) copy_v3_v3(co4, face->v4); - for (c=0;c<3;c++) { + for (c = 0; c < 3; c++) { rtf[0][c] = (co1[c] - oc->min[c]) * ocfac[c]; rts[0][c] = (short)rtf[0][c]; rtf[1][c] = (co2[c] - oc->min[c]) * ocfac[c]; @@ -536,62 +533,62 @@ static void octree_fill_rayface(Octree *oc, RayFace *face) } } - for (c=0;c<3;c++) { - oc1= rts[0][c]; - oc2= rts[1][c]; - oc3= rts[2][c]; + for (c = 0; c < 3; c++) { + oc1 = rts[0][c]; + oc2 = rts[1][c]; + oc3 = rts[2][c]; if (!RE_rayface_isQuad(face)) { - ocmin[c]= MIN3(oc1, oc2, oc3); - ocmax[c]= MAX3(oc1, oc2, oc3); + ocmin[c] = MIN3(oc1, oc2, oc3); + ocmax[c] = MAX3(oc1, oc2, oc3); } else { - oc4= rts[3][c]; - ocmin[c]= MIN4(oc1, oc2, oc3, oc4); - ocmax[c]= MAX4(oc1, oc2, oc3, oc4); + oc4 = rts[3][c]; + ocmin[c] = MIN4(oc1, oc2, oc3, oc4); + ocmax[c] = MAX4(oc1, oc2, oc3, oc4); } - if (ocmax[c]>oc->ocres-1) ocmax[c]=oc->ocres-1; - if (ocmin[c]<0) ocmin[c]=0; + if (ocmax[c] > oc->ocres - 1) ocmax[c] = oc->ocres - 1; + if (ocmin[c] < 0) ocmin[c] = 0; } - if (ocmin[0]==ocmax[0] && ocmin[1]==ocmax[1] && ocmin[2]==ocmax[2]) { + if (ocmin[0] == ocmax[0] && ocmin[1] == ocmax[1] && ocmin[2] == ocmax[2]) { ocwrite(oc, face, RE_rayface_isQuad(face), ocmin[0], ocmin[1], ocmin[2], rtf); } else { - d2dda(oc, 0, 1, 0, 1, ocface+ocres2, rts, rtf); + d2dda(oc, 0, 1, 0, 1, ocface + ocres2, rts, rtf); d2dda(oc, 0, 1, 0, 2, ocface, rts, rtf); - d2dda(oc, 0, 1, 1, 2, ocface+2*ocres2, rts, rtf); - d2dda(oc, 1, 2, 0, 1, ocface+ocres2, rts, rtf); + d2dda(oc, 0, 1, 1, 2, ocface + 2 * ocres2, rts, rtf); + d2dda(oc, 1, 2, 0, 1, ocface + ocres2, rts, rtf); d2dda(oc, 1, 2, 0, 2, ocface, rts, rtf); - d2dda(oc, 1, 2, 1, 2, ocface+2*ocres2, rts, rtf); + d2dda(oc, 1, 2, 1, 2, ocface + 2 * ocres2, rts, rtf); if (!RE_rayface_isQuad(face)) { - d2dda(oc, 2, 0, 0, 1, ocface+ocres2, rts, rtf); + d2dda(oc, 2, 0, 0, 1, ocface + ocres2, rts, rtf); d2dda(oc, 2, 0, 0, 2, ocface, rts, rtf); - d2dda(oc, 2, 0, 1, 2, ocface+2*ocres2, rts, rtf); + d2dda(oc, 2, 0, 1, 2, ocface + 2 * ocres2, rts, rtf); } else { - d2dda(oc, 2, 3, 0, 1, ocface+ocres2, rts, rtf); + d2dda(oc, 2, 3, 0, 1, ocface + ocres2, rts, rtf); d2dda(oc, 2, 3, 0, 2, ocface, rts, rtf); - d2dda(oc, 2, 3, 1, 2, ocface+2*ocres2, rts, rtf); - d2dda(oc, 3, 0, 0, 1, ocface+ocres2, rts, rtf); + d2dda(oc, 2, 3, 1, 2, ocface + 2 * ocres2, rts, rtf); + d2dda(oc, 3, 0, 0, 1, ocface + ocres2, rts, rtf); d2dda(oc, 3, 0, 0, 2, ocface, rts, rtf); - d2dda(oc, 3, 0, 1, 2, ocface+2*ocres2, rts, rtf); + d2dda(oc, 3, 0, 1, 2, ocface + 2 * ocres2, rts, rtf); } /* nothing todo with triangle..., just fills :) */ - filltriangle(oc, 0, 1, ocface+ocres2, ocmin, ocmax); + filltriangle(oc, 0, 1, ocface + ocres2, ocmin, ocmax); filltriangle(oc, 0, 2, ocface, ocmin, ocmax); - filltriangle(oc, 1, 2, ocface+2*ocres2, ocmin, ocmax); + filltriangle(oc, 1, 2, ocface + 2 * ocres2, ocmin, ocmax); /* init static vars here */ face_in_node(face, 0, 0, 0, rtf); - for (x=ocmin[0];x<=ocmax[0];x++) { - a= oc->ocres*x; - for (y=ocmin[1];y<=ocmax[1];y++) { - if (ocface[a+y+ocres2]) { - b= oc->ocres*y+2*ocres2; - for (z=ocmin[2];z<=ocmax[2];z++) { - if (ocface[b+z] && ocface[a+z]) { + for (x = ocmin[0]; x <= ocmax[0]; x++) { + a = oc->ocres * x; + for (y = ocmin[1]; y <= ocmax[1]; y++) { + if (ocface[a + y + ocres2]) { + b = oc->ocres * y + 2 * ocres2; + for (z = ocmin[2]; z <= ocmax[2]; z++) { + if (ocface[b + z] && ocface[a + z]) { if (face_in_node(NULL, x, y, z, rtf)) ocwrite(oc, face, RE_rayface_isQuad(face), x, y, z, rtf); } @@ -601,18 +598,18 @@ static void octree_fill_rayface(Octree *oc, RayFace *face) } /* same loops to clear octree, doubt it can be done smarter */ - for (x=ocmin[0];x<=ocmax[0];x++) { - a= oc->ocres*x; - for (y=ocmin[1];y<=ocmax[1];y++) { + for (x = ocmin[0]; x <= ocmax[0]; x++) { + a = oc->ocres * x; + for (y = ocmin[1]; y <= ocmax[1]; y++) { /* x-y */ - ocface[a+y+ocres2]= 0; + ocface[a + y + ocres2] = 0; - b= oc->ocres*y + 2*ocres2; - for (z=ocmin[2];z<=ocmax[2];z++) { + b = oc->ocres * y + 2 * ocres2; + for (z = ocmin[2]; z <= ocmax[2]; z++) { /* y-z */ - ocface[b+z]= 0; + ocface[b + z] = 0; /* x-z */ - ocface[a+z]= 0; + ocface[a + z] = 0; } } } @@ -621,44 +618,44 @@ static void octree_fill_rayface(Octree *oc, RayFace *face) static void RE_rayobject_octree_done(RayObject *tree) { - Octree *oc = (Octree*)tree; + Octree *oc = (Octree *)tree; int c; float t00, t01, t02; - int ocres2 = oc->ocres*oc->ocres; + int ocres2 = oc->ocres * oc->ocres; INIT_MINMAX(oc->min, oc->max); /* Calculate Bounding Box */ - for (c=0; c<oc->ro_nodes_used; c++) - RE_rayobject_merge_bb( RE_rayobject_unalignRayFace(oc->ro_nodes[c]), oc->min, oc->max); + for (c = 0; c < oc->ro_nodes_used; c++) + RE_rayobject_merge_bb(RE_rayobject_unalignRayFace(oc->ro_nodes[c]), oc->min, oc->max); /* Alloc memory */ - oc->adrbranch= (Branch**)MEM_callocN(sizeof(void *)*BRANCH_ARRAY, "octree branches"); - oc->adrnode= (Node**)MEM_callocN(sizeof(void *)*NODE_ARRAY, "octree nodes"); + oc->adrbranch = (Branch **)MEM_callocN(sizeof(void *) * BRANCH_ARRAY, "octree branches"); + oc->adrnode = (Node **)MEM_callocN(sizeof(void *) * NODE_ARRAY, "octree nodes"); - oc->adrbranch[0]=(Branch *)MEM_callocN(4096*sizeof(Branch), "makeoctree"); + oc->adrbranch[0] = (Branch *)MEM_callocN(4096 * sizeof(Branch), "makeoctree"); /* the lookup table, per face, for which nodes to fill in */ - oc->ocface= (char*)MEM_callocN( 3*ocres2 + 8, "ocface"); - memset(oc->ocface, 0, 3*ocres2); + oc->ocface = (char *)MEM_callocN(3 * ocres2 + 8, "ocface"); + memset(oc->ocface, 0, 3 * ocres2); - for (c=0;c<3;c++) { /* octree enlarge, still needed? */ - oc->min[c]-= 0.01f; - oc->max[c]+= 0.01f; + for (c = 0; c < 3; c++) { /* octree enlarge, still needed? */ + oc->min[c] -= 0.01f; + oc->max[c] += 0.01f; } - t00= oc->max[0]-oc->min[0]; - t01= oc->max[1]-oc->min[1]; - t02= oc->max[2]-oc->min[2]; + t00 = oc->max[0] - oc->min[0]; + t01 = oc->max[1] - oc->min[1]; + t02 = oc->max[2] - oc->min[2]; /* this minus 0.1 is old safety... seems to be needed? */ - oc->ocfacx= (oc->ocres-0.1)/t00; - oc->ocfacy= (oc->ocres-0.1)/t01; - oc->ocfacz= (oc->ocres-0.1)/t02; + oc->ocfacx = (oc->ocres - 0.1) / t00; + oc->ocfacy = (oc->ocres - 0.1) / t01; + oc->ocfacz = (oc->ocres - 0.1) / t02; - oc->ocsize= sqrt(t00*t00+t01*t01+t02*t02); /* global, max size octree */ + oc->ocsize = sqrt(t00 * t00 + t01 * t01 + t02 * t02); /* global, max size octree */ - for (c=0; c<oc->ro_nodes_used; c++) { + for (c = 0; c < oc->ro_nodes_used; c++) { octree_fill_rayface(oc, oc->ro_nodes[c]); } @@ -667,14 +664,14 @@ static void RE_rayobject_octree_done(RayObject *tree) MEM_freeN(oc->ro_nodes); oc->ro_nodes = NULL; - printf("%f %f - %f\n", oc->min[0], oc->max[0], oc->ocfacx ); - printf("%f %f - %f\n", oc->min[1], oc->max[1], oc->ocfacy ); - printf("%f %f - %f\n", oc->min[2], oc->max[2], oc->ocfacz ); + printf("%f %f - %f\n", oc->min[0], oc->max[0], oc->ocfacx); + printf("%f %f - %f\n", oc->min[1], oc->max[1], oc->ocfacy); + printf("%f %f - %f\n", oc->min[2], oc->max[2], oc->ocfacz); } static void RE_rayobject_octree_bb(RayObject *tree, float *min, float *max) { - Octree *oc = (Octree*)tree; + Octree *oc = (Octree *)tree; DO_MINMAX(oc->min, min, max); DO_MINMAX(oc->max, min, max); } @@ -687,7 +684,7 @@ static int testnode(Octree *UNUSED(oc), Isect *is, Node *no, OcVal ocval) /* return on any first hit */ if (is->mode == RE_RAY_SHADOW) { - for ( ; no; no = no->next) { + for (; no; no = no->next) { for (nr = 0; nr < 8; nr++) { RayFace *face = no->v[nr]; OcVal *ov = no->ov + nr; @@ -695,7 +692,7 @@ static int testnode(Octree *UNUSED(oc), Isect *is, Node *no, OcVal ocval) if (!face) break; if ( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { - if ( RE_rayobject_intersect( RE_rayobject_unalignRayFace(face), is) ) + if (RE_rayobject_intersect(RE_rayobject_unalignRayFace(face), is) ) return 1; } } @@ -703,9 +700,9 @@ static int testnode(Octree *UNUSED(oc), Isect *is, Node *no, OcVal ocval) } else { /* else mirror or glass or shadowtra, return closest face */ - int found= 0; + int found = 0; - for ( ; no; no = no->next) { + for (; no; no = no->next) { for (nr = 0; nr < 8; nr++) { RayFace *face = no->v[nr]; OcVal *ov = no->ov + nr; @@ -713,7 +710,7 @@ static int testnode(Octree *UNUSED(oc), Isect *is, Node *no, OcVal ocval) if (!face) break; if ( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { - if ( RE_rayobject_intersect( RE_rayobject_unalignRayFace(face), is) ) { + if (RE_rayobject_intersect(RE_rayobject_unalignRayFace(face), is) ) { found = 1; } } @@ -732,49 +729,49 @@ static Node *ocread(Octree *oc, int x, int y, int z) Branch *br; int oc1; - x<<=2; - y<<=1; + x <<= 2; + y <<= 1; - br= oc->adrbranch[0]; + br = oc->adrbranch[0]; - if (oc->ocres==512) { - oc1= ((x & 1024)+(y & 512)+(z & 256))>>8; - br= br->b[oc1]; - if (br==NULL) { + if (oc->ocres == 512) { + oc1 = ((x & 1024) + (y & 512) + (z & 256)) >> 8; + br = br->b[oc1]; + if (br == NULL) { return NULL; } } - if (oc->ocres>=256) { - oc1= ((x & 512)+(y & 256)+(z & 128))>>7; - br= br->b[oc1]; - if (br==NULL) { + if (oc->ocres >= 256) { + oc1 = ((x & 512) + (y & 256) + (z & 128)) >> 7; + br = br->b[oc1]; + if (br == NULL) { return NULL; } } - if (oc->ocres>=128) { - oc1= ((x & 256)+(y & 128)+(z & 64))>>6; - br= br->b[oc1]; - if (br==NULL) { + if (oc->ocres >= 128) { + oc1 = ((x & 256) + (y & 128) + (z & 64)) >> 6; + br = br->b[oc1]; + if (br == NULL) { return NULL; } } - oc1= ((x & 128)+(y & 64)+(z & 32))>>5; - br= br->b[oc1]; + oc1 = ((x & 128) + (y & 64) + (z & 32)) >> 5; + br = br->b[oc1]; if (br) { - oc1= ((x & 64)+(y & 32)+(z & 16))>>4; - br= br->b[oc1]; + oc1 = ((x & 64) + (y & 32) + (z & 16)) >> 4; + br = br->b[oc1]; if (br) { - oc1= ((x & 32)+(y & 16)+(z & 8))>>3; - br= br->b[oc1]; + oc1 = ((x & 32) + (y & 16) + (z & 8)) >> 3; + br = br->b[oc1]; if (br) { - oc1= ((x & 16)+(y & 8)+(z & 4))>>2; - br= br->b[oc1]; + oc1 = ((x & 16) + (y & 8) + (z & 4)) >> 2; + br = br->b[oc1]; if (br) { - oc1= ((x & 8)+(y & 4)+(z & 2))>>1; - br= br->b[oc1]; + oc1 = ((x & 8) + (y & 4) + (z & 2)) >> 1; + br = br->b[oc1]; if (br) { - oc1= ((x & 4)+(y & 2)+(z & 1)); + oc1 = ((x & 4) + (y & 2) + (z & 1)); return (Node *)br->b[oc1]; } } @@ -789,24 +786,24 @@ static int cliptest(float p, float q, float *u1, float *u2) { float r; - if (p<0.0f) { - if (q<p) return 0; - else if (q<0.0f) { - r= q/p; - if (r>*u2) return 0; - else if (r>*u1) *u1=r; + if (p < 0.0f) { + if (q < p) return 0; + else if (q < 0.0f) { + r = q / p; + if (r > *u2) return 0; + else if (r > *u1) *u1 = r; } } else { - if (p>0.0f) { - if (q<0.0f) return 0; - else if (q<p) { - r= q/p; - if (r<*u1) return 0; - else if (r<*u2) *u2=r; + if (p > 0.0f) { + if (q < 0.0f) return 0; + else if (q < p) { + r = q / p; + if (r < *u1) return 0; + else if (r < *u2) *u2 = r; } } - else if (q<0.0f) return 0; + else if (q < 0.0f) return 0; } return 1; } @@ -816,16 +813,16 @@ static int cliptest(float p, float q, float *u1, float *u2) #if 0 -in top: static int coh_nodes[16*16*16][6]; -in makeoctree: memset(coh_nodes, 0, sizeof(coh_nodes)); +in top : static int coh_nodes[16 * 16 * 16][6]; +in makeoctree : memset(coh_nodes, 0, sizeof(coh_nodes)); static void add_coherence_test(int ocx1, int ocx2, int ocy1, int ocy2, int ocz1, int ocz2) { short *sp; - sp= coh_nodes[ (ocx2 & 15) + 16*(ocy2 & 15) + 256*(ocz2 & 15) ]; - sp[0]= ocx1; sp[1]= ocy1; sp[2]= ocz1; - sp[3]= ocx2; sp[4]= ocy2; sp[5]= ocz2; + sp = coh_nodes[(ocx2 & 15) + 16 * (ocy2 & 15) + 256 * (ocz2 & 15)]; + sp[0] = ocx1; sp[1] = ocy1; sp[2] = ocz1; + sp[3] = ocx2; sp[4] = ocy2; sp[5] = ocz2; } @@ -833,9 +830,9 @@ static int do_coherence_test(int ocx1, int ocx2, int ocy1, int ocy2, int ocz1, i { short *sp; - sp= coh_nodes[ (ocx2 & 15) + 16*(ocy2 & 15) + 256*(ocz2 & 15) ]; - if (sp[0]==ocx1 && sp[1]==ocy1 && sp[2]==ocz1 && - sp[3]==ocx2 && sp[4]==ocy2 && sp[5]==ocz2) return 1; + sp = coh_nodes[(ocx2 & 15) + 16 * (ocy2 & 15) + 256 * (ocz2 & 15)]; + if (sp[0] == ocx1 && sp[1] == ocy1 && sp[2] == ocz1 && + sp[3] == ocx2 && sp[4] == ocy2 && sp[5] == ocz2) return 1; return 0; } @@ -845,7 +842,7 @@ static int do_coherence_test(int ocx1, int ocx2, int ocy1, int ocy2, int ocz1, i /* starts with is->orig.face */ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) { - Octree *oc= (Octree*)tree; + Octree *oc = (Octree *)tree; Node *no; OcVal ocval; float vec1[3], vec2[3], start[3], end[3]; @@ -853,47 +850,47 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) float labdao, labdax, ldx, labday, ldy, labdaz, ldz, ddalabda; float olabda = 0; int dx, dy, dz; - int xo, yo, zo, c1=0; + int xo, yo, zo, c1 = 0; int ocx1, ocx2, ocy1, ocy2, ocz1, ocz2; /* clip with octree */ - if (oc->branchcount==0) return 0; + if (oc->branchcount == 0) return 0; /* do this before intersect calls */ #if 0 - is->facecontr= NULL; /* to check shared edge */ - is->obcontr= 0; - is->faceisect= is->isect= 0; /* shared edge, quad half flag */ - is->userdata= oc->userdata; + is->facecontr = NULL; /* to check shared edge */ + is->obcontr = 0; + is->faceisect = is->isect = 0; /* shared edge, quad half flag */ + is->userdata = oc->userdata; #endif - copy_v3_v3( start, is->start ); - madd_v3_v3v3fl( end, is->start, is->dir, is->dist ); - ldx= is->dir[0]*is->dist; + copy_v3_v3(start, is->start); + madd_v3_v3v3fl(end, is->start, is->dir, is->dist); + ldx = is->dir[0] * is->dist; olabda = is->dist; - u1= 0.0f; - u2= 1.0f; + u1 = 0.0f; + u2 = 1.0f; /* clip with octree cube */ - if (cliptest(-ldx, start[0]-oc->min[0], &u1, &u2)) { - if (cliptest(ldx, oc->max[0]-start[0], &u1, &u2)) { - ldy= is->dir[1]*is->dist; - if (cliptest(-ldy, start[1]-oc->min[1], &u1, &u2)) { - if (cliptest(ldy, oc->max[1]-start[1], &u1, &u2)) { - ldz = is->dir[2]*is->dist; - if (cliptest(-ldz, start[2]-oc->min[2], &u1, &u2)) { - if (cliptest(ldz, oc->max[2]-start[2], &u1, &u2)) { - c1=1; - if (u2<1.0f) { - end[0] = start[0]+u2*ldx; - end[1] = start[1]+u2*ldy; - end[2] = start[2]+u2*ldz; + if (cliptest(-ldx, start[0] - oc->min[0], &u1, &u2)) { + if (cliptest(ldx, oc->max[0] - start[0], &u1, &u2)) { + ldy = is->dir[1] * is->dist; + if (cliptest(-ldy, start[1] - oc->min[1], &u1, &u2)) { + if (cliptest(ldy, oc->max[1] - start[1], &u1, &u2)) { + ldz = is->dir[2] * is->dist; + if (cliptest(-ldz, start[2] - oc->min[2], &u1, &u2)) { + if (cliptest(ldz, oc->max[2] - start[2], &u1, &u2)) { + c1 = 1; + if (u2 < 1.0f) { + end[0] = start[0] + u2 * ldx; + end[1] = start[1] + u2 * ldy; + end[2] = start[2] + u2 * ldz; } - if (u1>0.0f) { - start[0] += u1*ldx; - start[1] += u1*ldy; - start[2] += u1*ldz; + if (u1 > 0.0f) { + start[0] += u1 * ldx; + start[1] += u1 * ldy; + start[2] += u1 * ldz; } } } @@ -902,34 +899,34 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) } } - if (c1==0) return 0; + if (c1 == 0) return 0; /* reset static variables in ocread */ //ocread(oc, oc->ocres, 0, 0); /* setup 3dda to traverse octree */ - ox1= (start[0]-oc->min[0])*oc->ocfacx; - oy1= (start[1]-oc->min[1])*oc->ocfacy; - oz1= (start[2]-oc->min[2])*oc->ocfacz; - ox2= (end[0]-oc->min[0])*oc->ocfacx; - oy2= (end[1]-oc->min[1])*oc->ocfacy; - oz2= (end[2]-oc->min[2])*oc->ocfacz; - - ocx1= (int)ox1; - ocy1= (int)oy1; - ocz1= (int)oz1; - ocx2= (int)ox2; - ocy2= (int)oy2; - ocz2= (int)oz2; + ox1 = (start[0] - oc->min[0]) * oc->ocfacx; + oy1 = (start[1] - oc->min[1]) * oc->ocfacy; + oz1 = (start[2] - oc->min[2]) * oc->ocfacz; + ox2 = (end[0] - oc->min[0]) * oc->ocfacx; + oy2 = (end[1] - oc->min[1]) * oc->ocfacy; + oz2 = (end[2] - oc->min[2]) * oc->ocfacz; + + ocx1 = (int)ox1; + ocy1 = (int)oy1; + ocz1 = (int)oz1; + ocx2 = (int)ox2; + ocy2 = (int)oy2; + ocz2 = (int)oz2; - if (ocx1==ocx2 && ocy1==ocy2 && ocz1==ocz2) { - no= ocread(oc, ocx1, ocy1, ocz1); + if (ocx1 == ocx2 && ocy1 == ocy2 && ocz1 == ocz2) { + no = ocread(oc, ocx1, ocy1, ocz1); if (no) { /* exact intersection with node */ - vec1[0]= ox1; vec1[1]= oy1; vec1[2]= oz1; - vec2[0]= ox2; vec2[1]= oy2; vec2[2]= oz2; + vec1[0] = ox1; vec1[1] = oy1; vec1[2] = oz1; + vec2[0] = ox2; vec2[1] = oy2; vec2[2] = oz2; calc_ocval_ray(&ocval, (float)ocx1, (float)ocy1, (float)ocz1, vec1, vec2); - if ( testnode(oc, is, no, ocval) ) return 1; + if (testnode(oc, is, no, ocval) ) return 1; } } else { @@ -939,153 +936,153 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) int eqval; /* calc labda en ld */ - dox= ox1-ox2; - doy= oy1-oy2; - doz= oz1-oz2; - - if (dox<-FLT_EPSILON) { - ldx= -1.0f/dox; - labdax= (ocx1-ox1+1.0f)*ldx; - dx= 1; + dox = ox1 - ox2; + doy = oy1 - oy2; + doz = oz1 - oz2; + + if (dox < -FLT_EPSILON) { + ldx = -1.0f / dox; + labdax = (ocx1 - ox1 + 1.0f) * ldx; + dx = 1; } - else if (dox>FLT_EPSILON) { - ldx= 1.0f/dox; - labdax= (ox1-ocx1)*ldx; - dx= -1; + else if (dox > FLT_EPSILON) { + ldx = 1.0f / dox; + labdax = (ox1 - ocx1) * ldx; + dx = -1; } else { - labdax=1.0f; - ldx=0; - dx= 0; + labdax = 1.0f; + ldx = 0; + dx = 0; } - if (doy<-FLT_EPSILON) { - ldy= -1.0f/doy; - labday= (ocy1-oy1+1.0f)*ldy; - dy= 1; + if (doy < -FLT_EPSILON) { + ldy = -1.0f / doy; + labday = (ocy1 - oy1 + 1.0f) * ldy; + dy = 1; } - else if (doy>FLT_EPSILON) { - ldy= 1.0f/doy; - labday= (oy1-ocy1)*ldy; - dy= -1; + else if (doy > FLT_EPSILON) { + ldy = 1.0f / doy; + labday = (oy1 - ocy1) * ldy; + dy = -1; } else { - labday=1.0f; - ldy=0; - dy= 0; + labday = 1.0f; + ldy = 0; + dy = 0; } - if (doz<-FLT_EPSILON) { - ldz= -1.0f/doz; - labdaz= (ocz1-oz1+1.0f)*ldz; - dz= 1; + if (doz < -FLT_EPSILON) { + ldz = -1.0f / doz; + labdaz = (ocz1 - oz1 + 1.0f) * ldz; + dz = 1; } - else if (doz>FLT_EPSILON) { - ldz= 1.0f/doz; - labdaz= (oz1-ocz1)*ldz; - dz= -1; + else if (doz > FLT_EPSILON) { + ldz = 1.0f / doz; + labdaz = (oz1 - ocz1) * ldz; + dz = -1; } else { - labdaz=1.0f; - ldz=0; - dz= 0; + labdaz = 1.0f; + ldz = 0; + dz = 0; } - xo=ocx1; yo=ocy1; zo=ocz1; - ddalabda= MIN3(labdax, labday, labdaz); + xo = ocx1; yo = ocy1; zo = ocz1; + ddalabda = MIN3(labdax, labday, labdaz); - vec2[0]= ox1; - vec2[1]= oy1; - vec2[2]= oz1; + vec2[0] = ox1; + vec2[1] = oy1; + vec2[2] = oz1; /* this loop has been constructed to make sure the first and last node of ray * are always included, even when ddalabda==1.0f or larger */ while (TRUE) { - no= ocread(oc, xo, yo, zo); + no = ocread(oc, xo, yo, zo); if (no) { /* calculate ray intersection with octree node */ copy_v3_v3(vec1, vec2); // dox, y, z is negative - vec2[0]= ox1-ddalabda*dox; - vec2[1]= oy1-ddalabda*doy; - vec2[2]= oz1-ddalabda*doz; + vec2[0] = ox1 - ddalabda * dox; + vec2[1] = oy1 - ddalabda * doy; + vec2[2] = oz1 - ddalabda * doz; calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2); //is->dist = (u1+ddalabda*(u2-u1))*olabda; - if ( testnode(oc, is, no, ocval) ) + if (testnode(oc, is, no, ocval) ) found = 1; - if (is->dist < (u1+ddalabda*(u2-u1))*olabda) + if (is->dist < (u1 + ddalabda * (u2 - u1)) * olabda) return found; } - labdao= ddalabda; + labdao = ddalabda; /* traversing ocree nodes need careful detection of smallest values, with proper * exceptions for equal labdas */ - eqval= (labdax==labday); - if (labday==labdaz) eqval += 2; - if (labdax==labdaz) eqval += 4; - - if (eqval) { // only 4 cases exist! - if (eqval==7) { // x=y=z - xo+=dx; labdax+=ldx; - yo+=dy; labday+=ldy; - zo+=dz; labdaz+=ldz; + eqval = (labdax == labday); + if (labday == labdaz) eqval += 2; + if (labdax == labdaz) eqval += 4; + + if (eqval) { // only 4 cases exist! + if (eqval == 7) { // x=y=z + xo += dx; labdax += ldx; + yo += dy; labday += ldy; + zo += dz; labdaz += ldz; } - else if (eqval==1) { // x=y + else if (eqval == 1) { // x=y if (labday < labdaz) { - xo+=dx; labdax+=ldx; - yo+=dy; labday+=ldy; + xo += dx; labdax += ldx; + yo += dy; labday += ldy; } else { - zo+=dz; labdaz+=ldz; + zo += dz; labdaz += ldz; } } - else if (eqval==2) { // y=z + else if (eqval == 2) { // y=z if (labdax < labday) { - xo+=dx; labdax+=ldx; + xo += dx; labdax += ldx; } else { - yo+=dy; labday+=ldy; - zo+=dz; labdaz+=ldz; + yo += dy; labday += ldy; + zo += dz; labdaz += ldz; } } else { // x=z if (labday < labdax) { - yo+=dy; labday+=ldy; + yo += dy; labday += ldy; } else { - xo+=dx; labdax+=ldx; - zo+=dz; labdaz+=ldz; + xo += dx; labdax += ldx; + zo += dz; labdaz += ldz; } } } - else { // all three different, just three cases exist - eqval= (labdax<labday); - if (labday<labdaz) eqval += 2; - if (labdax<labdaz) eqval += 4; + else { // all three different, just three cases exist + eqval = (labdax < labday); + if (labday < labdaz) eqval += 2; + if (labdax < labdaz) eqval += 4; - if (eqval==7 || eqval==5) { // x smallest - xo+=dx; labdax+=ldx; + if (eqval == 7 || eqval == 5) { // x smallest + xo += dx; labdax += ldx; } - else if (eqval==2 || eqval==6) { // y smallest - yo+=dy; labday+=ldy; + else if (eqval == 2 || eqval == 6) { // y smallest + yo += dy; labday += ldy; } else { // z smallest - zo+=dz; labdaz+=ldz; + zo += dz; labdaz += ldz; } } - ddalabda=MIN3(labdax, labday, labdaz); - if (ddalabda==labdao) break; + ddalabda = MIN3(labdax, labday, labdaz); + if (ddalabda == labdao) break; /* to make sure the last node is always checked */ - if (labdao>=1.0f) break; + if (labdao >= 1.0f) break; } } diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 865462bda66..36eb74b3d30 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -521,8 +521,7 @@ static void calc_tangent_vector(ObjectRen *obr, VertexTangent **vtangents, MemAr ************ tangent space generation interface **************** ****************************************************************/ -typedef struct -{ +typedef struct { ObjectRen *obr; } SRenderMeshToTangent; @@ -1012,8 +1011,7 @@ static Material *give_render_material(Render *re, Object *ob, short nr) /* ------------------------------------------------------------------------- */ /* Particles */ /* ------------------------------------------------------------------------- */ -typedef struct ParticleStrandData -{ +typedef struct ParticleStrandData { struct MCol *mcol; float *orco, *uvco, *surfnor; float time, adapt_angle, adapt_pix, size; @@ -5706,7 +5704,7 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned ok= 1; } if (ok==0) { - printf("speed table: missing object %s\n", obi->ob->id.name+2); + printf("speed table: missing object %s\n", obi->ob->id.name+2); continue; } diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 0f3a3111a13..61de4d39585 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -74,49 +74,49 @@ static void envmap_split_ima(EnvMap *env, ImBuf *ibuf) /* after lock we test cube[1], if set the other thread has done it fine */ BLI_lock_thread(LOCK_IMAGE); - if (env->cube[1]==NULL) { + if (env->cube[1] == NULL) { BKE_free_envmapdata(env); - dx= ibuf->y; - dx/= 2; - if (3*dx == ibuf->x) { + dx = ibuf->y; + dx /= 2; + if (3 * dx == ibuf->x) { env->type = ENV_CUBE; - env->ok= ENV_OSA; + env->ok = ENV_OSA; } else if (ibuf->x == ibuf->y) { env->type = ENV_PLANE; - env->ok= ENV_OSA; + env->ok = ENV_OSA; } else { printf("Incorrect envmap size\n"); - env->ok= 0; - env->ima->ok= 0; + env->ok = 0; + env->ima->ok = 0; } if (env->ok) { if (env->type == ENV_CUBE) { - for (part=0; part<6; part++) { - env->cube[part]= IMB_allocImBuf(dx, dx, 24, IB_rect|IB_rectfloat); + for (part = 0; part < 6; part++) { + env->cube[part] = IMB_allocImBuf(dx, dx, 24, IB_rect | IB_rectfloat); } IMB_float_from_rect(ibuf); IMB_rectcpy(env->cube[0], ibuf, - 0, 0, 0, 0, dx, dx); + 0, 0, 0, 0, dx, dx); IMB_rectcpy(env->cube[1], ibuf, - 0, 0, dx, 0, dx, dx); + 0, 0, dx, 0, dx, dx); IMB_rectcpy(env->cube[2], ibuf, - 0, 0, 2*dx, 0, dx, dx); + 0, 0, 2 * dx, 0, dx, dx); IMB_rectcpy(env->cube[3], ibuf, - 0, 0, 0, dx, dx, dx); + 0, 0, 0, dx, dx, dx); IMB_rectcpy(env->cube[4], ibuf, - 0, 0, dx, dx, dx, dx); + 0, 0, dx, dx, dx, dx); IMB_rectcpy(env->cube[5], ibuf, - 0, 0, 2*dx, dx, dx, dx); + 0, 0, 2 * dx, dx, dx, dx); } else { /* ENV_PLANE */ - env->cube[1]= IMB_dupImBuf(ibuf); + env->cube[1] = IMB_dupImBuf(ibuf); IMB_float_from_rect(env->cube[1]); } } @@ -134,53 +134,53 @@ static Render *envmap_render_copy(Render *re, EnvMap *env) float viewscale; int cuberes; - envre= RE_NewRender("Envmap"); + envre = RE_NewRender("Envmap"); - env->lastsize= re->r.size; + env->lastsize = re->r.size; cuberes = (env->cuberes * re->r.size) / 100; cuberes &= 0xFFFC; /* this flag has R_ZTRA in it for example */ - envre->flag= re->flag; + envre->flag = re->flag; /* set up renderdata */ - envre->r= re->r; + envre->r = re->r; envre->r.mode &= ~(R_BORDER | R_PANORAMA | R_ORTHO | R_MBLUR); - envre->r.layers.first= envre->r.layers.last= NULL; - envre->r.filtertype= 0; - envre->r.xparts= envre->r.yparts= 2; - envre->r.size= 100; - envre->r.yasp= envre->r.xasp= 1; + envre->r.layers.first = envre->r.layers.last = NULL; + envre->r.filtertype = 0; + envre->r.xparts = envre->r.yparts = 2; + envre->r.size = 100; + envre->r.yasp = envre->r.xasp = 1; RE_InitState(envre, NULL, &envre->r, NULL, cuberes, cuberes, NULL); - envre->scene= re->scene; /* unsure about this... */ - envre->lay= re->lay; + envre->scene = re->scene; /* unsure about this... */ + envre->lay = re->lay; /* view stuff in env render */ - viewscale= (env->type == ENV_PLANE)? env->viewscale: 1.0f; + viewscale = (env->type == ENV_PLANE) ? env->viewscale : 1.0f; RE_SetEnvmapCamera(envre, env->object, viewscale, env->clipsta, env->clipend); /* callbacks */ - envre->display_draw= re->display_draw; - envre->ddh= re->ddh; - envre->test_break= re->test_break; - envre->tbh= re->tbh; + envre->display_draw = re->display_draw; + envre->ddh = re->ddh; + envre->test_break = re->test_break; + envre->tbh = re->tbh; /* and for the evil stuff; copy the database... */ - envre->totvlak= re->totvlak; - envre->totvert= re->totvert; - envre->tothalo= re->tothalo; - envre->totstrand= re->totstrand; - envre->totlamp= re->totlamp; - envre->sortedhalos= re->sortedhalos; - envre->lights= re->lights; - envre->objecttable= re->objecttable; - envre->customdata_names= re->customdata_names; - envre->raytree= re->raytree; - envre->totinstance= re->totinstance; - envre->instancetable= re->instancetable; - envre->objectinstance= re->objectinstance; - envre->qmcsamplers= re->qmcsamplers; + envre->totvlak = re->totvlak; + envre->totvert = re->totvert; + envre->tothalo = re->tothalo; + envre->totstrand = re->totstrand; + envre->totlamp = re->totlamp; + envre->sortedhalos = re->sortedhalos; + envre->lights = re->lights; + envre->objecttable = re->objecttable; + envre->customdata_names = re->customdata_names; + envre->raytree = re->raytree; + envre->totinstance = re->totinstance; + envre->instancetable = re->instancetable; + envre->objectinstance = re->objectinstance; + envre->qmcsamplers = re->qmcsamplers; return envre; } @@ -188,20 +188,20 @@ static Render *envmap_render_copy(Render *re, EnvMap *env) static void envmap_free_render_copy(Render *envre) { - envre->totvlak= 0; - envre->totvert= 0; - envre->tothalo= 0; - envre->totstrand= 0; - envre->totlamp= 0; - envre->totinstance= 0; - envre->sortedhalos= NULL; - envre->lights.first= envre->lights.last= NULL; - envre->objecttable.first= envre->objecttable.last= NULL; - envre->customdata_names.first= envre->customdata_names.last= NULL; - envre->raytree= NULL; - envre->instancetable.first= envre->instancetable.last= NULL; - envre->objectinstance= NULL; - envre->qmcsamplers= NULL; + envre->totvlak = 0; + envre->totvert = 0; + envre->tothalo = 0; + envre->totstrand = 0; + envre->totlamp = 0; + envre->totinstance = 0; + envre->sortedhalos = NULL; + envre->lights.first = envre->lights.last = NULL; + envre->objecttable.first = envre->objecttable.last = NULL; + envre->customdata_names.first = envre->customdata_names.last = NULL; + envre->raytree = NULL; + envre->instancetable.first = envre->instancetable.last = NULL; + envre->objectinstance = NULL; + envre->qmcsamplers = NULL; RE_FreeRender(envre); } @@ -212,28 +212,28 @@ static void envmap_transmatrix(float mat[][4], int part) { float tmat[4][4], eul[3], rotmat[4][4]; - eul[0]= eul[1]= eul[2]= 0.0; + eul[0] = eul[1] = eul[2] = 0.0; - if (part==0) { /* neg z */ + if (part == 0) { /* neg z */ ; } - else if (part==1) { /* pos z */ - eul[0]= M_PI; + else if (part == 1) { /* pos z */ + eul[0] = M_PI; } - else if (part==2) { /* pos y */ - eul[0]= M_PI/2.0; + else if (part == 2) { /* pos y */ + eul[0] = M_PI / 2.0; } - else if (part==3) { /* neg x */ - eul[0]= M_PI/2.0; - eul[2]= M_PI/2.0; + else if (part == 3) { /* neg x */ + eul[0] = M_PI / 2.0; + eul[2] = M_PI / 2.0; } - else if (part==4) { /* neg y */ - eul[0]= M_PI/2.0; - eul[2]= M_PI; + else if (part == 4) { /* neg y */ + eul[0] = M_PI / 2.0; + eul[2] = M_PI; } - else { /* pos x */ - eul[0]= M_PI/2.0; - eul[2]= -M_PI/2.0; + else { /* pos x */ + eul[0] = M_PI / 2.0; + eul[2] = -M_PI / 2.0; } copy_m4_m4(tmat, mat); @@ -255,7 +255,7 @@ static void env_rotate_scene(Render *re, float mat[][4], int mode) float imat[3][3], pmat[4][4], smat[4][4], tmat[4][4], cmat[3][3], tmpmat[4][4]; int a; - if (mode==0) { + if (mode == 0) { invert_m4_m4(tmat, mat); copy_m3_m4(imat, tmat); } @@ -264,13 +264,13 @@ static void env_rotate_scene(Render *re, float mat[][4], int mode) copy_m3_m4(imat, mat); } - for (obi=re->instancetable.first; obi; obi=obi->next) { + for (obi = re->instancetable.first; obi; obi = obi->next) { /* append or set matrix depending on dupli */ if (obi->flag & R_DUPLI_TRANSFORMED) { copy_m4_m4(tmpmat, obi->mat); mult_m4_m4m4(obi->mat, tmat, tmpmat); } - else if (mode==1) + else if (mode == 1) copy_m4_m4(obi->mat, tmat); else unit_m4(obi->mat); @@ -280,24 +280,24 @@ static void env_rotate_scene(Render *re, float mat[][4], int mode) transpose_m3(obi->nmat); /* indicate the renderer has to use transform matrices */ - if (mode==0) + if (mode == 0) obi->flag &= ~R_ENV_TRANSFORMED; else obi->flag |= R_ENV_TRANSFORMED; } - for (obr=re->objecttable.first; obr; obr=obr->next) { - for (a=0; a<obr->tothalo; a++) { - if ((a & 255)==0) har= obr->bloha[a>>8]; + for (obr = re->objecttable.first; obr; obr = obr->next) { + for (a = 0; a < obr->tothalo; a++) { + if ((a & 255) == 0) har = obr->bloha[a >> 8]; else har++; mul_m4_v3(tmat, har->co); } } - for (go=re->lights.first; go; go= go->next) { - lar= go->lampren; + for (go = re->lights.first; go; go = go->next) { + lar = go->lampren; /* removed here some horrible code of someone in NaN who tried to fix * prototypes... just solved by introducing a correct cmat[3][3] instead @@ -308,14 +308,14 @@ static void env_rotate_scene(Render *re, float mat[][4], int mode) mul_m3_v3(imat, lar->vec); mul_m4_v3(tmat, lar->co); - lar->sh_invcampos[0]= -lar->co[0]; - lar->sh_invcampos[1]= -lar->co[1]; - lar->sh_invcampos[2]= -lar->co[2]; + lar->sh_invcampos[0] = -lar->co[0]; + lar->sh_invcampos[1] = -lar->co[1]; + lar->sh_invcampos[2] = -lar->co[2]; mul_m3_v3(lar->imat, lar->sh_invcampos); - lar->sh_invcampos[2]*= lar->sh_zfac; + lar->sh_invcampos[2] *= lar->sh_zfac; if (lar->shb) { - if (mode==1) { + if (mode == 1) { invert_m4_m4(pmat, mat); mult_m4_m4m4(smat, lar->shb->viewmat, pmat); mult_m4_m4m4(lar->shb->persmat, lar->shb->winmat, smat); @@ -342,12 +342,12 @@ static void env_layerflags(Render *re, unsigned int notlay) * now (face & ~not) is true */ - notlay= ~notlay; + notlay = ~notlay; - for (obr=re->objecttable.first; obr; obr=obr->next) { - if ((obr->lay & notlay)==0) { - for (a=0; a<obr->totvlak; a++) { - if ((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; + for (obr = re->objecttable.first; obr; obr = obr->next) { + if ((obr->lay & notlay) == 0) { + for (a = 0; a < obr->totvlak; a++) { + if ((a & 255) == 0) vlr = obr->vlaknodes[a >> 8].vlak; else vlr++; vlr->flag |= R_HIDDEN; @@ -362,9 +362,9 @@ static void env_hideobject(Render *re, Object *ob) VlakRen *vlr = NULL; int a; - for (obr=re->objecttable.first; obr; obr=obr->next) { - for (a=0; a<obr->totvlak; a++) { - if ((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; + for (obr = re->objecttable.first; obr; obr = obr->next) { + for (a = 0; a < obr->totvlak; a++) { + if ((a & 255) == 0) vlr = obr->vlaknodes[a >> 8].vlak; else vlr++; if (obr->ob == ob) @@ -379,9 +379,9 @@ static void env_showobjects(Render *re) VlakRen *vlr = NULL; int a; - for (obr=re->objecttable.first; obr; obr=obr->next) { - for (a=0; a<obr->totvlak; a++) { - if ((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; + for (obr = re->objecttable.first; obr; obr = obr->next) { + for (a = 0; a < obr->totvlak; a++) { + if ((a & 255) == 0) vlr = obr->vlaknodes[a >> 8].vlak; else vlr++; vlr->flag &= ~R_HIDDEN; @@ -396,12 +396,12 @@ static void env_set_imats(Render *re) Base *base; float mat[4][4]; - base= re->scene->base.first; + base = re->scene->base.first; while (base) { mult_m4_m4m4(mat, re->viewmat, base->object->obmat); invert_m4_m4(base->object->imat, mat); - base= base->next; + base = base->next; } } @@ -420,7 +420,7 @@ static void render_envmap(Render *re, EnvMap *env) /* need a recalc: ortho-render has no correct viewinv */ invert_m4_m4(oldviewinv, re->viewmat); - envre= envmap_render_copy(re, env); + envre = envmap_render_copy(re, env); /* precalc orthmat for object */ copy_m4_m4(orthmat, env->object->obmat); @@ -431,8 +431,8 @@ static void render_envmap(Render *re, EnvMap *env) invert_m4_m4(tmat, mat); copy_m3_m4(env->obimat, tmat); - for (part=0; part<6; part++) { - if (env->type==ENV_PLANE && part!=1) + for (part = 0; part < 6; part++) { + if (env->type == ENV_PLANE && part != 1) continue; re->display_clear(re->dch, envre->result); @@ -456,7 +456,7 @@ static void render_envmap(Render *re, EnvMap *env) env_hideobject(envre, env->object); env_set_imats(envre); - if (re->test_break(re->tbh)==0) { + if (re->test_break(re->tbh) == 0) { RE_TileProcessor(envre); } @@ -464,23 +464,23 @@ static void render_envmap(Render *re, EnvMap *env) env_showobjects(envre); env_rotate_scene(envre, tmat, 0); - if (re->test_break(re->tbh)==0) { - RenderLayer *rl= envre->result->layers.first; + if (re->test_break(re->tbh) == 0) { + RenderLayer *rl = envre->result->layers.first; int y; float *alpha; - ibuf= IMB_allocImBuf(envre->rectx, envre->recty, 24, IB_rect|IB_rectfloat); + ibuf = IMB_allocImBuf(envre->rectx, envre->recty, 24, IB_rect | IB_rectfloat); memcpy(ibuf->rect_float, rl->rectf, ibuf->channels * ibuf->x * ibuf->y * sizeof(float)); if (re->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) ibuf->profile = IB_PROFILE_LINEAR_RGB; /* envmap renders without alpha */ - alpha= ((float *)ibuf->rect_float)+3; - for (y= ibuf->x*ibuf->y - 1; y>=0; y--, alpha+=4) - *alpha= 1.0; + alpha = ((float *)ibuf->rect_float) + 3; + for (y = ibuf->x * ibuf->y - 1; y >= 0; y--, alpha += 4) + *alpha = 1.0; - env->cube[part]= ibuf; + env->cube[part] = ibuf; } if (re->test_break(re->tbh)) break; @@ -489,9 +489,9 @@ static void render_envmap(Render *re, EnvMap *env) if (re->test_break(re->tbh)) BKE_free_envmapdata(env); else { - if (envre->r.mode & R_OSA) env->ok= ENV_OSA; - else env->ok= ENV_NORMAL; - env->lastframe= re->scene->r.cfra; + if (envre->r.mode & R_OSA) env->ok = ENV_OSA; + else env->ok = ENV_NORMAL; + env->lastframe = re->scene->r.cfra; } /* restore */ @@ -505,27 +505,27 @@ static void render_envmap(Render *re, EnvMap *env) void make_envmaps(Render *re) { Tex *tex; - int do_init = FALSE, depth= 0, trace; + int do_init = FALSE, depth = 0, trace; if (!(re->r.mode & R_ENVMAP)) return; /* we don't raytrace, disabling the flag will cause ray_transp render solid */ - trace= (re->r.mode & R_RAYTRACE); + trace = (re->r.mode & R_RAYTRACE); re->r.mode &= ~R_RAYTRACE; - re->i.infostr= "Creating Environment maps"; + re->i.infostr = "Creating Environment maps"; re->stats_draw(re->sdh, &re->i); /* 5 = hardcoded max recursion level */ - while (depth<5) { - tex= re->main->tex.first; + while (depth < 5) { + tex = re->main->tex.first; while (tex) { - if (tex->id.us && tex->type==TEX_ENVMAP) { + if (tex->id.us && tex->type == TEX_ENVMAP) { if (tex->env && tex->env->object) { - EnvMap *env= tex->env; + EnvMap *env = tex->env; if (env->object->lay & re->lay) { - if (env->stype==ENV_LOAD) { + if (env->stype == ENV_LOAD) { float orthmat[4][4], mat[4][4], tmat[4][4]; /* precalc orthmat for object */ @@ -545,31 +545,31 @@ void make_envmaps(Render *re) /* set 'recalc' to make sure it does an entire loop of recalcs */ if (env->ok) { - /* free when OSA, and old one isn't OSA */ - if ((re->r.mode & R_OSA) && env->ok==ENV_NORMAL) + /* free when OSA, and old one isn't OSA */ + if ((re->r.mode & R_OSA) && env->ok == ENV_NORMAL) BKE_free_envmapdata(env); - /* free when size larger */ + /* free when size larger */ else if (env->lastsize < re->r.size) BKE_free_envmapdata(env); - /* free when env is in recalcmode */ + /* free when env is in recalcmode */ else if (env->recalc) BKE_free_envmapdata(env); } - if (env->ok==0 && depth==0) env->recalc= 1; + if (env->ok == 0 && depth == 0) env->recalc = 1; - if (env->ok==0) { + if (env->ok == 0) { do_init = TRUE; render_envmap(re, env); - if (depth==env->depth) env->recalc= 0; + if (depth == env->depth) env->recalc = 0; } } } } } } - tex= tex->id.next; + tex = tex->id.next; } depth++; } @@ -591,55 +591,55 @@ static int envcube_isect(EnvMap *env, const float vec[3], float answ[2]) float labda; int face; - if (env->type==ENV_PLANE) { - face= 1; + if (env->type == ENV_PLANE) { + face = 1; - labda= 1.0f/vec[2]; - answ[0]= env->viewscale*labda*vec[0]; - answ[1]= -env->viewscale*labda*vec[1]; + labda = 1.0f / vec[2]; + answ[0] = env->viewscale * labda * vec[0]; + answ[1] = -env->viewscale * labda * vec[1]; } else { /* which face */ - if ( vec[2] <= -fabsf(vec[0]) && vec[2] <= -fabsf(vec[1]) ) { - face= 0; - labda= -1.0f/vec[2]; - answ[0]= labda*vec[0]; - answ[1]= labda*vec[1]; + if (vec[2] <= -fabsf(vec[0]) && vec[2] <= -fabsf(vec[1]) ) { + face = 0; + labda = -1.0f / vec[2]; + answ[0] = labda * vec[0]; + answ[1] = labda * vec[1]; } else if (vec[2] >= fabsf(vec[0]) && vec[2] >= fabsf(vec[1])) { - face= 1; - labda= 1.0f/vec[2]; - answ[0]= labda*vec[0]; - answ[1]= -labda*vec[1]; + face = 1; + labda = 1.0f / vec[2]; + answ[0] = labda * vec[0]; + answ[1] = -labda * vec[1]; } else if (vec[1] >= fabsf(vec[0])) { - face= 2; - labda= 1.0f/vec[1]; - answ[0]= labda*vec[0]; - answ[1]= labda*vec[2]; + face = 2; + labda = 1.0f / vec[1]; + answ[0] = labda * vec[0]; + answ[1] = labda * vec[2]; } else if (vec[0] <= -fabsf(vec[1])) { - face= 3; - labda= -1.0f/vec[0]; - answ[0]= labda*vec[1]; - answ[1]= labda*vec[2]; + face = 3; + labda = -1.0f / vec[0]; + answ[0] = labda * vec[1]; + answ[1] = labda * vec[2]; } else if (vec[1] <= -fabsf(vec[0])) { - face= 4; - labda= -1.0f/vec[1]; - answ[0]= -labda*vec[0]; - answ[1]= labda*vec[2]; + face = 4; + labda = -1.0f / vec[1]; + answ[0] = -labda * vec[0]; + answ[1] = labda * vec[2]; } else { - face= 5; - labda= 1.0f/vec[0]; - answ[0]= -labda*vec[1]; - answ[1]= labda*vec[2]; + face = 5; + labda = 1.0f / vec[0]; + answ[0] = -labda * vec[1]; + answ[1] = labda * vec[2]; } } - answ[0]= 0.5f+0.5f*answ[0]; - answ[1]= 0.5f+0.5f*answ[1]; + answ[0] = 0.5f + 0.5f * answ[0]; + answ[1] = 0.5f + 0.5f * answ[1]; return face; } @@ -647,23 +647,23 @@ static int envcube_isect(EnvMap *env, const float vec[3], float answ[2]) static void set_dxtdyt(float *dxts, float *dyts, float *dxt, float *dyt, int face) { - if (face==2 || face==4) { - dxts[0]= dxt[0]; - dyts[0]= dyt[0]; - dxts[1]= dxt[2]; - dyts[1]= dyt[2]; + if (face == 2 || face == 4) { + dxts[0] = dxt[0]; + dyts[0] = dyt[0]; + dxts[1] = dxt[2]; + dyts[1] = dyt[2]; } - else if (face==3 || face==5) { - dxts[0]= dxt[1]; - dxts[1]= dxt[2]; - dyts[0]= dyt[1]; - dyts[1]= dyt[2]; + else if (face == 3 || face == 5) { + dxts[0] = dxt[1]; + dxts[1] = dxt[2]; + dyts[0] = dyt[1]; + dyts[1] = dyt[2]; } else { - dxts[0]= dxt[0]; - dyts[0]= dyt[0]; - dxts[1]= dxt[1]; - dyts[1]= dyt[1]; + dxts[0] = dxt[0]; + dyts[0] = dyt[0]; + dxts[1] = dxt[1]; + dyts[1] = dyt[1]; } } @@ -671,34 +671,34 @@ static void set_dxtdyt(float *dxts, float *dyts, float *dxt, float *dyt, int fac int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres) { - extern Render R; /* only in this call */ + extern Render R; /* only in this call */ /* texvec should be the already reflected normal */ EnvMap *env; ImBuf *ibuf; float fac, vec[3], sco[3], dxts[3], dyts[3]; int face, face1; - env= tex->env; - if (env==NULL || (env->stype!=ENV_LOAD && env->object==NULL)) { - texres->tin= 0.0; + env = tex->env; + if (env == NULL || (env->stype != ENV_LOAD && env->object == NULL)) { + texres->tin = 0.0; return 0; } - if (env->stype==ENV_LOAD) { - env->ima= tex->ima; + if (env->stype == ENV_LOAD) { + env->ima = tex->ima; if (env->ima && env->ima->ok) { - if (env->cube[1]==NULL) { - ImBuf *ibuf_ima= BKE_image_get_ibuf(env->ima, NULL); + if (env->cube[1] == NULL) { + ImBuf *ibuf_ima = BKE_image_get_ibuf(env->ima, NULL); if (ibuf_ima) envmap_split_ima(env, ibuf_ima); else - env->ok= 0; + env->ok = 0; } } } - if (env->ok==0) { - texres->tin= 0.0; + if (env->ok == 0) { + texres->tin = 0.0; return 0; } @@ -707,8 +707,8 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe if (env->object) mul_m3_v3(env->obimat, vec); else mul_mat3_m4_v3(R.viewinv, vec); - face= envcube_isect(env, vec, sco); - ibuf= env->cube[face]; + face = envcube_isect(env, vec, sco); + ibuf = env->cube[face]; if (osatex) { if (env->object) { @@ -724,45 +724,45 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe /* edges? */ - if (texres->ta<1.0f) { + if (texres->ta < 1.0f) { TexResult texr1, texr2; - texr1.nor= texr2.nor= NULL; - texr1.talpha= texr2.talpha= texres->talpha; /* boxclip expects this initialized */ + texr1.nor = texr2.nor = NULL; + texr1.talpha = texr2.talpha = texres->talpha; /* boxclip expects this initialized */ add_v3_v3(vec, dxt); - face1= envcube_isect(env, vec, sco); + face1 = envcube_isect(env, vec, sco); sub_v3_v3(vec, dxt); - if (face!=face1) { - ibuf= env->cube[face1]; + if (face != face1) { + ibuf = env->cube[face1]; set_dxtdyt(dxts, dyts, dxt, dyt, face1); imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr1); } - else texr1.tr= texr1.tg= texr1.tb= texr1.ta= 0.0; + else texr1.tr = texr1.tg = texr1.tb = texr1.ta = 0.0; /* here was the nasty bug! results were not zero-ed. FPE! */ add_v3_v3(vec, dyt); - face1= envcube_isect(env, vec, sco); + face1 = envcube_isect(env, vec, sco); sub_v3_v3(vec, dyt); - if (face!=face1) { - ibuf= env->cube[face1]; + if (face != face1) { + ibuf = env->cube[face1]; set_dxtdyt(dxts, dyts, dxt, dyt, face1); imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr2); } - else texr2.tr= texr2.tg= texr2.tb= texr2.ta= 0.0; + else texr2.tr = texr2.tg = texr2.tb = texr2.ta = 0.0; - fac= (texres->ta+texr1.ta+texr2.ta); - if (fac!=0.0f) { - fac= 1.0f/fac; + fac = (texres->ta + texr1.ta + texr2.ta); + if (fac != 0.0f) { + fac = 1.0f / fac; - texres->tr= fac*(texres->ta*texres->tr + texr1.ta*texr1.tr + texr2.ta*texr2.tr ); - texres->tg= fac*(texres->ta*texres->tg + texr1.ta*texr1.tg + texr2.ta*texr2.tg ); - texres->tb= fac*(texres->ta*texres->tb + texr1.ta*texr1.tb + texr2.ta*texr2.tb ); + texres->tr = fac * (texres->ta * texres->tr + texr1.ta * texr1.tr + texr2.ta * texr2.tr); + texres->tg = fac * (texres->ta * texres->tg + texr1.ta * texr1.tg + texr2.ta * texr2.tg); + texres->tb = fac * (texres->ta * texres->tb + texr1.ta * texr1.tb + texr2.ta * texr2.tb); } - texres->ta= 1.0; + texres->ta = 1.0; } } else { @@ -771,7 +771,3 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe return 1; } - -/* ------------------------------------------------------------------------- */ - -/* eof */ diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 02ef89a0edd..c37d7e0e5d8 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1717,7 +1717,7 @@ int RE_seq_render_active(Scene *scene, RenderData *rd) return 0; for (seq= ed->seqbase.first; seq; seq= seq->next) { - if (seq->type != SEQ_SOUND) + if (seq->type != SEQ_TYPE_SOUND_RAM) return 1; } @@ -1842,7 +1842,7 @@ static int check_valid_camera(Scene *scene, Object *camera_override) check_comp= 0; while (seq) { - if (seq->type == SEQ_SCENE && seq->scene) { + if (seq->type == SEQ_TYPE_SCENE && seq->scene) { if (!seq->scene_camera) { if (!seq->scene->camera && !BKE_scene_camera_find(seq->scene)) { if (seq->scene == scene) { diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index 96a1a13b75f..3c1a18316ca 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -325,8 +325,7 @@ void free_pointdensities(Render *re) } } -typedef struct PointDensityRangeData -{ +typedef struct PointDensityRangeData { float *density; float squared_radius; float *point_data; diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 5c45be3f03a..f6fe8e8974d 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -3534,8 +3534,7 @@ Material *RE_init_sample_material(Material *orig_mat, Scene *scene) /* update image sequences and movies */ if (tex->ima && ELEM(tex->ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { - if (tex->iuser.flag & IMA_ANIM_ALWAYS) - BKE_image_user_frame_calc(&tex->iuser, (int)scene->r.cfra, 0); + BKE_image_user_check_frame_calc(&tex->iuser, (int)scene->r.cfra, 0); } } } diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index b599da48803..75748696a72 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -71,7 +71,7 @@ extern struct Render R; /* luminance rec. 709 */ BLI_INLINE float luminance(const float col[3]) { - return (0.212671f*col[0] + 0.71516f*col[1] + 0.072169f*col[2]); + return (0.212671f * col[0] + 0.71516f * col[1] + 0.072169f * col[2]); } /* tracing */ @@ -80,7 +80,7 @@ static float vol_get_shadow(ShadeInput *shi, LampRen *lar, const float co[3]) float visibility = 1.f; if (lar->shb) { - float dxco[3]={0.f, 0.f, 0.f}, dyco[3]={0.f, 0.f, 0.f}; + float dxco[3] = {0.f, 0.f, 0.f}, dyco[3] = {0.f, 0.f, 0.f}; visibility = testshadowbuf(&R, lar->shb, co, dxco, dyco, 1.0, 0.0); } @@ -89,7 +89,7 @@ static float vol_get_shadow(ShadeInput *shi, LampRen *lar, const float co[3]) Isect is; copy_v3_v3(is.start, co); - if (lar->type==LA_SUN || lar->type==LA_HEMI) { + if (lar->type == LA_SUN || lar->type == LA_HEMI) { is.dir[0] = -lar->vec[0]; is.dir[1] = -lar->vec[1]; is.dir[2] = -lar->vec[2]; @@ -97,17 +97,17 @@ static float vol_get_shadow(ShadeInput *shi, LampRen *lar, const float co[3]) } else { sub_v3_v3v3(is.dir, lar->co, is.start); - is.dist = normalize_v3(is.dir ); + is.dist = normalize_v3(is.dir); } is.mode = RE_RAY_MIRROR; is.check = RE_CHECK_VLR_NON_SOLID_MATERIAL; is.skip = 0; - if (lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) - is.lay= lar->lay; + if (lar->mode & (LA_LAYER | LA_LAYER_SHADOW)) + is.lay = lar->lay; else - is.lay= -1; + is.lay = -1; is.orig.ob = NULL; is.orig.face = NULL; @@ -117,7 +117,7 @@ static float vol_get_shadow(ShadeInput *shi, LampRen *lar, const float co[3]) visibility = 0.f; } - lar->last_hit[shi->thread]= is.last_hit; + lar->last_hit[shi->thread] = is.last_hit; } return visibility; } @@ -128,26 +128,26 @@ static int vol_get_bounds(ShadeInput *shi, const float co[3], const float vec[3] copy_v3_v3(isect->start, co); copy_v3_v3(isect->dir, vec); isect->dist = FLT_MAX; - isect->mode= RE_RAY_MIRROR; + isect->mode = RE_RAY_MIRROR; isect->last_hit = NULL; - isect->lay= -1; - isect->check= RE_CHECK_VLR_NONE; + isect->lay = -1; + isect->check = RE_CHECK_VLR_NONE; if (intersect_type == VOL_BOUNDS_DEPTH) { isect->skip = RE_SKIP_VLR_NEIGHBOUR; - isect->orig.face = (void*)shi->vlr; - isect->orig.ob = (void*)shi->obi; + isect->orig.face = (void *)shi->vlr; + isect->orig.ob = (void *)shi->obi; } else { // if (intersect_type == VOL_BOUNDS_SS) { - isect->skip= 0; - isect->orig.face= NULL; + isect->skip = 0; + isect->orig.face = NULL; isect->orig.ob = NULL; } if (RE_rayobject_raycast(R.raytree, isect)) { - hitco[0] = isect->start[0] + isect->dist*isect->dir[0]; - hitco[1] = isect->start[1] + isect->dist*isect->dir[1]; - hitco[2] = isect->start[2] + isect->dist*isect->dir[2]; + hitco[0] = isect->start[0] + isect->dist * isect->dir[0]; + hitco[1] = isect->start[1] + isect->dist * isect->dir[1]; + hitco[2] = isect->start[2] + isect->dist * isect->dir[2]; return 1; } else { @@ -162,18 +162,18 @@ static void shade_intersection(ShadeInput *shi, float col_r[4], Isect *is) memset(&shi_new, 0, sizeof(ShadeInput)); - shi_new.mask= shi->mask; - shi_new.osatex= shi->osatex; - shi_new.thread= shi->thread; + shi_new.mask = shi->mask; + shi_new.osatex = shi->osatex; + shi_new.thread = shi->thread; shi_new.depth = shi->depth + 1; - shi_new.volume_depth= shi->volume_depth + 1; - shi_new.xs= shi->xs; - shi_new.ys= shi->ys; - shi_new.lay= shi->lay; - shi_new.passflag= SCE_PASS_COMBINED; /* result of tracing needs no pass info */ - shi_new.combinedflag= 0xFFFFFF; /* ray trace does all options */ - shi_new.light_override= shi->light_override; - shi_new.mat_override= shi->mat_override; + shi_new.volume_depth = shi->volume_depth + 1; + shi_new.xs = shi->xs; + shi_new.ys = shi->ys; + shi_new.lay = shi->lay; + shi_new.passflag = SCE_PASS_COMBINED; /* result of tracing needs no pass info */ + shi_new.combinedflag = 0xFFFFFF; /* ray trace does all options */ + shi_new.light_override = shi->light_override; + shi_new.mat_override = shi->mat_override; copy_v3_v3(shi_new.camera_co, is->start); @@ -196,13 +196,13 @@ static void vol_trace_behind(ShadeInput *shi, VlakRen *vlr, const float co[3], f copy_v3_v3(isect.dir, shi->view); isect.dist = FLT_MAX; - isect.mode= RE_RAY_MIRROR; + isect.mode = RE_RAY_MIRROR; isect.check = RE_CHECK_VLR_NONE; isect.skip = RE_SKIP_VLR_NEIGHBOUR; - isect.orig.ob = (void*) shi->obi; - isect.orig.face = (void*)vlr; + isect.orig.ob = (void *) shi->obi; + isect.orig.face = (void *)vlr; isect.last_hit = NULL; - isect.lay= -1; + isect.lay = -1; /* check to see if there's anything behind the volume, otherwise shade the sky */ if (RE_rayobject_raycast(R.raytree, &isect)) { @@ -241,11 +241,11 @@ static void vol_get_precached_scattering(Render *re, ShadeInput *shi, float scat /* Meta object density, brute force for now * (might be good enough anyway, don't need huge number of metaobs to model volumetric objects */ -static float metadensity(Object* ob, const float co[3]) +static float metadensity(Object *ob, const float co[3]) { float mat[4][4], imat[4][4], dens = 0.f; - MetaBall* mb = (MetaBall*)ob->data; - MetaElem* ml; + MetaBall *mb = (MetaBall *)ob->data; + MetaElem *ml; /* transform co to meta-element */ float tco[3] = {co[0], co[1], co[2]}; @@ -253,13 +253,13 @@ static float metadensity(Object* ob, const float co[3]) invert_m4_m4(imat, mat); mul_m4_v3(imat, tco); - for (ml = mb->elems.first; ml; ml=ml->next) { + for (ml = mb->elems.first; ml; ml = ml->next) { float bmat[3][3], dist2; /* element rotation transform */ float tp[3] = {ml->x - tco[0], ml->y - tco[1], ml->z - tco[2]}; quat_to_mat3(bmat, ml->quat); - transpose_m3(bmat); // rot.only, so inverse == transpose + transpose_m3(bmat); // rot.only, so inverse == transpose mul_m3_v3(bmat, tp); /* MB_BALL default */ @@ -269,10 +269,10 @@ static float metadensity(Object* ob, const float co[3]) break; case MB_CUBE: tp[2] = (tp[2] > ml->expz) ? (tp[2] - ml->expz) : ((tp[2] < -ml->expz) ? (tp[2] + ml->expz) : 0.f); - // no break, xy as plane + // no break, xy as plane case MB_PLANE: tp[1] = (tp[1] > ml->expy) ? (tp[1] - ml->expy) : ((tp[1] < -ml->expy) ? (tp[1] + ml->expy) : 0.f); - // no break, x as tube + // no break, x as tube case MB_TUBE: tp[0] = (tp[0] > ml->expx) ? (tp[0] - ml->expx) : ((tp[0] < -ml->expx) ? (tp[0] + ml->expx) : 0.f); } @@ -280,7 +280,7 @@ static float metadensity(Object* ob, const float co[3]) /* ml->rad2 is not set */ dist2 = 1.0f - (dot_v3v3(tp, tp) / (ml->rad * ml->rad)); if (dist2 > 0.f) - dens += (ml->flag & MB_NEGATIVE) ? -ml->s*dist2*dist2*dist2 : ml->s*dist2*dist2*dist2; + dens += (ml->flag & MB_NEGATIVE) ? -ml->s * dist2 * dist2 * dist2 : ml->s * dist2 * dist2 * dist2; } dens -= mb->thresh; @@ -299,7 +299,7 @@ float vol_get_density(struct ShadeInput *shi, const float co[3]) if (shi->obi->obr->ob->type == OB_MBALL) { const float md = metadensity(shi->obi->obr->ob, co); if (md < 1.f) density *= md; - } + } return density * density_scale; } @@ -311,11 +311,11 @@ float vol_get_density(struct ShadeInput *shi, const float co[3]) static void vol_get_reflection_color(ShadeInput *shi, float ref_col[3], const float co[3]) { float scatter = shi->mat->vol.scattering; - float reflection= shi->mat->vol.reflection; + float reflection = shi->mat->vol.reflection; copy_v3_v3(ref_col, shi->mat->vol.reflection_col); - if (shi->mat->mapto_textured & (MAP_SCATTERING+MAP_REFLECTION_COL)) - do_volume_tex(shi, co, MAP_SCATTERING+MAP_REFLECTION_COL, ref_col, &scatter, &R); + if (shi->mat->mapto_textured & (MAP_SCATTERING + MAP_REFLECTION_COL)) + do_volume_tex(shi, co, MAP_SCATTERING + MAP_REFLECTION_COL, ref_col, &scatter, &R); /* only one single float parameter at a time... :s */ if (shi->mat->mapto_textured & (MAP_REFLECTION)) @@ -333,8 +333,8 @@ static void vol_get_emission(ShadeInput *shi, float emission_col[3], const float float emission = shi->mat->vol.emission; copy_v3_v3(emission_col, shi->mat->vol.emission_col); - if (shi->mat->mapto_textured & (MAP_EMISSION+MAP_EMISSION_COL)) - do_volume_tex(shi, co, MAP_EMISSION+MAP_EMISSION_COL, emission_col, &emission, &R); + if (shi->mat->mapto_textured & (MAP_EMISSION + MAP_EMISSION_COL)) + do_volume_tex(shi, co, MAP_EMISSION + MAP_EMISSION_COL, emission_col, &emission, &R); emission_col[0] = emission_col[0] * emission; emission_col[1] = emission_col[1] * emission; @@ -353,8 +353,8 @@ static void vol_get_sigma_t(ShadeInput *shi, float sigma_t[3], const float co[3] float transmission_col[3] = {shi->mat->vol.transmission_col[0], shi->mat->vol.transmission_col[1], shi->mat->vol.transmission_col[2]}; float scattering = shi->mat->vol.scattering; - if (shi->mat->mapto_textured & (MAP_SCATTERING+MAP_TRANSMISSION_COL)) - do_volume_tex(shi, co, MAP_SCATTERING+MAP_TRANSMISSION_COL, transmission_col, &scattering, &R); + if (shi->mat->mapto_textured & (MAP_SCATTERING + MAP_TRANSMISSION_COL)) + do_volume_tex(shi, co, MAP_SCATTERING + MAP_TRANSMISSION_COL, transmission_col, &scattering, &R); sigma_t[0] = (1.0f - transmission_col[0]) + scattering; sigma_t[1] = (1.0f - transmission_col[1]) + scattering; @@ -378,13 +378,13 @@ static float vol_get_phasefunc(ShadeInput *UNUSED(shi), float g, const float w[3 * until Blender's shading system supports this better. --matt */ - if (g == 0.f) { /* isotropic */ + if (g == 0.f) { /* isotropic */ return normalize * 1.f; } - else { /* schlick */ + else { /* schlick */ const float k = 1.55f * g - .55f * g * g * g; const float kcostheta = k * dot_v3v3(w, wp); - return normalize * (1.f - k*k) / ((1.f - kcostheta) * (1.f - kcostheta)); + return normalize * (1.f - k * k) / ((1.f - kcostheta) * (1.f - kcostheta)); } /* not used, but here for reference: */ @@ -395,14 +395,14 @@ static float vol_get_phasefunc(ShadeInput *UNUSED(shi), float g, const float w[3 case MA_VOL_PH_MIEMURKY: return normalize * (0.5f + 16.5f * powf(0.5 * (1.f + costheta), 32.f)); case MA_VOL_PH_RAYLEIGH: - return normalize * 3.f/4.f * (1 + costheta * costheta); + return normalize * 3.f / 4.f * (1 + costheta * costheta); case MA_VOL_PH_HG: return normalize * (1.f - g * g) / powf(1.f + g * g - 2.f * g * costheta, 1.5f); case MA_VOL_PH_SCHLICK: { const float k = 1.55f * g - .55f * g * g * g; const float kcostheta = k * costheta; - return normalize * (1.f - k*k) / ((1.f - kcostheta) * (1.f - kcostheta)); + return normalize * (1.f - k * k) / ((1.f - kcostheta) * (1.f - kcostheta)); } case MA_VOL_PH_ISOTROPIC: default: @@ -471,20 +471,20 @@ static void vol_get_transmittance(ShadeInput *shi, float tr[3], const float co[3 static void vol_shade_one_lamp(struct ShadeInput *shi, const float co[3], const float view[3], LampRen *lar, float lacol[3]) { float visifac, lv[3], lampdist; - float tr[3]={1.0, 1.0, 1.0}; + float tr[3] = {1.0, 1.0, 1.0}; float hitco[3], *atten_co; float p, ref_col[3]; - if (lar->mode & LA_LAYER) if ((lar->lay & shi->obi->lay)==0) return; - if ((lar->lay & shi->lay)==0) return; + if (lar->mode & LA_LAYER) if ((lar->lay & shi->obi->lay) == 0) return; + if ((lar->lay & shi->lay) == 0) return; if (lar->energy == 0.0f) return; - if ((visifac= lamp_get_visibility(lar, co, lv, &lampdist)) == 0.f) return; + if ((visifac = lamp_get_visibility(lar, co, lv, &lampdist)) == 0.f) return; copy_v3_v3(lacol, &lar->r); if (lar->mode & LA_TEXTURE) { - shi->osatex= 0; + shi->osatex = 0; do_lamp_tex(lar, lv, shi, lacol, LA_TEXTURE); } @@ -519,7 +519,7 @@ static void vol_shade_one_lamp(struct ShadeInput *shi, const float co[3], const if (ELEM(lar->type, LA_SUN, LA_HEMI)) /* infinite lights, can never be inside volume */ atten_co = hitco; - else if ( lampdist < dist ) { + else if (lampdist < dist) { atten_co = lar->co; } else @@ -558,10 +558,10 @@ void vol_get_scattering(ShadeInput *shi, float scatter_col[3], const float co[3] zero_v3(scatter_col); - lights= get_lights(shi); - for (go=lights->first; go; go= go->next) { + lights = get_lights(shi); + for (go = lights->first; go; go = go->next) { float lacol[3] = {0.f, 0.f, 0.f}; - lar= go->lampren; + lar = go->lampren; if (lar) { vol_shade_one_lamp(shi, co, view, lar, lacol); @@ -598,7 +598,7 @@ static void volumeintegrate(struct ShadeInput *shi, float col[4], const float co float t0 = 0.f; float pt0 = t0; - float t1 = normalize_v3(step_vec); /* returns vector length */ + float t1 = normalize_v3(step_vec); /* returns vector length */ t0 += stepsize * ((shi->mat->vol.stepsize_type == MA_VOL_STEP_CONSTANT) ? 0.5f : BLI_thread_frand(shi->thread)); p[0] += t0 * step_vec[0]; @@ -656,7 +656,7 @@ static void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr, int in float hitco[3], col[4] = {0.f, 0.f, 0.f, 0.f}; float *startco, *endco; int trace_behind = 1; - const int ztransp= ((shi->depth==0) && (shi->mat->mode & MA_TRANSP) && (shi->mat->mode & MA_ZTRANSP)); + const int ztransp = ((shi->depth == 0) && (shi->mat->mode & MA_TRANSP) && (shi->mat->mode & MA_ZTRANSP)); Isect is; /* check for shading an internal face a volume object directly */ @@ -669,7 +669,7 @@ static void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr, int in if (ztransp && inside_volume == VOL_SHADE_INSIDE) { MatInside *mi; - int render_this=0; + int render_this = 0; /* don't render the backfaces of ztransp volume materials. * @@ -683,9 +683,9 @@ static void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr, int in * which would otherwise render the volume in between the camera and the backface * --matt */ - for (mi=R.render_volumes_inside.first; mi; mi=mi->next) { + for (mi = R.render_volumes_inside.first; mi; mi = mi->next) { /* weak... */ - if (mi->ma == shi->mat) render_this=1; + if (mi->ma == shi->mat) render_this = 1; } if (!render_this) return; } @@ -733,7 +733,7 @@ static void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr, int in } if (ztransp) - col[3] = col[3]>1.f?1.f:col[3]; + col[3] = col[3] > 1.f ? 1.f : col[3]; else col[3] = 1.f; @@ -749,7 +749,7 @@ void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct { float hitco[3]; float tr[3] = {1.0, 1.0, 1.0}; - Isect is= {{0}}; + Isect is = {{0}}; float *startco, *endco; memset(shr, 0, sizeof(ShadeResult)); @@ -825,5 +825,3 @@ void shade_volume_inside(ShadeInput *shi, ShadeResult *shr) shi->obi = obi_backup; shi->obr = obi_backup->obr; } - - diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index 90e6594d888..7d54f77fc90 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -66,10 +66,10 @@ static int is_vd_res_ok(VoxelData *vd) { /* arbitrary large value so corrupt headers don't break */ - const int min= 1, max= 100000; - return (vd->resol[0] >= min && vd->resol[0] <= max) && - (vd->resol[1] >= min && vd->resol[1] <= max) && - (vd->resol[2] >= min && vd->resol[2] <= max); + const int min = 1, max = 100000; + return (vd->resol[0] >= min && vd->resol[0] <= max) && + (vd->resol[1] >= min && vd->resol[1] <= max) && + (vd->resol[2] >= min && vd->resol[2] <= max); } /* use size_t because the result may exceed INT_MAX */ @@ -86,10 +86,10 @@ static int load_frame_blendervoxel(VoxelData *vd, FILE *fp, int frame) if (is_vd_res_ok(vd) == FALSE) return 0; - vd->dataset = MEM_mapallocN(sizeof(float)*size, "voxel dataset"); + vd->dataset = MEM_mapallocN(sizeof(float) * size, "voxel dataset"); if (vd->dataset == NULL) return 0; - if (fseek(fp, frame*size*sizeof(float)+offset, 0) == -1) + if (fseek(fp, frame * size * sizeof(float) + offset, 0) == -1) return 0; if (fread(vd->dataset, sizeof(float), size, fp) != size) return 0; @@ -108,29 +108,29 @@ static int load_frame_raw8(VoxelData *vd, FILE *fp, int frame) if (is_vd_res_ok(vd) == FALSE) return 0; - vd->dataset = MEM_mapallocN(sizeof(float)*size, "voxel dataset"); + vd->dataset = MEM_mapallocN(sizeof(float) * size, "voxel dataset"); if (vd->dataset == NULL) return 0; - data_c = (char *)MEM_mallocN(sizeof(char)*size, "temporary voxel file reading storage"); + data_c = (char *)MEM_mallocN(sizeof(char) * size, "temporary voxel file reading storage"); if (data_c == NULL) { MEM_freeN(vd->dataset); - vd->dataset= NULL; + vd->dataset = NULL; return 0; } - if (fseek(fp, (frame-1)*size*sizeof(char), 0) == -1) { + if (fseek(fp, (frame - 1) * size * sizeof(char), 0) == -1) { MEM_freeN(data_c); MEM_freeN(vd->dataset); - vd->dataset= NULL; + vd->dataset = NULL; return 0; } if (fread(data_c, sizeof(char), size, fp) != size) { MEM_freeN(data_c); MEM_freeN(vd->dataset); - vd->dataset= NULL; + vd->dataset = NULL; return 0; } - for (i=0; i<size; i++) { + for (i = 0; i < size; i++) { vd->dataset[i] = (float)data_c[i] / 255.f; } MEM_freeN(data_c); @@ -146,7 +146,7 @@ static void load_frame_image_sequence(VoxelData *vd, Tex *tex) Image *ima = tex->ima; ImageUser *tiuser = &tex->iuser; ImageUser iuser = *(tiuser); - int x=0, y=0, z=0; + int x = 0, y = 0, z = 0; float *rf; if (!ima || !tiuser) return; @@ -157,10 +157,10 @@ static void load_frame_image_sequence(VoxelData *vd, Tex *tex) /* find the first valid ibuf and use it to initialize the resolution of the data set */ /* need to do this in advance so we know how much memory to allocate */ - ibuf= BKE_image_get_ibuf(ima, &iuser); + ibuf = BKE_image_get_ibuf(ima, &iuser); while (!ibuf && (iuser.framenr < iuser.frames)) { iuser.framenr++; - ibuf= BKE_image_get_ibuf(ima, &iuser); + ibuf = BKE_image_get_ibuf(ima, &iuser); } if (!ibuf) return; if (!ibuf->rect_float) IMB_float_from_rect(ibuf); @@ -169,23 +169,23 @@ static void load_frame_image_sequence(VoxelData *vd, Tex *tex) vd->resol[0] = ibuf->x; vd->resol[1] = ibuf->y; vd->resol[2] = iuser.frames; - vd->dataset = MEM_mapallocN(sizeof(float)*vd_resol_size(vd), "voxel dataset"); + vd->dataset = MEM_mapallocN(sizeof(float) * vd_resol_size(vd), "voxel dataset"); - for (z=0; z < iuser.frames; z++) { + for (z = 0; z < iuser.frames; z++) { /* get a new ibuf for each frame */ if (z > 0) { iuser.framenr++; - ibuf= BKE_image_get_ibuf(ima, &iuser); + ibuf = BKE_image_get_ibuf(ima, &iuser); if (!ibuf) break; if (!ibuf->rect_float) IMB_float_from_rect(ibuf); } rf = ibuf->rect_float; - for (y=0; y < ibuf->y; y++) { - for (x=0; x < ibuf->x; x++) { + for (y = 0; y < ibuf->y; y++) { + for (x = 0; x < ibuf->x; x++) { /* currently averaged to monchrome */ - vd->dataset[ BLI_VOXEL_INDEX(x, y, z, vd->resol) ] = (rf[0] + rf[1] + rf[2]) * 0.333f; - rf +=4; + vd->dataset[BLI_VOXEL_INDEX(x, y, z, vd->resol)] = (rf[0] + rf[1] + rf[2]) * 0.333f; + rf += 4; } } @@ -198,7 +198,7 @@ static void load_frame_image_sequence(VoxelData *vd, Tex *tex) static int read_voxeldata_header(FILE *fp, struct VoxelData *vd) { - VoxelDataHeader *h=(VoxelDataHeader *)MEM_mallocN(sizeof(VoxelDataHeader), "voxel data header"); + VoxelDataHeader *h = (VoxelDataHeader *)MEM_mallocN(sizeof(VoxelDataHeader), "voxel data header"); rewind(fp); if (fread(h, sizeof(VoxelDataHeader), 1, fp) != 1) { @@ -206,9 +206,9 @@ static int read_voxeldata_header(FILE *fp, struct VoxelData *vd) return 0; } - vd->resol[0]=h->resolX; - vd->resol[1]=h->resolY; - vd->resol[2]=h->resolZ; + vd->resol[0] = h->resolX; + vd->resol[1] = h->resolY; + vd->resol[2] = h->resolZ; MEM_freeN(h); return 1; @@ -221,8 +221,8 @@ static void init_frame_smoke(VoxelData *vd, float cfra) ModifierData *md; vd->dataset = NULL; - if (vd->object == NULL) return; - ob= vd->object; + if (vd->object == NULL) return; + ob = vd->object; /* draw code for smoke */ if ((md = (ModifierData *)modifiers_findByType(ob, eModifierType_Smoke))) { @@ -231,23 +231,23 @@ static void init_frame_smoke(VoxelData *vd, float cfra) if (smd->domain && smd->domain->fluid) { if (cfra < smd->domain->point_cache[0]->startframe) - ; /* don't show smoke before simulation starts, this could be made an option in the future */ + ; /* don't show smoke before simulation starts, this could be made an option in the future */ else if (vd->smoked_type == TEX_VD_SMOKEHEAT) { size_t totRes; size_t i; float *heat; copy_v3_v3_int(vd->resol, smd->domain->res); - totRes= vd_resol_size(vd); + totRes = vd_resol_size(vd); // scaling heat values from -2.0-2.0 to 0.0-1.0 - vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data"); + vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data"); heat = smoke_get_heat(smd->domain->fluid); - for (i=0; i<totRes; i++) { - vd->dataset[i] = (heat[i]+2.0f)/4.0f; + for (i = 0; i < totRes; i++) { + vd->dataset[i] = (heat[i] + 2.0f) / 4.0f; } //vd->dataset = smoke_get_heat(smd->domain->fluid); @@ -258,17 +258,17 @@ static void init_frame_smoke(VoxelData *vd, float cfra) float *xvel, *yvel, *zvel; copy_v3_v3_int(vd->resol, smd->domain->res); - totRes= vd_resol_size(vd); + totRes = vd_resol_size(vd); // scaling heat values from -2.0-2.0 to 0.0-1.0 - vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data"); + vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data"); xvel = smoke_get_velocity_x(smd->domain->fluid); yvel = smoke_get_velocity_y(smd->domain->fluid); zvel = smoke_get_velocity_z(smd->domain->fluid); - for (i=0; i<totRes; i++) { - vd->dataset[i] = sqrt(xvel[i]*xvel[i] + yvel[i]*yvel[i] + zvel[i]*zvel[i])*3.0f; + for (i = 0; i < totRes; i++) { + vd->dataset[i] = sqrt(xvel[i] * xvel[i] + yvel[i] * yvel[i] + zvel[i] * zvel[i]) * 3.0f; } } @@ -286,10 +286,10 @@ static void init_frame_smoke(VoxelData *vd, float cfra) } /* TODO: is_vd_res_ok(rvd) doesnt check this resolution */ - totRes= vd_resol_size(vd); + totRes = vd_resol_size(vd); /* always store copy, as smoke internal data can change */ - vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data"); - memcpy(vd->dataset, density, sizeof(float)*totRes); + vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data"); + memcpy(vd->dataset, density, sizeof(float) * totRes); } // end of fluid condition } } @@ -300,7 +300,7 @@ static void init_frame_smoke(VoxelData *vd, float cfra) (void)vd; (void)cfra; - vd->dataset= NULL; + vd->dataset = NULL; #endif } @@ -342,7 +342,7 @@ void cache_voxeldata(Tex *tex, int scene_frame) if (!fp) return; if (read_voxeldata_header(fp, vd)) - load_frame_blendervoxel(vd, fp, curframe-1); + load_frame_blendervoxel(vd, fp, curframe - 1); fclose(fp); return; @@ -362,17 +362,17 @@ void make_voxeldata(struct Render *re) { Tex *tex; - re->i.infostr= "Loading voxel datasets"; + re->i.infostr = "Loading voxel datasets"; re->stats_draw(re->sdh, &re->i); /* XXX: should be doing only textures used in this render */ - for (tex= re->main->tex.first; tex; tex= tex->id.next) { - if (tex->id.us && tex->type==TEX_VOXELDATA) { + for (tex = re->main->tex.first; tex; tex = tex->id.next) { + if (tex->id.us && tex->type == TEX_VOXELDATA) { cache_voxeldata(tex, re->r.cfra); } } - re->i.infostr= NULL; + re->i.infostr = NULL; re->stats_draw(re->sdh, &re->i); } @@ -383,7 +383,7 @@ int voxeldatatex(struct Tex *tex, const float texvec[3], struct TexResult *texre VoxelData *vd = tex->vd; float co[3], offset[3] = {0.5, 0.5, 0.5}; - if (vd->dataset==NULL) { + if (vd->dataset == NULL) { texres->tin = 0.0f; return 0; } @@ -448,5 +448,3 @@ int voxeldatatex(struct Tex *tex, const float texvec[3], struct TexResult *texre return retval; } - - diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index a3bc4f87b60..72d2bf9d1f1 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -167,7 +167,8 @@ typedef struct wmNotifier { #define NC_ID (18<<24) #define NC_LOGIC (19<<24) #define NC_MOVIECLIP (20<<24) -#define NC_LINESTYLE (21<<24) +#define NC_MASK (21<<24) +#define NC_LINESTYLE (22<<24) /* data type, 256 entries is enough, it can overlap */ #define NOTE_DATA 0x00FF0000 @@ -385,7 +386,7 @@ typedef struct wmTabletData { float Ytilt; /* as above */ } wmTabletData; -typedef enum { // motion progress, for modal handlers +typedef enum { /* motion progress, for modal handlers */ P_NOT_STARTED, P_STARTING, // <-- P_IN_PROGRESS, // <-- only these are sent for NDOF motion diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 42787be8e02..425baac25fd 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2162,7 +2162,11 @@ static int wm_collada_export_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED static int wm_collada_export_exec(bContext *C, wmOperator *op) { char filename[FILE_MAX]; - int selected, second_life, apply_modifiers, include_bone_children, use_object_instantiation; + int selected, second_life, + include_armatures, + apply_modifiers, + include_bone_children, + use_object_instantiation; if (!RNA_struct_property_is_set(op->ptr, "filepath")) { BKE_report(op->reports, RPT_ERROR, "No filename given"); @@ -2174,8 +2178,9 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) /* Options panel */ selected = RNA_boolean_get(op->ptr, "selected"); apply_modifiers = RNA_boolean_get(op->ptr, "apply_modifiers"); - include_bone_children = RNA_boolean_get(op->ptr, "include_bone_children"); - use_object_instantiation = RNA_boolean_get(op->ptr, "use_object_instantiation"); + include_armatures = RNA_boolean_get(op->ptr, "include_armatures"); + include_bone_children = RNA_boolean_get(op->ptr, "include_bone_children"); + use_object_instantiation = RNA_boolean_get(op->ptr, "use_object_instantiation"); second_life = RNA_boolean_get(op->ptr, "second_life"); /* get editmode results */ @@ -2186,6 +2191,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) filename, selected, apply_modifiers, + include_armatures, include_bone_children, use_object_instantiation, second_life)) { @@ -2216,6 +2222,9 @@ static void WM_OT_collada_export(wmOperatorType *ot) RNA_def_boolean(ot->srna, "apply_modifiers", 0, "Apply Modifiers", "Apply modifiers (Preview Resolution)"); + RNA_def_boolean(ot->srna, "include_armatures", 0, "Include Armatures", + "Include armature(s) used by the exported objects"); + RNA_def_boolean(ot->srna, "include_bone_children", 0, "Include Bone Children", "Include all objects attached to bones of selected Armature(s)"); @@ -3853,6 +3862,7 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "VIEW3D_OT_select_circle"); WM_modalkeymap_assign(keymap, "UV_OT_circle_select"); WM_modalkeymap_assign(keymap, "CLIP_OT_select_circle"); + WM_modalkeymap_assign(keymap, "MASK_OT_select_circle"); } @@ -3936,6 +3946,7 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "UV_OT_select_border"); WM_modalkeymap_assign(keymap, "CLIP_OT_select_border"); WM_modalkeymap_assign(keymap, "CLIP_OT_graph_select_border"); + WM_modalkeymap_assign(keymap, "MASK_OT_select_border"); WM_modalkeymap_assign(keymap, "VIEW2D_OT_zoom_border"); WM_modalkeymap_assign(keymap, "VIEW3D_OT_clip_border"); WM_modalkeymap_assign(keymap, "VIEW3D_OT_render_border"); @@ -4155,3 +4166,13 @@ EnumPropertyItem *RNA_movieclip_local_itemf(bContext *C, PointerRNA *ptr, Proper { return rna_id_itemf(C, ptr, do_free, C ? (ID *)CTX_data_main(C)->movieclip.first : NULL, TRUE); } + +EnumPropertyItem *RNA_mask_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *do_free) +{ + return rna_id_itemf(C, ptr, do_free, C ? (ID *)CTX_data_main(C)->mask.first : NULL, FALSE); +} +EnumPropertyItem *RNA_mask_local_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *do_free) +{ + return rna_id_itemf(C, ptr, do_free, C ? (ID *)CTX_data_main(C)->mask.first : NULL, TRUE); +} + diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 7361e74755e..265a3c11377 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -577,12 +577,11 @@ int wm_window_fullscreen_toggle_exec(bContext *C, wmOperator *UNUSED(op)) /* ************ events *************** */ -typedef enum -{ - SHIFT = 's', - CONTROL = 'c', - ALT = 'a', - OS = 'C' +typedef enum { + SHIFT = 's', + CONTROL = 'c', + ALT = 'a', + OS = 'C' } modifierKeyType; /* check if specified modifier key type is pressed */ diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt index 674d5540c8b..99db5576fa0 100644 --- a/source/blenderplayer/CMakeLists.txt +++ b/source/blenderplayer/CMakeLists.txt @@ -31,12 +31,6 @@ if(WITH_CODEC_QUICKTIME) add_definitions(-DWITH_QUICKTIME) endif() -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/dna.c - COMMAND ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/makesdna ${CMAKE_CURRENT_BINARY_DIR}/dna.c ${CMAKE_SOURCE_DIR}/source/blender/makesdna/ - DEPENDS ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/makesdna -) - if(WIN32 AND NOT UNIX) string(SUBSTRING ${BLENDER_VERSION} 0 1 bver1) string(SUBSTRING ${BLENDER_VERSION} 2 1 bver2) @@ -60,10 +54,10 @@ if(WIN32 AND NOT UNIX) ) endif() - add_executable(blenderplayer ${EXETYPE} ${CMAKE_CURRENT_BINARY_DIR}/dna.c ../icons/winblender.rc) + add_executable(blenderplayer ${EXETYPE} bad_level_call_stubs/stubs.c ../icons/winblender.rc) elseif(APPLE) - add_executable(blenderplayer ${EXETYPE} ${CMAKE_CURRENT_BINARY_DIR}/dna.c) + add_executable(blenderplayer ${EXETYPE} bad_level_call_stubs/stubs.c) # setup Info.plist execute_process(COMMAND date "+%Y-%m-%d" OUTPUT_VARIABLE BLENDER_DATE OUTPUT_STRIP_TRAILING_WHITESPACE) set(PLAYER_SOURCEDIR ${CMAKE_SOURCE_DIR}/source/darwin/blenderplayer.app) @@ -74,7 +68,7 @@ elseif(APPLE) MACOSX_BUNDLE_LONG_VERSION_STRING "${BLENDER_VERSION} ${BLENDER_DATE}") else() - add_executable(blenderplayer ${CMAKE_CURRENT_BINARY_DIR}/dna.c) + add_executable(blenderplayer bad_level_call_stubs/stubs.c) endif() add_dependencies(blenderplayer makesdna) @@ -152,6 +146,7 @@ endif() bf_blenkernel # duplicate for linking bf_intern_mikktspace extern_recastnavigation + bf_intern_raskter ) if(WITH_MOD_CLOTH_ELTOPO) @@ -168,6 +163,7 @@ endif() if(WITH_LIBMV) list(APPEND BLENDER_SORTED_LIBS extern_libmv) + list(APPEND BLENDER_SORTED_LIBS extern_ceres) endif() list(APPEND BLENDER_SORTED_LIBS extern_colamd) diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 9f0e2749e34..324f0f3cada 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -231,6 +231,7 @@ void ED_space_image_uv_sculpt_update(struct wmWindowManager *wm, struct ToolSett void ED_screen_set_scene(struct bContext *C, struct Scene *scene) {} void ED_space_clip_set(struct bContext *C, struct SpaceClip *sc, struct MovieClip *clip) {} +void ED_space_clip_set_mask(struct bContext *C, struct SpaceClip *sc, struct Mask *mask){} void ED_area_tag_redraw_regiontype(struct ScrArea *sa, int regiontype) {} void ED_render_engine_changed(struct Main *bmain) {} diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 3be4758dc5e..c4f7400fa50 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -824,6 +824,7 @@ endif() bf_editor_sound bf_editor_animation bf_editor_datafiles + bf_editor_mask bf_render bf_intern_opennl @@ -896,10 +897,12 @@ endif() cycles_subd bf_compositor #added for opencl compositor bf_opencl #added for opencl compositor + bf_intern_raskter ) if(WITH_LIBMV) list(APPEND BLENDER_SORTED_LIBS extern_libmv) + list(APPEND BLENDER_SORTED_LIBS extern_ceres) endif() if(WITH_MOD_CLOTH_ELTOPO) diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp index f38782a9405..7174a563efa 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.cpp +++ b/source/gameengine/Converter/BL_ArmatureObject.cpp @@ -529,7 +529,7 @@ bool BL_ArmatureObject::SetActiveAction(BL_ActionActuator *act, short priority, return true; } - else{ + else { act->SetBlendTime(0.0); return false; } diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 3d73ca66c92..927a0535870 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -488,11 +488,10 @@ static void GetRGB(short type, } } -typedef struct MTF_localLayer -{ +typedef struct MTF_localLayer { MTFace *face; const char *name; -}MTF_localLayer; +} MTF_localLayer; // ------------------------------------ bool ConvertMaterial( @@ -1193,7 +1192,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, twoside = ((ma->game.flag & GEMAT_BACKCULL)==0); collider = ((ma->game.flag & GEMAT_NOPHYSICS)==0); } - else{ + else { visible = true; twoside = false; collider = true; diff --git a/source/gameengine/Converter/BL_DeformableGameObject.cpp b/source/gameengine/Converter/BL_DeformableGameObject.cpp index dd4c51b5403..4967401f279 100644 --- a/source/gameengine/Converter/BL_DeformableGameObject.cpp +++ b/source/gameengine/Converter/BL_DeformableGameObject.cpp @@ -76,7 +76,7 @@ bool BL_DeformableGameObject::SetActiveAction(BL_ShapeActionActuator *act, short return true; } - else{ + else { act->SetBlendTime(0.0f); return false; } diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.cpp b/source/gameengine/Converter/BL_ShapeActionActuator.cpp index 13e79b13304..c339e10f673 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.cpp +++ b/source/gameengine/Converter/BL_ShapeActionActuator.cpp @@ -316,7 +316,7 @@ bool BL_ShapeActionActuator::Update(double curtime, bool frame) m_localtime += (length/m_stridelength) * deltapos.length(); m_lastpos = newpos; } - else{ + else { SetLocalTime(curtime); } } @@ -466,7 +466,7 @@ bool BL_ShapeActionActuator::Update(double curtime, bool frame) BLI_freelistN(&tchanbase); } } - else{ + else { m_blendframe = 0.0f; } } diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 0613b137fe8..78e5d7b32c2 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -930,13 +930,34 @@ bool KX_BlenderSceneConverter::LinkBlendFilePath(const char *path, char *group, return LinkBlendFile(bpy_openlib, path, group, scene_merge, err_str, options); } -bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options) +static void load_datablocks(Main *main_newlib, BlendHandle *bpy_openlib, const char *path, int idcode) { - Main *main_newlib; /* stored as a dynamic 'main' until we free it */ Main *main_tmp= NULL; /* created only for linking, then freed */ LinkNode *names = NULL; - int idcode= BKE_idcode_from_name(group); short flag= 0; /* don't need any special options */ + + /* here appending/linking starts */ + main_tmp = BLO_library_append_begin(main_newlib, &bpy_openlib, (char *)path); + + int totnames_dummy; + names = BLO_blendhandle_get_datablock_names( bpy_openlib, idcode, &totnames_dummy); + + int i=0; + LinkNode *n= names; + while(n) { + BLO_library_append_named_part(main_tmp, &bpy_openlib, (char *)n->link, idcode); + n= (LinkNode *)n->next; + i++; + } + BLI_linklist_free(names, free); /* free linklist *and* each node's data */ + + BLO_library_append_end(NULL, main_tmp, &bpy_openlib, idcode, flag); +} + +bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options) +{ + Main *main_newlib; /* stored as a dynamic 'main' until we free it */ + int idcode= BKE_idcode_from_name(group); ReportList reports; static char err_local[255]; @@ -964,40 +985,11 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha main_newlib= (Main *)MEM_callocN( sizeof(Main), "BgeMain"); BKE_reports_init(&reports, RPT_STORE); - /* here appending/linking starts */ - main_tmp = BLO_library_append_begin(main_newlib, &bpy_openlib, (char *)path); - - int totnames_dummy; - names = BLO_blendhandle_get_datablock_names( bpy_openlib, idcode, &totnames_dummy); - - int i=0; - LinkNode *n= names; - while(n) { - BLO_library_append_named_part(main_tmp, &bpy_openlib, (char *)n->link, idcode); - n= (LinkNode *)n->next; - i++; - } - BLI_linklist_free(names, free); /* free linklist *and* each node's data */ - - BLO_library_append_end(NULL, main_tmp, &bpy_openlib, idcode, flag); + load_datablocks(main_newlib, bpy_openlib, path, idcode); /* now do another round of linking for Scenes so all actions are properly loaded */ if (idcode==ID_SCE && options & LIB_LOAD_LOAD_ACTIONS) { - main_tmp = BLO_library_append_begin(main_newlib, &bpy_openlib, (char *)path); - - int totnames_dummy; - names = BLO_blendhandle_get_datablock_names( bpy_openlib, ID_AC, &totnames_dummy); - - int i=0; - LinkNode *n= names; - while(n) { - BLO_library_append_named_part(main_tmp, &bpy_openlib, (char *)n->link, ID_AC); - n= (LinkNode *)n->next; - i++; - } - BLI_linklist_free(names, free); /* free linklist *and* each node's data */ - - BLO_library_append_end(NULL, main_tmp, &bpy_openlib, ID_AC, flag); + load_datablocks(main_newlib, bpy_openlib, path, ID_AC); } BLO_blendhandle_close(bpy_openlib); diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp index fa9eb5317b9..2bd1688ca6d 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.cpp +++ b/source/gameengine/Converter/KX_ConvertSensors.cpp @@ -302,7 +302,8 @@ void BL_ConvertSensors(struct Object* blenderobject, (blenderkeybdsensor->type == SENS_ALL_KEYS), blenderkeybdsensor->targetName, blenderkeybdsensor->toggleName, - gameobj); // blenderkeybdsensor->pad); + gameobj, + KX_KetsjiEngine::GetExitKey()); // blenderkeybdsensor->pad); } diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index 278febee4ac..c50e42446a5 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -527,7 +527,7 @@ typedef struct KX_PYATTRIBUTE_DEF { /*------------------------------ * PyObjectPlus ------------------------------*/ -typedef PyTypeObject * PyParentObject; // Define the PyParent Object +typedef PyTypeObject *PyParentObject; /* Define the PyParent Object */ #else // WITH_PYTHON diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index 00320ff9ed2..261f5244f21 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -158,7 +158,7 @@ class CAction public: CAction() { }; - virtual ~CAction(){ + virtual ~CAction() { }; virtual void Execute() const =0; diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.h b/source/gameengine/GameLogic/Joystick/SCA_Joystick.h index a6809716e32..685cc3fcc48 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.h +++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.h @@ -99,7 +99,7 @@ class SCA_Joystick void OnButtonDown(SDL_Event *sdl_event); void OnNothing(SDL_Event *sdl_event); #if 0 /* not used yet */ - void OnBallMotion(SDL_Event *sdl_event){} + void OnBallMotion(SDL_Event *sdl_event) {} #endif #endif /* WITH_SDL */ @@ -156,27 +156,27 @@ public: void cSetPrecision(int val); - int GetAxisPosition(int index){ + int GetAxisPosition(int index) { return m_axis_array[index]; } - int GetHat(int index){ + int GetHat(int index) { return m_hat_array[index]; } - int GetThreshold(void){ + int GetThreshold(void) { return m_prec; } - bool IsTrigAxis(void){ + bool IsTrigAxis(void) { return m_istrig_axis; } - bool IsTrigButton(void){ + bool IsTrigButton(void) { return m_istrig_button; } - bool IsTrigHat(void){ + bool IsTrigHat(void) { return m_istrig_hat; } diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp index 07fad3bfe37..c82e015919d 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp @@ -137,7 +137,8 @@ bool SCA_JoystickSensor::Evaluate() if (js->aAxisPairIsPositive(m_axis-1)) { /* use zero based axis index internally */ m_istrig = 1; result = true; - }else{ + } + else { if (m_istrig) { m_istrig = 0; result = true; @@ -148,7 +149,8 @@ bool SCA_JoystickSensor::Evaluate() if (js->aAxisPairDirectionIsPositive(m_axis-1, m_axisf)) { /* use zero based axis index internally */ m_istrig = 1; result = true; - }else{ + } + else { if (m_istrig) { m_istrig = 0; result = true; @@ -168,7 +170,8 @@ bool SCA_JoystickSensor::Evaluate() if (js->aAxisIsPositive(m_axis-1)) { /* use zero based axis index internally */ m_istrig = 1; result = true; - }else{ + } + else { if (m_istrig) { m_istrig = 0; result = true; @@ -209,7 +212,8 @@ bool SCA_JoystickSensor::Evaluate() if ((m_bAllEvents && js->GetHat(m_hat-1)) || js->aHatIsPositive(m_hat-1, m_hatf)) { m_istrig = 1; result = true; - }else{ + } + else { if (m_istrig) { m_istrig = 0; result = true; diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.h b/source/gameengine/GameLogic/SCA_JoystickSensor.h index eecbf2c4183..5dc35faf244 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.h +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.h @@ -117,7 +117,7 @@ public: virtual bool IsPositiveTrigger(); virtual void Init(); - short int GetJoyIndex(void){ + short int GetJoyIndex(void) { return m_joyindex; } diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp index b39ae209d67..5bdf2e96e93 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp @@ -54,7 +54,8 @@ SCA_KeyboardSensor::SCA_KeyboardSensor(SCA_KeyboardManager* keybdmgr, bool bAllKeys, const STR_String& targetProp, const STR_String& toggleProp, - SCA_IObject* gameobj) + SCA_IObject* gameobj, + short int exitKey) :SCA_ISensor(gameobj,keybdmgr), m_hotkey(hotkey), m_qual(qual), @@ -63,7 +64,7 @@ SCA_KeyboardSensor::SCA_KeyboardSensor(SCA_KeyboardManager* keybdmgr, m_targetprop(targetProp), m_toggleprop(toggleProp) { - if (hotkey == SCA_IInputDevice::KX_ESCKEY) + if (hotkey == exitKey) keybdmgr->GetInputDevice()->HookEscape(); // SetDrawColor(0xff0000ff); Init(); diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h index 8e21d6bfde1..778929a2551 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.h +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h @@ -94,7 +94,8 @@ public: bool bAllKeys, const STR_String& targetProp, const STR_String& toggleProp, - SCA_IObject* gameobj); + SCA_IObject* gameobj, + short int exitKey); virtual ~SCA_KeyboardSensor(); virtual CValue* GetReplica(); virtual void Init(); diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp index d0d940a2e42..ce183b37498 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp +++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp @@ -91,10 +91,10 @@ void SCA_PropertySensor::PrecalculateRangeExpression() //The context is needed to retrieve the property at runtime but it creates //loop of references pars.SetContext(this->AddRef()); - STR_String checkstr = "(" + m_checkpropval + " <= " - + m_checkpropname + ") && ( " - + m_checkpropname + " <= " - + m_checkpropmaxval + ")"; + STR_String checkstr = ("(" + m_checkpropval + " <= " + + m_checkpropname + ") && ( " + + m_checkpropname + " <= " + + m_checkpropmaxval + ")"); m_range_expr = pars.ProcessText(checkstr); } diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.cpp b/source/gameengine/GameLogic/SCA_RandomActuator.cpp index 40dba3bf03a..b0fc1431482 100644 --- a/source/gameengine/GameLogic/SCA_RandomActuator.cpp +++ b/source/gameengine/GameLogic/SCA_RandomActuator.cpp @@ -141,8 +141,7 @@ bool SCA_RandomActuator::Update() int res; /* The [0, 1] interval is projected onto the [min, max+1] domain, */ /* and then rounded. */ - res = (int) floor( ((m_parameter2 - m_parameter1 + 1) * m_base->DrawFloat()) - + m_parameter1); + res = (int)floor( ((m_parameter2 - m_parameter1 + 1) * m_base->DrawFloat()) + m_parameter1); tmpval = new CIntValue(res); } break; @@ -172,8 +171,7 @@ bool SCA_RandomActuator::Update() } break; case KX_RANDOMACT_FLOAT_UNIFORM: { - float res = ((m_parameter2 - m_parameter1) * m_base->DrawFloat()) - + m_parameter1; + float res = ((m_parameter2 - m_parameter1) * m_base->DrawFloat()) + m_parameter1; tmpval = new CFloatValue(res); } break; @@ -239,8 +237,7 @@ bool SCA_RandomActuator::Update() /* controlling parameter. Using the 'normal' exponent is not very */ /* intuitive... */ /* tmpval = new CFloatValue( (1.0 / m_parameter1) */ - tmpval = new CFloatValue( (m_parameter1) - * (-log(1.0 - m_base->DrawFloat())) ); + tmpval = new CFloatValue((m_parameter1) * (-log(1.0 - m_base->DrawFloat()))); } break; diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index 1e16cbd51f2..26cfc560b6d 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -118,8 +118,7 @@ static void mem_error_cb(const char *errorStr) } #ifdef WIN32 -typedef enum -{ +typedef enum { SCREEN_SAVER_MODE_NONE = 0, SCREEN_SAVER_MODE_PREVIEW, SCREEN_SAVER_MODE_SAVER, diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 018a8d44cc1..939f0693161 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -175,8 +175,8 @@ void KX_BlenderMaterial::OnConstruction(int layer) spit("unable to initialize image("<<i<<") in "<< mMaterial->matname<< ", image will not be available"); } - - else { + // If we're using glsl materials, the textures are handled by bf_gpu, so don't load them twice! + else if (!mMaterial->glslmat) { if ( mMaterial->img[i] ) { if ( ! mTextures[i].InitFromImage(i, mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 )) spit("unable to initialize image("<<i<<") in "<< diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.h b/source/gameengine/Ketsji/KX_BulletPhysicsController.h index 4ced21aa2d8..3b3a1f5cbfb 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.h +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.h @@ -86,7 +86,7 @@ public: SetOption( int option, int value - ){ + ) { // intentionally empty }; diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index eaabbdd8233..6d57b6950f1 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -445,7 +445,8 @@ void KX_Dome::GLDrawWarpQuads(void) } } glEnd(); - } else{ + } + else { printf("Dome Error: Warp Mode %d unsupported. Try 1 for Polar Mesh or 2 for Fisheye.\n", warp.mode); } } @@ -502,7 +503,8 @@ bool KX_Dome::ParseWarpMesh(STR_String text) if ((int)lines.size() < 2 + (warp.n_width * warp.n_height)) { printf("Dome Error: Warp Mesh File with insufficient data!\n"); return false; - }else{ + } + else { warp.nodes = vector<vector<WarpMeshNode> > (warp.n_height, vector<WarpMeshNode>(warp.n_width)); for (i=2; i-2 < (warp.n_width*warp.n_height); i++) { @@ -520,7 +522,7 @@ bool KX_Dome::ParseWarpMesh(STR_String text) warp.nodes[nodeY][nodeX].v = atof(columns[3]); warp.nodes[nodeY][nodeX].i = atof(columns[4]); } - else{ + else { warp.nodes.clear(); printf("Dome Error: Warp Mesh File with wrong number of fields. You should use 5: x y u v i.\n"); return false; @@ -1671,7 +1673,8 @@ void KX_Dome::DrawEnvMap(void) if (can_width/3 <= can_height/2) { ortho_width = 1.0; ortho_height = (float)can_height/can_width; - }else{ + } + else { ortho_height = 2.0f / 3; ortho_width = (float)can_width/can_height * ortho_height; } @@ -1801,7 +1804,8 @@ void KX_Dome::DrawDomeFisheye(void) if (can_width < can_height) { ortho_width = 1.0; ortho_height = (float)can_height/can_width; - }else{ + } + else { ortho_width = (float)can_width/can_height; ortho_height = 1.0; } @@ -1897,7 +1901,8 @@ void KX_Dome::DrawPanorama(void) if ((can_width / 2) <= (can_height)) { ortho_width = 1.0; ortho_height = (float)can_height/can_width; - }else{ + } + else { ortho_width = (float)can_width/can_height * 0.5; ortho_height = 0.5; } @@ -1995,7 +2000,7 @@ void KX_Dome::DrawDomeWarped(void) glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]); glCallList(dlistId + m_numfaces); } - else{ + else { glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]); GLDrawWarpQuads(); } diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index a173ef1ed8f..2b0d13ff2f7 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -712,7 +712,7 @@ public: void AddMesh( RAS_MeshObject* mesh - ){ + ) { m_meshes.push_back(mesh); } diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp index 9777eaf333e..7e7e7f8cef2 100644 --- a/source/gameengine/Ketsji/KX_IpoActuator.cpp +++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp @@ -297,7 +297,7 @@ bool KX_IpoActuator::Update(double curtime, bool frame) { SetLocalTime(curtime); } - else{ + else { if (!m_bNegativeEvent) { /* Perform wraparound */ SetLocalTime(curtime); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 0a50ab0a43a..f9c6d59b668 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -150,8 +150,7 @@ private: int m_curreye; /** Categories for profiling display. */ - typedef enum - { + typedef enum { tc_first = 0, tc_physics = 0, tc_logic, diff --git a/source/gameengine/Ketsji/KX_LightIpoSGController.h b/source/gameengine/Ketsji/KX_LightIpoSGController.h index 78466e822e7..15591bfa981 100644 --- a/source/gameengine/Ketsji/KX_LightIpoSGController.h +++ b/source/gameengine/Ketsji/KX_LightIpoSGController.h @@ -90,7 +90,7 @@ public: SetOption( int option, int value - ){ + ) { // intentionally empty }; diff --git a/source/gameengine/Ketsji/KX_MaterialIpoController.h b/source/gameengine/Ketsji/KX_MaterialIpoController.h index 85b2a971fbe..11d92925a02 100644 --- a/source/gameengine/Ketsji/KX_MaterialIpoController.h +++ b/source/gameengine/Ketsji/KX_MaterialIpoController.h @@ -49,7 +49,7 @@ public: SetOption( int option, int value - ){ + ) { // intentionally empty }; diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h index 8655d93d406..82f523283ed 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.h +++ b/source/gameengine/Ketsji/KX_NearSensor.h @@ -74,7 +74,7 @@ public: virtual void ReParent(SCA_IObject* parent); virtual bool NewHandleCollision(void* obj1,void* obj2, - const PHY_CollData * coll_data); + const PHY_CollData * coll_data); virtual bool BroadPhaseFilterCollision(void*obj1,void*obj2); virtual bool BroadPhaseSensorFilterCollision(void* obj1,void* obj2) { return false; } virtual sensortype GetSensorType() { return ST_NEAR; } diff --git a/source/gameengine/Ketsji/KX_ObColorIpoSGController.h b/source/gameengine/Ketsji/KX_ObColorIpoSGController.h index d2d69d6db12..d2f4c69bf47 100644 --- a/source/gameengine/Ketsji/KX_ObColorIpoSGController.h +++ b/source/gameengine/Ketsji/KX_ObColorIpoSGController.h @@ -64,7 +64,7 @@ public: SetOption( int option, int value - ){ + ) { // intentionally empty }; diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 4f0ae4261c9..695ad1f945c 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -2267,10 +2267,10 @@ KX_PYMETHODDEF_DOC(KX_Scene, addObject, !ConvertPythonToGameObject(pyother, &other, false, "scene.addObject(object, other, time): KX_Scene (second argument)") ) return NULL; - if (!m_inactivelist->SearchValue(ob)) { - PyErr_Format(PyExc_ValueError, "scene.addObject(object, other, time): KX_Scene (second argument): object does not belong to scene"); - return NULL; - } + if (!m_inactivelist->SearchValue(ob)) { + PyErr_Format(PyExc_ValueError, "scene.addObject(object, other, time): KX_Scene (second argument): object does not belong to scene"); + return NULL; + } SCA_IObject* replica = AddReplicaObject((SCA_IObject*)ob, other, time); // release here because AddReplicaObject AddRef's diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h index 71ec3ae2f59..dbdb17d0da5 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.h +++ b/source/gameengine/Ketsji/KX_SoundActuator.h @@ -43,8 +43,7 @@ #include "BKE_sound.h" -typedef struct KX_3DSoundSettings -{ +typedef struct KX_3DSoundSettings { float min_gain; float max_gain; float reference_distance; diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h index 1a22067f9ac..d739144d70d 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.h +++ b/source/gameengine/Ketsji/KX_TouchSensor.h @@ -93,8 +93,10 @@ public: virtual void UnregisterSumo(KX_TouchEventManager* touchman); virtual void UnregisterToManager(); -// virtual DT_Bool HandleCollision(void* obj1,void* obj2, -// const DT_CollData * coll_data); +#if 0 + virtual DT_Bool HandleCollision(void* obj1,void* obj2, + const DT_CollData * coll_data); +#endif virtual bool NewHandleCollision(void*obj1,void*obj2,const PHY_CollData* colldata); diff --git a/source/gameengine/Ketsji/KX_WorldIpoController.h b/source/gameengine/Ketsji/KX_WorldIpoController.h index 1f60280e355..9578130b51e 100644 --- a/source/gameengine/Ketsji/KX_WorldIpoController.h +++ b/source/gameengine/Ketsji/KX_WorldIpoController.h @@ -88,7 +88,7 @@ public: SetOption( int option, int value - ){ + ) { // intentionally empty }; diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index 767d99583b8..343cb549337 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -719,8 +719,8 @@ void CcdPhysicsEnvironment::processFhSprings(double curTime,float interval) { if (ctrl->getConstructionInfo().m_do_fh) { - btVector3 lspot = cl_object->getCenterOfMassPosition() - + rayDirLocal * resultCallback.m_closestHitFraction; + btVector3 lspot = cl_object->getCenterOfMassPosition() + + rayDirLocal * resultCallback.m_closestHitFraction; diff --git a/source/gameengine/Rasterizer/RAS_LightObject.h b/source/gameengine/Rasterizer/RAS_LightObject.h index c378a9ea0c2..ddf360683cd 100644 --- a/source/gameengine/Rasterizer/RAS_LightObject.h +++ b/source/gameengine/Rasterizer/RAS_LightObject.h @@ -36,7 +36,7 @@ struct RAS_LightObject { - enum LightType{ + enum LightType { LIGHT_SPOT, LIGHT_SUN, LIGHT_NORMAL diff --git a/source/gameengine/SceneGraph/SG_ParentRelation.h b/source/gameengine/SceneGraph/SG_ParentRelation.h index 689ada84edd..4140563828f 100644 --- a/source/gameengine/SceneGraph/SG_ParentRelation.h +++ b/source/gameengine/SceneGraph/SG_ParentRelation.h @@ -76,8 +76,7 @@ public : virtual ~SG_ParentRelation( - ){ - }; + ) {}; /** * You must provide a way of duplicating an diff --git a/source/gameengine/VideoTexture/FilterColor.h b/source/gameengine/VideoTexture/FilterColor.h index 9b1976cf40f..cd61900bbda 100644 --- a/source/gameengine/VideoTexture/FilterColor.h +++ b/source/gameengine/VideoTexture/FilterColor.h @@ -91,9 +91,9 @@ protected: /// calculate one color component unsigned char calcColor (unsigned int val, short idx) { - return (((m_matrix[idx][0] * (VT_R(val)) + m_matrix[idx][1] * (VT_G(val)) - + m_matrix[idx][2] * (VT_B(val)) + m_matrix[idx][3] * (VT_A(val)) - + m_matrix[idx][4]) >> 8) & 0xFF); + return (((m_matrix[idx][0] * (VT_R(val)) + m_matrix[idx][1] * (VT_G(val)) + + m_matrix[idx][2] * (VT_B(val)) + m_matrix[idx][3] * (VT_A(val)) + + m_matrix[idx][4]) >> 8) & 0xFF); } /// filter pixel template, source int buffer diff --git a/source/gameengine/VideoTexture/ImageBase.cpp b/source/gameengine/VideoTexture/ImageBase.cpp index b1d77d8807f..ac92bcc6d41 100644 --- a/source/gameengine/VideoTexture/ImageBase.cpp +++ b/source/gameengine/VideoTexture/ImageBase.cpp @@ -444,9 +444,9 @@ PyObject * Image_getImage (PyImage * self, char * mode) // get an empty buffer buffer = BGL_MakeBuffer( GL_BYTE, 1, &dimensions, NULL); // and fill it - for (i=0, d=(unsigned char*)buffer->buf.asbyte, s=(unsigned char*)image; - i<pixels; - ++i, d+=ncolor, s+=4) + for (i = 0, d = (unsigned char *)buffer->buf.asbyte, s = (unsigned char *)image; + i < pixels; + i++, d += ncolor, s += 4) { for (c=0; c<ncolor; c++) { |