diff options
Diffstat (limited to 'source/blender')
616 files changed, 11811 insertions, 10669 deletions
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index d46df829295..998b415a6af 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -210,6 +210,7 @@ void blf_font_draw_ascii(FontBLF *font, const char *str, size_t len) blf_font_ensure_ascii_table(font); while ((c = *(str++)) && len--) { + BLI_assert(c < 128); if ((g = glyph_ascii_table[c]) == NULL) continue; if (has_kerning) diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index 698098d28c3..3ac5c8c9a76 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -132,61 +132,21 @@ struct bActionGroup *BKE_action_group_find_name(struct bAction *act, const char void action_groups_clear_tempflags(struct bAction *act); /* Pose API ----------------- */ - -/** - * Deallocates a pose channel. - * Does not free the pose channel itself. - */ -void BKE_pose_channel_free(struct bPoseChannel *pchan); - -/** - * Removes and deallocates all channels from a pose. - * Does not free the pose itself. - */ -void BKE_pose_channels_free(struct bPose *pose); -/** - * Removes the hash for quick lookup of channels, must - * be done when adding/removing channels. - */ -void BKE_pose_channels_hash_make(struct bPose *pose); -void BKE_pose_channels_hash_free(struct bPose *pose); - -/** - * Removes and deallocates all data from a pose, and also frees the pose. - */ -void BKE_pose_free(struct bPose *pose); +void BKE_pose_channel_free(struct bPoseChannel *pchan); -/** - * Allocate a new pose on the heap, and copy the src pose and it's channels - * into the new pose. *dst is set to the newly allocated structure, and assumed to be NULL. - */ -void BKE_pose_copy_data(struct bPose **dst, struct bPose *src, int copyconstraints); +void BKE_pose_channels_free(struct bPose *pose); -/** - * Copy the internal members of each pose channel including constraints - * and ID-Props, used when duplicating bones in editmode. - */ -void BKE_pose_channel_copy_data(struct bPoseChannel *pchan, const struct bPoseChannel *pchan_from); +void BKE_pose_channels_hash_make(struct bPose *pose); +void BKE_pose_channels_hash_free(struct bPose *pose); -/** - * Return a pointer to the pose channel of the given name - * from this pose. - */ +void BKE_pose_free(struct bPose *pose); +void BKE_pose_copy_data(struct bPose **dst, struct bPose *src, const bool copy_constraints); +void BKE_pose_channel_copy_data(struct bPoseChannel *pchan, const struct bPoseChannel *pchan_from); struct bPoseChannel *BKE_pose_channel_find_name(const struct bPose *pose, const char *name); - -/** - * Return a pointer to the active pose channel from this Object. - * (Note: Object, not bPose is used here, as we need layer info from Armature) - */ struct bPoseChannel *BKE_pose_channel_active(struct Object *ob); - -/** - * Looks to see if the channel with the given name - * already exists in this pose - if not a new one is - * allocated and initialized. - */ struct bPoseChannel *BKE_pose_channel_verify(struct bPose *pose, const char *name); +struct bPoseChannel *BKE_pose_channel_get_mirrored(const struct bPose *pose, const char *name); #ifndef NDEBUG bool BKE_pose_channels_is_valid(const struct bPose *pose); diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h index f0f6b5a2319..a0ec6c7757f 100644 --- a/source/blender/blenkernel/BKE_animsys.h +++ b/source/blender/blenkernel/BKE_animsys.h @@ -104,6 +104,10 @@ void BKE_keyingsets_free(struct ListBase *list); /* ************************************* */ /* Path Fixing API */ +/* Fix all the paths for the the given ID + Action */ +void BKE_action_fix_paths_rename(struct ID *owner_id, struct bAction *act, const char *prefix, const char *oldName, + const char *newName, int oldSubscript, int newSubscript, int verify_paths); + /* Fix all the paths for the given ID+AnimData */ void BKE_animdata_fix_paths_rename(struct ID *owner_id, struct AnimData *adt, struct ID *ref_id, const char *prefix, const char *oldName, const char *newName, int oldSubscript, int newSubscript, diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 5b32e7229d5..f2d9c0efc13 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 269 -#define BLENDER_SUBVERSION 1 +#define BLENDER_SUBVERSION 2 /* 262 was the last editmesh release but it has compatibility code for bmesh data */ #define BLENDER_MINVERSION 262 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenkernel/BKE_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h index 8d4c9e782db..9e1bca45432 100644 --- a/source/blender/blenkernel/BKE_bvhutils.h +++ b/source/blender/blenkernel/BKE_bvhutils.h @@ -116,6 +116,8 @@ float nearest_point_in_tri_surface(const float v0[3], const float v1[3], const f #define BVHTREE_FROM_VERTICES 1 #define BVHTREE_FROM_EDGES 2 +#define BVHTREE_FROM_FACES_EDITMESH 3 + typedef struct LinkNode *BVHCache; diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h index ddb36df74ca..560617db474 100644 --- a/source/blender/blenkernel/BKE_cdderivedmesh.h +++ b/source/blender/blenkernel/BKE_cdderivedmesh.h @@ -122,6 +122,7 @@ void CDDM_recalc_tessellation_ex(struct DerivedMesh *dm, const int do_face_nor_c */ void CDDM_lower_num_verts(struct DerivedMesh *dm, int numVerts); void CDDM_lower_num_edges(struct DerivedMesh *dm, int numEdges); +void CDDM_lower_num_loops(struct DerivedMesh *dm, int numLoops); void CDDM_lower_num_polys(struct DerivedMesh *dm, int numPolys); void CDDM_lower_num_tessfaces(DerivedMesh *dm, int numTessFaces); diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 07116979eab..dee27cebf59 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -119,6 +119,7 @@ void BKE_nurbList_flag_set(ListBase *editnurb, short flag); void BKE_nurb_free(struct Nurb *nu); struct Nurb *BKE_nurb_duplicate(struct Nurb *nu); +struct Nurb *BKE_nurb_copy(struct Nurb *src, int pntsu, int pntsv); void BKE_nurb_test2D(struct Nurb *nu); void BKE_nurb_minmax(struct Nurb *nu, float min[3], float max[3]); diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 5a283922707..f28d16427cf 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -147,14 +147,14 @@ void *CustomData_add_layer_named(struct CustomData *data, int type, int alloctyp void *layer, int totelem, const char *name); /* frees the active or first data layer with the give type. - * returns 1 on succes, 0 if no layer with the given type is found + * returns 1 on success, 0 if no layer with the given type is found * * in editmode, use EDBM_data_layer_free instead of this function */ bool CustomData_free_layer(struct CustomData *data, int type, int totelem, int index); /* frees the layer index with the give type. - * returns 1 on succes, 0 if no layer with the given type is found + * returns 1 on success, 0 if no layer with the given type is found * * in editmode, use EDBM_data_layer_free instead of this function */ diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index 435cad17e57..e203549fef5 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -91,6 +91,7 @@ void defvert_normalize_lock_map(struct MDeformVert *dvert, void BKE_deform_split_suffix(const char string[MAX_VGROUP_NAME], char base[MAX_VGROUP_NAME], char ext[MAX_VGROUP_NAME]); void BKE_deform_split_prefix(const char string[MAX_VGROUP_NAME], char base[MAX_VGROUP_NAME], char ext[MAX_VGROUP_NAME]); -void flip_side_name(char name[MAX_VGROUP_NAME], const char from_name[MAX_VGROUP_NAME], int strip_number); +void BKE_deform_flip_side_name(char name[MAX_VGROUP_NAME], const char from_name[MAX_VGROUP_NAME], + const bool strip_number); #endif /* __BKE_DEFORM_H__ */ diff --git a/source/blender/blenkernel/BKE_editmesh.h b/source/blender/blenkernel/BKE_editmesh.h index 738cd87dc39..310807370da 100644 --- a/source/blender/blenkernel/BKE_editmesh.h +++ b/source/blender/blenkernel/BKE_editmesh.h @@ -71,13 +71,6 @@ typedef struct BMEditMesh { unsigned char (*derivedFaceColor)[4]; int derivedFaceColorLen; - /* index tables, to map indices to elements via - * EDBM_index_arrays_init and associated functions. don't - * touch this or read it directly.*/ - struct BMVert **vert_index; - struct BMEdge **edge_index; - struct BMFace **face_index; - /*selection mode*/ short selectmode; short mat_nr; diff --git a/source/blender/blenkernel/BKE_editmesh_bvh.h b/source/blender/blenkernel/BKE_editmesh_bvh.h index 7b4ad4284c6..aeac00b06c1 100644 --- a/source/blender/blenkernel/BKE_editmesh_bvh.h +++ b/source/blender/blenkernel/BKE_editmesh_bvh.h @@ -33,15 +33,19 @@ #define __BKE_EDITMESH_BVH_H__ struct BMEditMesh; +struct BMesh; struct BMFace; struct BMVert; +struct BMLoop; struct BMBVHTree; struct BVHTree; struct Scene; typedef struct BMBVHTree BMBVHTree; -BMBVHTree *BKE_bmbvh_new(struct BMEditMesh *em, int flag, const float (*cos_cage)[3], const bool cos_cage_free); +BMBVHTree *BKE_bmbvh_new_from_editmesh(struct BMEditMesh *em, int flag, const float (*cos_cage)[3], const bool cos_cage_free); +BMBVHTree *BKE_bmbvh_new(struct BMesh *bm, struct BMLoop *(*looptris)[3], int looptris_tot, int flag, + const float (*cos_cage)[3], const bool cos_cage_free); void BKE_bmbvh_free(BMBVHTree *tree); struct BVHTree *BKE_bmbvh_tree_get(BMBVHTree *tree); struct BMFace *BKE_bmbvh_ray_cast(BMBVHTree *tree, const float co[3], const float dir[3], const float radius, diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h index 028ff0f93d6..8f5ccf1087e 100644 --- a/source/blender/blenkernel/BKE_font.h +++ b/source/blender/blenkernel/BKE_font.h @@ -63,8 +63,6 @@ typedef struct EditFont { wchar_t *textbuf; struct CharInfo *textbufinfo; - wchar_t *oldstr; - struct CharInfo *oldstrinfo; float textcurs[4][2]; diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index 9d33af1a0f4..d0341ab8c89 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -192,6 +192,7 @@ enum { #define G_TRANSFORM_OBJ 1 #define G_TRANSFORM_EDIT 2 #define G_TRANSFORM_SEQ 4 +#define G_TRANSFORM_FCURVES 8 /* G.special1 */ diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h index 71fd163a8ee..bd90960eced 100644 --- a/source/blender/blenkernel/BKE_idprop.h +++ b/source/blender/blenkernel/BKE_idprop.h @@ -94,7 +94,8 @@ void IDP_MergeGroup(IDProperty *dest, IDProperty *src, const int do_overwrite) A int IDP_AddToGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL(); int IDP_InsertToGroup(struct IDProperty *group, struct IDProperty *previous, struct IDProperty *pnew) ATTR_NONNULL(1 /* group */, 3 /* pnew */); -void IDP_RemFromGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL(); +void IDP_RemoveFromGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL(); +void IDP_FreeFromGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL(); IDProperty *IDP_GetPropertyFromGroup(struct IDProperty *prop, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); IDProperty *IDP_GetPropertyTypeFromGroup(struct IDProperty *prop, const char *name, const char type) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index 264a7421e91..7b7b69034a9 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -53,7 +53,8 @@ typedef struct Main { char name[1024]; /* 1024 = FILE_MAX */ short versionfile, subversionfile; /* see BLENDER_VERSION, BLENDER_SUBVERSION */ short minversionfile, minsubversionfile; - int revision; /* svn revision of binary that saved file */ + uint64_t build_commit_timestamp; /* commit's timestamp from buildinfo */ + char build_hash[16]; /* hash from buildinfo */ short recovered; /* indicate the main->name (file) is the recovered one */ struct Library *curlib; diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 9e73e0662ce..d73249041e8 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -90,7 +90,7 @@ float BKE_mask_spline_project_co(struct MaskSpline *spline, struct MaskSplinePoi /* 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, +void BKE_mask_point_set_handle(struct MaskSplinePoint *point, float loc[2], bool keep_direction, float orig_handle[2], float orig_vec[3][3]); void BKE_mask_point_segment_co(struct MaskSpline *spline, struct MaskSplinePoint *point, float u, float co[2]); @@ -123,9 +123,9 @@ void BKE_mask_coord_to_image(struct Image *image, struct ImageUser *iuser, float 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_layer_evaluate(struct MaskLayer *masklay, const float ctime, const int do_newframe); +void BKE_mask_evaluate_all_masks(struct Main *bmain, float ctime, const bool do_newframe); +void BKE_mask_evaluate(struct Mask *mask, const float ctime, const bool do_newframe); +void BKE_mask_layer_evaluate(struct MaskLayer *masklay, const float ctime, const bool do_newframe); void BKE_mask_update_scene(struct Main *bmain, struct Scene *scene); void BKE_mask_parent_init(struct MaskParent *parent); void BKE_mask_calc_handle_adjacent_interp(struct MaskSpline *spline, struct MaskSplinePoint *point, const float u); @@ -156,17 +156,18 @@ int BKE_mask_layer_shape_find_frame_range(struct MaskLayer *masklay, const float 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_verify_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, +bool 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); +/* TODO(sergey): do_init and do_init_interpolate are always true, so let's wipe them later. */ void BKE_mask_layer_shape_changed_add(struct MaskLayer *masklay, int index, - int do_init, int do_init_interpolate); + bool do_init, bool do_init_interpolate); void BKE_mask_layer_shape_changed_remove(struct MaskLayer *masklay, int index, int count); diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 6bf42a3e885..65038c7f09c 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -357,6 +357,7 @@ bool modifiers_usesArmature(struct Object *ob, struct bArmature *arm); bool modifiers_isCorrectableDeformed(struct Scene *scene, struct Object *ob); void modifier_freeTemporaryData(struct ModifierData *md); bool modifiers_isPreview(struct Object *ob); +void modifier_skin_customdata_ensure(struct Object *ob); typedef struct CDMaskLink { struct CDMaskLink *next; diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 7cc8c7290f7..b700cbb16db 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -132,7 +132,7 @@ typedef struct bNodeSocketType { } bNodeSocketType; typedef void *(*NodeInitExecFunction)(struct bNodeExecContext *context, struct bNode *node, bNodeInstanceKey key); -typedef void (*NodeFreeExecFunction)(struct bNode *node, void *nodedata); +typedef void (*NodeFreeExecFunction)(void *nodedata); typedef void (*NodeExecFunction)(void *data, int thread, struct bNode *, struct bNodeExecData *execdata, struct bNodeStack **in, struct bNodeStack **out); typedef int (*NodeGPUExecFunction)(struct GPUMaterial *mat, struct bNode *node, struct bNodeExecData *execdata, struct GPUNodeStack *in, struct GPUNodeStack *out); @@ -175,7 +175,7 @@ typedef struct bNodeType { void (*draw_backdrop)(struct SpaceNode *snode, struct ImBuf *backdrop, struct bNode *node, int x, int y); /// Optional custom label function for the node header. - const char *(*labelfunc)(struct bNode *); + void (*labelfunc)(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen); /// Optional custom resize handle polling. int (*resize_area_func)(struct bNode *node, int x, int y); /// Optional selection area polling. @@ -556,7 +556,7 @@ void BKE_node_preview_set_pixel(struct bNodePreview *preview, const f /* ************** NODE TYPE ACCESS *************** */ -const char *nodeLabel(struct bNode *node); +void nodeLabel(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen); int nodeGroupPoll(struct bNodeTree *nodetree, struct bNodeTree *grouptree); @@ -571,7 +571,7 @@ void node_type_storage(struct bNodeType *ntype, const char *storagename, void (*freefunc)(struct bNode *node), void (*copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, struct bNode *src_node)); -void node_type_label(struct bNodeType *ntype, const char *(*labelfunc)(struct bNode *)); +void node_type_label(struct bNodeType *ntype, void (*labelfunc)(struct bNodeTree *ntree, struct bNode *, char *label, int maxlen)); void node_type_update(struct bNodeType *ntype, void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node), void (*verifyfunc)(struct bNodeTree *ntree, struct bNode *node, struct ID *id)); @@ -944,6 +944,9 @@ void ntreeCompositOutputFileSetLayer(struct bNode *node, struct bNodeSocket *soc void ntreeCompositOutputFileUniquePath(struct ListBase *list, struct bNodeSocket *sock, const char defname[], char delim); void ntreeCompositOutputFileUniqueLayer(struct ListBase *list, struct bNodeSocket *sock, const char defname[], char delim); +void ntreeCompositColorBalanceSyncFromLGG(bNodeTree *ntree, bNode *node); +void ntreeCompositColorBalanceSyncFromCDL(bNodeTree *ntree, bNode *node); + /* ************** TEXTURE NODES *************** */ struct TexResult; diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index e99eb2a64f2..434175624b7 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -48,6 +48,7 @@ struct rctf; struct MovieClip; struct Main; struct RigidBodyWorld; +struct HookModifierData; void BKE_object_workob_clear(struct Object *workob); void BKE_object_workob_calc_parent(struct Scene *scene, struct Object *ob, struct Object *workob); @@ -66,6 +67,8 @@ void BKE_object_update_base_layer(struct Scene *scene, struct Object *ob); void BKE_object_free(struct Object *ob); void BKE_object_free_derived_caches(struct Object *ob); +void BKE_object_modifier_hook_reset(struct Object *ob, struct HookModifierData *hmd); + bool BKE_object_support_modifier_type_check(struct Object *ob, int modifier_type); void BKE_object_link_modifiers(struct Object *ob, struct Object *from); diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 9e21831dba0..f8c21a1fa16 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -151,8 +151,9 @@ typedef enum { void BKE_pbvh_node_mark_update(PBVHNode *node); void BKE_pbvh_node_mark_rebuild_draw(PBVHNode *node); -void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden); +void BKE_pbvh_node_mark_redraw(PBVHNode *node); void BKE_pbvh_node_mark_topology_update(PBVHNode *node); +void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden); void BKE_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int *totgrid, int *maxgrid, int *gridsize, diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h index 929d9686328..86be3bfe770 100644 --- a/source/blender/blenkernel/BKE_rigidbody.h +++ b/source/blender/blenkernel/BKE_rigidbody.h @@ -57,7 +57,7 @@ void BKE_rigidbody_relink_constraint(struct RigidBodyCon *rbc); /* -------------- */ /* Setup */ -/* create Blender-side settings data - physics objects not initialised yet */ +/* create Blender-side settings data - physics objects not initialized yet */ struct RigidBodyWorld *BKE_rigidbody_create_world(struct Scene *scene); struct RigidBodyOb *BKE_rigidbody_create_object(struct Scene *scene, struct Object *ob, short type); struct RigidBodyCon *BKE_rigidbody_create_constraint(struct Scene *scene, struct Object *ob, short type); diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h index 2a00dee2a3f..e9e351f8f37 100644 --- a/source/blender/blenkernel/BKE_texture.h +++ b/source/blender/blenkernel/BKE_texture.h @@ -52,6 +52,7 @@ struct ParticleSettings; struct PointDensity; struct Tex; struct TexMapping; +struct TexResult; struct VoxelData; struct World; @@ -129,6 +130,8 @@ struct OceanTex *BKE_copy_oceantex(struct OceanTex *ot); bool BKE_texture_dependsOnTime(const struct Tex *texture); +void BKE_texture_get_value(struct Scene *scene, struct Tex *texture, float *tex_co, struct TexResult *texres, bool use_color_management); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 51f97180ddb..94e530529ec 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -225,7 +225,7 @@ void BKE_tracking_homography_between_two_quads(/*const*/ float reference_corners bool BKE_tracking_reconstruction_check(struct MovieTracking *tracking, struct MovieTrackingObject *object, char *error_msg, int error_size); -struct MovieReconstructContext *BKE_tracking_reconstruction_context_new(struct MovieTracking *tracking, +struct MovieReconstructContext *BKE_tracking_reconstruction_context_new(struct MovieClip *clip, struct MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height); diff --git a/source/blender/blenkernel/BKE_writeffmpeg.h b/source/blender/blenkernel/BKE_writeffmpeg.h index 8a11d48d063..347c8b60532 100644 --- a/source/blender/blenkernel/BKE_writeffmpeg.h +++ b/source/blender/blenkernel/BKE_writeffmpeg.h @@ -38,31 +38,34 @@ extern "C" { #endif -#define FFMPEG_MPEG1 0 -#define FFMPEG_MPEG2 1 -#define FFMPEG_MPEG4 2 -#define FFMPEG_AVI 3 -#define FFMPEG_MOV 4 -#define FFMPEG_DV 5 -#define FFMPEG_H264 6 -#define FFMPEG_XVID 7 -#define FFMPEG_FLV 8 -#define FFMPEG_MKV 9 -#define FFMPEG_OGG 10 -#define FFMPEG_WAV 11 -#define FFMPEG_MP3 12 +enum { + FFMPEG_MPEG1 = 0, + FFMPEG_MPEG2 = 1, + FFMPEG_MPEG4 = 2, + FFMPEG_AVI = 3, + FFMPEG_MOV = 4, + FFMPEG_DV = 5, + FFMPEG_H264 = 6, + FFMPEG_XVID = 7, + FFMPEG_FLV = 8, + FFMPEG_MKV = 9, + FFMPEG_OGG = 10, + FFMPEG_INVALID = 11, +}; -#define FFMPEG_PRESET_NONE 0 -#define FFMPEG_PRESET_DVD 1 -#define FFMPEG_PRESET_SVCD 2 -#define FFMPEG_PRESET_VCD 3 -#define FFMPEG_PRESET_DV 4 -#define FFMPEG_PRESET_H264 5 -#define FFMPEG_PRESET_THEORA 6 -#define FFMPEG_PRESET_XVID 7 +enum { + FFMPEG_PRESET_NONE = 0, + FFMPEG_PRESET_DVD = 1, + FFMPEG_PRESET_SVCD = 2, + FFMPEG_PRESET_VCD = 3, + FFMPEG_PRESET_DV = 4, + FFMPEG_PRESET_H264 = 5, + FFMPEG_PRESET_THEORA = 6, + FFMPEG_PRESET_XVID = 7, +}; struct IDProperty; -struct RenderData; +struct RenderData; struct ReportList; struct Scene; diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 368c1e517ef..731196c2480 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1259,7 +1259,7 @@ void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag, } if (dm->type == DM_TYPE_EDITBMESH) { - /* editmesh draw function checks spesifically for this */ + /* editmesh draw function checks specifically for this */ } else { const int dm_totpoly = dm->getNumPolys(dm); @@ -2859,14 +2859,19 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, else layer = CustomData_get_active_layer_index(ldata, CD_MLOOPUV); - if (layer != -1) { - a = attribs->tottface++; + a = attribs->tottface++; + if (layer != -1) { attribs->tface[a].array = tfdata->layers[layer].data; attribs->tface[a].em_offset = ldata->layers[layer].offset; - attribs->tface[a].gl_index = gattribs->layer[b].glindex; - attribs->tface[a].gl_texco = gattribs->layer[b].gltexco; } + else { + attribs->tface[a].array = NULL; + attribs->tface[a].em_offset = -1; + } + + attribs->tface[a].gl_index = gattribs->layer[b].glindex; + attribs->tface[a].gl_texco = gattribs->layer[b].gltexco; } else { if (gattribs->layer[b].name[0]) @@ -2875,14 +2880,19 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, else layer = CustomData_get_active_layer_index(tfdata, CD_MTFACE); - if (layer != -1) { - a = attribs->tottface++; + a = attribs->tottface++; + if (layer != -1) { attribs->tface[a].array = tfdata->layers[layer].data; attribs->tface[a].em_offset = tfdata->layers[layer].offset; - attribs->tface[a].gl_index = gattribs->layer[b].glindex; - attribs->tface[a].gl_texco = gattribs->layer[b].gltexco; } + else { + attribs->tface[a].array = NULL; + attribs->tface[a].em_offset = -1; + } + + attribs->tface[a].gl_index = gattribs->layer[b].glindex; + attribs->tface[a].gl_texco = gattribs->layer[b].gltexco; } } else if (gattribs->layer[b].type == CD_MCOL) { @@ -2896,14 +2906,19 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, else layer = CustomData_get_active_layer_index(ldata, CD_MLOOPCOL); - if (layer != -1) { - a = attribs->totmcol++; + a = attribs->totmcol++; + if (layer != -1) { attribs->mcol[a].array = tfdata->layers[layer].data; /* odd, store the offset for a different layer type here, but editmode draw code expects it */ attribs->mcol[a].em_offset = ldata->layers[layer].offset; - attribs->mcol[a].gl_index = gattribs->layer[b].glindex; } + else { + attribs->mcol[a].array = NULL; + attribs->mcol[a].em_offset = -1; + } + + attribs->mcol[a].gl_index = gattribs->layer[b].glindex; } else { /* vertex colors */ @@ -2913,40 +2928,54 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, else layer = CustomData_get_active_layer_index(tfdata, CD_MCOL); - if (layer != -1) { - a = attribs->totmcol++; + a = attribs->totmcol++; + if (layer != -1) { attribs->mcol[a].array = tfdata->layers[layer].data; /* odd, store the offset for a different layer type here, but editmode draw code expects it */ attribs->mcol[a].em_offset = tfdata->layers[layer].offset; - attribs->mcol[a].gl_index = gattribs->layer[b].glindex; } + else { + attribs->mcol[a].array = NULL; + attribs->mcol[a].em_offset = -1; + } + + attribs->mcol[a].gl_index = gattribs->layer[b].glindex; } } else if (gattribs->layer[b].type == CD_TANGENT) { /* tangents */ layer = CustomData_get_layer_index(fdata, CD_TANGENT); - if (layer != -1) { - attribs->tottang = 1; + attribs->tottang = 1; + if (layer != -1) { attribs->tang.array = fdata->layers[layer].data; attribs->tang.em_offset = fdata->layers[layer].offset; - attribs->tang.gl_index = gattribs->layer[b].glindex; } + else { + attribs->tang.array = NULL; + attribs->tang.em_offset = -1; + } + + attribs->tang.gl_index = gattribs->layer[b].glindex; } else if (gattribs->layer[b].type == CD_ORCO) { /* original coordinates */ layer = CustomData_get_layer_index(vdata, CD_ORCO); + attribs->totorco = 1; if (layer != -1) { - attribs->totorco = 1; - attribs->orco.array = vdata->layers[layer].data; attribs->orco.em_offset = vdata->layers[layer].offset; - attribs->orco.gl_index = gattribs->layer[b].glindex; - attribs->orco.gl_texco = gattribs->layer[b].gltexco; } + else { + attribs->orco.array = NULL; + attribs->orco.em_offset = -1; + } + + attribs->orco.gl_index = gattribs->layer[b].glindex; + attribs->orco.gl_texco = gattribs->layer[b].gltexco; } } } diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index b0644da4598..c91fae2adbc 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -53,6 +53,7 @@ #include "BKE_anim.h" #include "BKE_animsys.h" #include "BKE_constraint.h" +#include "BKE_deform.h" #include "BKE_fcurve.h" #include "BKE_global.h" #include "BKE_idprop.h" @@ -440,6 +441,10 @@ void action_groups_clear_tempflags(bAction *act) /* *************** Pose channels *************** */ +/** + * Return a pointer to the pose channel of the given name + * from this pose. + */ bPoseChannel *BKE_pose_channel_find_name(const bPose *pose, const char *name) { if (ELEM(NULL, pose, name) || (name[0] == '\0')) @@ -451,8 +456,14 @@ bPoseChannel *BKE_pose_channel_find_name(const bPose *pose, const char *name) return BLI_findstring(&((bPose *)pose)->chanbase, name, offsetof(bPoseChannel, name)); } -/* Use with care, not on Armature poses but for temporal ones */ -/* (currently used for action constraints and in rebuild_pose) */ +/** + * Looks to see if the channel with the given name + * already exists in this pose - if not a new one is + * allocated and initialized. + * + * \note Use with care, not on Armature poses but for temporal ones. + * \note (currently used for action constraints and in rebuild_pose). + */ bPoseChannel *BKE_pose_channel_verify(bPose *pose, const char *name) { bPoseChannel *chan; @@ -505,7 +516,12 @@ bool BKE_pose_channels_is_valid(const bPose *pose) } #endif -/* Find the active posechannel for an object (we can't just use pose, as layer info is in armature) */ + +/** + * Find the active posechannel for an object (we can't just use pose, as layer info is in armature) + * + * \note: Object, not bPose is used here, as we need layer info from Armature) + */ bPoseChannel *BKE_pose_channel_active(Object *ob) { bArmature *arm = (ob) ? ob->data : NULL; @@ -524,6 +540,22 @@ bPoseChannel *BKE_pose_channel_active(Object *ob) return NULL; } +/** + * \see #ED_armature_bone_get_mirrored (edit-mode, matching function) + */ +bPoseChannel *BKE_pose_channel_get_mirrored(const bPose *pose, const char *name) +{ + char name_flip[MAXBONENAME]; + + BKE_deform_flip_side_name(name_flip, name, false); + + if (!STREQ(name_flip, name)) { + return BKE_pose_channel_find_name(pose, name_flip); + } + + return NULL; +} + const char *BKE_pose_ikparam_get_name(bPose *pose) { if (pose) { @@ -536,8 +568,14 @@ const char *BKE_pose_ikparam_get_name(bPose *pose) } return NULL; } -/* dst should be freed already, makes entire duplicate */ -void BKE_pose_copy_data(bPose **dst, bPose *src, int copycon) + +/** + * Allocate a new pose on the heap, and copy the src pose and it's channels + * into the new pose. *dst is set to the newly allocated structure, and assumed to be NULL. + * + * \param dst Should be freed already, makes entire duplicate. + */ +void BKE_pose_copy_data(bPose **dst, bPose *src, const bool copy_constraints) { bPose *outPose; bPoseChannel *pchan; @@ -551,15 +589,22 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, int copycon) outPose = MEM_callocN(sizeof(bPose), "pose"); BLI_duplicatelist(&outPose->chanbase, &src->chanbase); - + if (outPose->chanbase.first) { + bPoseChannel *pchan; + for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) { + if (pchan->custom) { + id_us_plus(&pchan->custom->id); + } + } + } + outPose->iksolver = src->iksolver; outPose->ikdata = NULL; outPose->ikparam = MEM_dupallocN(src->ikparam); outPose->avs = src->avs; for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) { - /* TODO: rename this argument... */ - if (copycon) { + if (copy_constraints) { BKE_copy_constraints(&listb, &pchan->constraints, TRUE); // BKE_copy_constraints NULLs listb pchan->constraints = listb; pchan->mpath = NULL; /* motion paths should not get copied yet... */ @@ -571,8 +616,9 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, int copycon) } /* for now, duplicate Bone Groups too when doing this */ - if (copycon) + if (copy_constraints) { BLI_duplicatelist(&outPose->agroups, &src->agroups); + } *dst = outPose; } @@ -641,7 +687,10 @@ bool BKE_pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan) return pose_channel_in_IK_chain(ob, pchan, 0); } - +/** + * Removes the hash for quick lookup of channels, must + * be done when adding/removing channels. + */ void BKE_pose_channels_hash_make(bPose *pose) { if (!pose->chanhash) { @@ -661,6 +710,10 @@ void BKE_pose_channels_hash_free(bPose *pose) } } +/** + * Deallocates a pose channel. + * Does not free the pose channel itself. + */ void BKE_pose_channel_free(bPoseChannel *pchan) { if (pchan->custom) { @@ -681,6 +734,10 @@ void BKE_pose_channel_free(bPoseChannel *pchan) } } +/** + * Removes and deallocates all channels from a pose. + * Does not free the pose itself. + */ void BKE_pose_channels_free(bPose *pose) { bPoseChannel *pchan; @@ -695,6 +752,9 @@ void BKE_pose_channels_free(bPose *pose) BKE_pose_channels_hash_free(pose); } +/** + * Removes and deallocates all data from a pose, and also frees the pose. + */ void BKE_pose_free(bPose *pose) { if (pose) { @@ -739,9 +799,13 @@ static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan } } -/* makes copies of internal data, unlike copy_pose_channel_data which only - * copies the pose state. - * hint: use when copying bones in editmode (on returned value from BKE_pose_channel_verify) */ +/** + * Copy the internal members of each pose channel including constraints + * and ID-Props, used when duplicating bones in editmode. + * (unlike copy_pose_channel_data which only). + * + * \note use when copying bones in editmode (on returned value from #BKE_pose_channel_verify) + */ void BKE_pose_channel_copy_data(bPoseChannel *pchan, const bPoseChannel *pchan_from) { /* copy transform locks */ diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 225be335c6d..9226538910c 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -285,7 +285,7 @@ void animviz_get_object_motionpaths(Object *ob, ListBase *targets) /* ........ */ /* Note on evaluation optimizations: - * Optimisations currently used here play tricks with the depsgraph in order to try and + * Optimization's currently used here play tricks with the depsgraph in order to try and * evaluate as few objects as strictly necessary to get nicer performance under standard * production conditions. For those people who really need the accurate version, * disable the ifdef (i.e. 1 -> 0) and comment out the call to motionpaths_calc_optimise_depsgraph() diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 74578266c63..cb628db8cd2 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -711,6 +711,49 @@ static void nlastrips_path_rename_fix(ID *owner_id, const char *prefix, const ch } } +/* Fix all RNA_Paths in the given Action, relative to the given ID block + * + * This is just an external wrapper for the F-Curve fixing function, + * with input validity checks on top of the basic method. + * + * NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]> + * i.e. pose.bones["Bone"] + */ +void BKE_action_fix_paths_rename(ID *owner_id, bAction *act, const char *prefix, const char *oldName, + const char *newName, int oldSubscript, int newSubscript, int verify_paths) +{ + char *oldN, *newN; + + /* if no action, no need to proceed */ + if (ELEM(NULL, owner_id, act)) + return; + + /* Name sanitation logic - copied from BKE_animdata_fix_paths_rename() */ + if ((oldName != NULL) && (newName != NULL)) { + /* pad the names with [" "] so that only exact matches are made */ + const size_t name_old_len = strlen(oldName); + const size_t name_new_len = strlen(newName); + char *name_old_esc = BLI_array_alloca(name_old_esc, (name_old_len * 2) + 1); + char *name_new_esc = BLI_array_alloca(name_new_esc, (name_new_len * 2) + 1); + + BLI_strescape(name_old_esc, oldName, (name_old_len * 2) + 1); + BLI_strescape(name_new_esc, newName, (name_new_len * 2) + 1); + oldN = BLI_sprintfN("[\"%s\"]", name_old_esc); + newN = BLI_sprintfN("[\"%s\"]", name_new_esc); + } + else { + oldN = BLI_sprintfN("[%d]", oldSubscript); + newN = BLI_sprintfN("[%d]", newSubscript); + } + + /* fix paths in action */ + fcurves_path_rename_fix(owner_id, prefix, oldName, newName, oldN, newN, &act->curves, verify_paths); + + /* free the temp names */ + MEM_freeN(oldN); + MEM_freeN(newN); +} + /* Fix all RNA-Paths in the AnimData block used by the given ID block * NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]> * i.e. pose.bones["Bone"] @@ -725,6 +768,7 @@ void BKE_animdata_fix_paths_rename(ID *owner_id, AnimData *adt, ID *ref_id, cons if (ELEM(NULL, owner_id, adt)) return; + /* Name sanitation logic - shared with BKE_action_fix_paths_rename() */ if ((oldName != NULL) && (newName != NULL)) { /* pad the names with [" "] so that only exact matches are made */ const size_t name_old_len = strlen(oldName); @@ -1523,11 +1567,11 @@ static float nlastrip_get_influence(NlaStrip *strip, float cframe) strip->blendout = fabsf(strip->blendout); /* result depends on where frame is in respect to blendin/out values */ - if (IS_EQ(strip->blendin, 0) == 0 && (cframe <= (strip->start + strip->blendin))) { + if (IS_EQF(strip->blendin, 0.0f) == false && (cframe <= (strip->start + strip->blendin))) { /* there is some blend-in */ return fabsf(cframe - strip->start) / (strip->blendin); } - else if (IS_EQ(strip->blendout, 0) == 0 && (cframe >= (strip->end - strip->blendout))) { + else if (IS_EQF(strip->blendout, 0.0f) == false && (cframe >= (strip->end - strip->blendout))) { /* there is some blend-out */ return fabsf(strip->end - cframe) / (strip->blendout); } @@ -1812,7 +1856,7 @@ static void nlaevalchan_accumulate(NlaEvalChannel *nec, NlaEvalStrip *nes, float inf *= nes->strip_time; /* optimisation: no need to try applying if there is no influence */ - if (IS_EQ(inf, 0)) return; + if (IS_EQF(inf, 0.0f)) return; /* perform blending */ switch (blendmode) { @@ -2030,7 +2074,7 @@ static void nlastrip_evaluate_transition(PointerRNA *ptr, ListBase *channels, Li tmp_nes = *nes; /* evaluate these strips into a temp-buffer (tmp_channels) */ - /* FIXME: modifier evalation here needs some work... */ + /* FIXME: modifier evaluation here needs some work... */ /* first strip */ tmp_nes.strip_mode = NES_TIME_TRANSITION_START; tmp_nes.strip = s1; @@ -2042,7 +2086,7 @@ static void nlastrip_evaluate_transition(PointerRNA *ptr, ListBase *channels, Li nlastrip_evaluate(ptr, &tmp_channels, &tmp_modifiers, &tmp_nes); - /* assumulate temp-buffer and full-buffer, using the 'real' strip */ + /* accumulate temp-buffer and full-buffer, using the 'real' strip */ nlaevalchan_buffers_accumulate(channels, &tmp_channels, nes); /* unlink this strip's modifiers from the parent's modifiers again */ @@ -2080,7 +2124,7 @@ static void nlastrip_evaluate_meta(PointerRNA *ptr, ListBase *channels, ListBase */ nlastrip_evaluate(ptr, &tmp_channels, &tmp_modifiers, tmp_nes); - /* assumulate temp-buffer and full-buffer, using the 'real' strip */ + /* accumulate temp-buffer and full-buffer, using the 'real' strip */ nlaevalchan_buffers_accumulate(channels, &tmp_channels, nes); /* free temp eval-strip */ @@ -2290,7 +2334,7 @@ static void animsys_calculate_nla(PointerRNA *ptr, AnimData *adt, float ctime) /* ***************************************** */ /* Overrides System - Public API */ -/* Clear all overides */ +/* Clear all overrides */ /* Add or get existing Override for given setting */ #if 0 diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 6b2b782717d..3be80a7e30d 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -285,7 +285,7 @@ int bone_autoside_name(char name[MAXBONENAME], int UNUSED(strip_number), short a */ if (axis == 2) { /* z-axis - vertical (top/bottom) */ - if (IS_EQ(head, 0)) { + if (IS_EQF(head, 0.0f)) { if (tail < 0) strcpy(extension, "Bot"); else if (tail > 0) @@ -300,7 +300,7 @@ int bone_autoside_name(char name[MAXBONENAME], int UNUSED(strip_number), short a } else if (axis == 1) { /* y-axis - depth (front/back) */ - if (IS_EQ(head, 0)) { + if (IS_EQF(head, 0.0f)) { if (tail < 0) strcpy(extension, "Fr"); else if (tail > 0) @@ -315,7 +315,7 @@ int bone_autoside_name(char name[MAXBONENAME], int UNUSED(strip_number), short a } else { /* x-axis - horizontal (left/right) */ - if (IS_EQ(head, 0)) { + if (IS_EQF(head, 0.0f)) { if (tail < 0) strcpy(extension, "R"); else if (tail > 0) @@ -405,7 +405,7 @@ static void equalize_bezier(float *data, int desired) dist = ((float)a) * ddist; /* we're looking for location (distance) 'dist' in the array */ - while ((dist >= pdist[nr]) && nr < MAX_BBONE_SUBDIV) + while ((nr < MAX_BBONE_SUBDIV) && (dist >= pdist[nr])) nr++; fac1 = pdist[nr] - pdist[nr - 1]; diff --git a/source/blender/blenkernel/intern/bmfont.c b/source/blender/blenkernel/intern/bmfont.c index 2d7249b54f5..732c0c35feb 100644 --- a/source/blender/blenkernel/intern/bmfont.c +++ b/source/blender/blenkernel/intern/bmfont.c @@ -204,7 +204,7 @@ void detectBitmapFont(ImBuf *ibuf) printf("detectBitmapFont :Unsupported version %d\n", (int)version); } - /* on succes ibuf->userdata points to the bitmapfont */ + /* on success ibuf->userdata points to the bitmapfont */ if (ibuf->userdata) { break; } diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 790c1f09ff0..33c6f3eb7c0 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -762,7 +762,7 @@ float BKE_brush_sample_masktex(const Scene *scene, Brush *br, * radius become inconsistent. * the biggest problem is that it isn't possible to change * unprojected radius because a view context is not - * available. my ussual solution to this is to use the + * available. my usual solution to this is to use the * ratio of change of the size to change the unprojected * radius. Not completely convinced that is correct. * In any case, a better solution is needed to prevent diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c index 370dbc62ef8..cce511aedcb 100644 --- a/source/blender/blenkernel/intern/bvhutils.c +++ b/source/blender/blenkernel/intern/bvhutils.c @@ -557,7 +557,7 @@ BVHTree *bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *dm, float e data->cached = true; /* a NULL nearest callback works fine - * remeber the min distance to point is the same as the min distance to BV of point */ + * remember the min distance to point is the same as the min distance to BV of point */ data->nearest_callback = NULL; data->raycast_callback = NULL; @@ -573,8 +573,9 @@ BVHTree *bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *dm, float e /* Builds a bvh tree.. where nodes are the faces of the given dm. */ BVHTree *bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *dm, float epsilon, int tree_type, int axis) { - BVHTree *tree = bvhcache_find(&dm->bvhCache, BVHTREE_FROM_FACES); BMEditMesh *em = data->em_evil; + const int bvhcache_type = em ? BVHTREE_FROM_FACES_EDITMESH : BVHTREE_FROM_FACES; + BVHTree *tree = bvhcache_find(&dm->bvhCache, bvhcache_type); /* Not in cache */ if (tree == NULL) { @@ -682,7 +683,7 @@ BVHTree *bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *dm, float e /* Save on cache for later use */ // printf("BVHTree built and saved on cache\n"); - bvhcache_insert(&dm->bvhCache, tree, BVHTREE_FROM_FACES); + bvhcache_insert(&dm->bvhCache, tree, bvhcache_type); } } } diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 1bc12cffe7b..d57d9180697 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1063,37 +1063,57 @@ static void cdDM_drawMappedFacesTex(DerivedMesh *dm, static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal) { + const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}; int b; /* orco texture coordinates */ if (attribs->totorco) { + /*const*/ float (*array)[3] = attribs->orco.array; + const float *orco = (array) ? array[index] : zero; + if (attribs->orco.gl_texco) - glTexCoord3fv(attribs->orco.array[index]); + glTexCoord3fv(orco); else - glVertexAttrib3fvARB(attribs->orco.gl_index, attribs->orco.array[index]); + glVertexAttrib3fvARB(attribs->orco.gl_index, orco); } /* uv texture coordinates */ for (b = 0; b < attribs->tottface; b++) { - MTFace *tf = &attribs->tface[b].array[a]; + const float *uv; + + if (attribs->tface[b].array) { + MTFace *tf = &attribs->tface[b].array[a]; + uv = tf->uv[vert]; + } + else { + uv = zero; + } if (attribs->tface[b].gl_texco) - glTexCoord2fv(tf->uv[vert]); + glTexCoord2fv(uv); else - glVertexAttrib2fvARB(attribs->tface[b].gl_index, tf->uv[vert]); + glVertexAttrib2fvARB(attribs->tface[b].gl_index, uv); } /* vertex colors */ for (b = 0; b < attribs->totmcol; b++) { - MCol *cp = &attribs->mcol[b].array[a * 4 + vert]; GLubyte col[4]; - col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; + + if (attribs->mcol[b].array) { + MCol *cp = &attribs->mcol[b].array[a * 4 + vert]; + col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; + } + else { + col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0; + } + glVertexAttrib4ubvARB(attribs->mcol[b].gl_index, col); } /* tangent for normal mapping */ if (attribs->tottang) { - float *tang = attribs->tang.array[a * 4 + vert]; + /*const*/ float (*array)[4] = attribs->tang.array; + const float *tang = (array) ? array[a * 4 + vert] : zero; glVertexAttrib4fvARB(attribs->tang.gl_index, tang); } @@ -1264,25 +1284,29 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, if (do_draw) { DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); - if (attribs.totorco) { + if (attribs.totorco && attribs.orco.array) { datatypes[numdata].index = attribs.orco.gl_index; datatypes[numdata].size = 3; datatypes[numdata].type = GL_FLOAT; numdata++; } for (b = 0; b < attribs.tottface; b++) { - datatypes[numdata].index = attribs.tface[b].gl_index; - datatypes[numdata].size = 2; - datatypes[numdata].type = GL_FLOAT; - numdata++; + if (attribs.tface[b].array) { + datatypes[numdata].index = attribs.tface[b].gl_index; + datatypes[numdata].size = 2; + datatypes[numdata].type = GL_FLOAT; + numdata++; + } } for (b = 0; b < attribs.totmcol; b++) { - datatypes[numdata].index = attribs.mcol[b].gl_index; - datatypes[numdata].size = 4; - datatypes[numdata].type = GL_UNSIGNED_BYTE; - numdata++; + if (attribs.mcol[b].array) { + datatypes[numdata].index = attribs.mcol[b].gl_index; + datatypes[numdata].size = 4; + datatypes[numdata].type = GL_UNSIGNED_BYTE; + numdata++; + } } - if (attribs.tottang) { + if (attribs.tottang && attribs.tang.array) { datatypes[numdata].index = attribs.tang.gl_index; datatypes[numdata].size = 4; datatypes[numdata].type = GL_FLOAT; @@ -1315,34 +1339,38 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, if (do_draw && numdata != 0) { offset = 0; - if (attribs.totorco) { + if (attribs.totorco && attribs.orco.array) { copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v1]); copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v2]); copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v3]); offset += sizeof(float) * 3; } for (b = 0; b < attribs.tottface; b++) { - MTFace *tf = &attribs.tface[b].array[a]; - copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[0]); - copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[1]); + if (attribs.tface[b].array) { + MTFace *tf = &attribs.tface[b].array[a]; + copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[0]); + copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[1]); - copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[2]); - offset += sizeof(float) * 2; + copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[2]); + offset += sizeof(float) * 2; + } } for (b = 0; b < attribs.totmcol; b++) { - MCol *cp = &attribs.mcol[b].array[a * 4 + 0]; - GLubyte col[4]; - col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; - copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col); - cp = &attribs.mcol[b].array[a * 4 + 1]; - col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; - copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col); - cp = &attribs.mcol[b].array[a * 4 + 2]; - col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; - copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col); - offset += sizeof(unsigned char) * 4; + if (attribs.mcol[b].array) { + MCol *cp = &attribs.mcol[b].array[a * 4 + 0]; + GLubyte col[4]; + col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; + copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col); + cp = &attribs.mcol[b].array[a * 4 + 1]; + col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; + copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col); + cp = &attribs.mcol[b].array[a * 4 + 2]; + col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; + copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col); + offset += sizeof(unsigned char) * 4; + } } - if (attribs.tottang) { + if (attribs.tottang && attribs.tang.array) { float *tang = attribs.tang.array[a * 4 + 0]; copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang); tang = attribs.tang.array[a * 4 + 1]; @@ -1357,33 +1385,37 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, if (mface->v4) { if (do_draw && numdata != 0) { offset = 0; - if (attribs.totorco) { + if (attribs.totorco && attribs.orco.array) { copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v3]); copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v4]); copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v1]); offset += sizeof(float) * 3; } for (b = 0; b < attribs.tottface; b++) { - MTFace *tf = &attribs.tface[b].array[a]; - copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[2]); - copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[3]); - copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[0]); - offset += sizeof(float) * 2; + if (attribs.tface[b].array) { + MTFace *tf = &attribs.tface[b].array[a]; + copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[2]); + copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[3]); + copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[0]); + offset += sizeof(float) * 2; + } } for (b = 0; b < attribs.totmcol; b++) { - MCol *cp = &attribs.mcol[b].array[a * 4 + 2]; - GLubyte col[4]; - col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; - copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col); - cp = &attribs.mcol[b].array[a * 4 + 3]; - col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; - copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col); - cp = &attribs.mcol[b].array[a * 4 + 0]; - col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; - copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col); - offset += sizeof(unsigned char) * 4; + if (attribs.mcol[b].array) { + MCol *cp = &attribs.mcol[b].array[a * 4 + 2]; + GLubyte col[4]; + col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; + copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col); + cp = &attribs.mcol[b].array[a * 4 + 3]; + col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; + copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col); + cp = &attribs.mcol[b].array[a * 4 + 0]; + col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; + copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col); + offset += sizeof(unsigned char) * 4; + } } - if (attribs.tottang) { + if (attribs.tottang && attribs.tang.array) { float *tang = attribs.tang.array[a * 4 + 2]; copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang); tang = attribs.tang.array[a * 4 + 3]; @@ -2754,6 +2786,7 @@ void CDDM_calc_edges(DerivedMesh *dm) void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts) { + BLI_assert(numVerts >= 0); if (numVerts < dm->numVertData) CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData - numVerts); @@ -2762,6 +2795,7 @@ void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts) void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges) { + BLI_assert(numEdges >= 0); if (numEdges < dm->numEdgeData) CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData - numEdges); @@ -2770,14 +2804,25 @@ void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges) void CDDM_lower_num_tessfaces(DerivedMesh *dm, int numTessFaces) { + BLI_assert(numTessFaces >= 0); if (numTessFaces < dm->numTessFaceData) CustomData_free_elem(&dm->faceData, numTessFaces, dm->numTessFaceData - numTessFaces); dm->numTessFaceData = numTessFaces; } +void CDDM_lower_num_loops(DerivedMesh *dm, int numLoops) +{ + BLI_assert(numLoops >= 0); + if (numLoops < dm->numLoopData) + CustomData_free_elem(&dm->loopData, numLoops, dm->numLoopData - numLoops); + + dm->numLoopData = numLoops; +} + void CDDM_lower_num_polys(DerivedMesh *dm, int numPolys) { + BLI_assert(numPolys >= 0); if (numPolys < dm->numPolyData) CustomData_free_elem(&dm->polyData, numPolys, dm->numPolyData - numPolys); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index e4c6f7790d7..cab4adf46bf 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -1114,8 +1114,8 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) if ( numedges==0 ) return 0; - /* NOTE: handling ownership of sptings and edgehash is quite sloppy - * currenlty they are never initialized but assert just to be sure */ + /* NOTE: handling ownership of springs and edgehash is quite sloppy + * currently they are never initialized but assert just to be sure */ BLI_assert(cloth->springs == NULL); BLI_assert(cloth->edgehash == NULL); diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 1f892432d80..0dbb739e6f8 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1008,7 +1008,7 @@ static bConstraintTypeInfo CTI_TRACKTO = { trackto_evaluate /* evaluate */ }; -/* --------- Inverse-Kinemetics --------- */ +/* --------- Inverse-Kinematics --------- */ static void kinematic_new_data(void *cdata) { @@ -3075,7 +3075,7 @@ static void clampto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar float offset; /* check to make sure len is not so close to zero that it'll cause errors */ - if (IS_EQ(len, 0) == 0) { + if (IS_EQF(len, 0.0f) == false) { /* find bounding-box range where target is located */ if (ownLoc[clamp_axis] < curveMin[clamp_axis]) { /* bounding-box range is before */ @@ -3107,7 +3107,7 @@ static void clampto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar curvetime = 0.0f; else if (ownLoc[clamp_axis] >= curveMax[clamp_axis]) curvetime = 1.0f; - else if (IS_EQ((curveMax[clamp_axis] - curveMin[clamp_axis]), 0) == 0) + else if (IS_EQF((curveMax[clamp_axis] - curveMin[clamp_axis]), 0.0f) == false) curvetime = (ownLoc[clamp_axis] - curveMin[clamp_axis]) / (curveMax[clamp_axis] - curveMin[clamp_axis]); else curvetime = 0.0f; diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index e255732d3fb..bcf0eafaa65 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -104,10 +104,6 @@ void BKE_curve_editfont_free(Curve *cu) if (cu->editfont) { EditFont *ef = cu->editfont; - if (ef->oldstr) - MEM_freeN(ef->oldstr); - if (ef->oldstrinfo) - MEM_freeN(ef->oldstrinfo); if (ef->textbuf) MEM_freeN(ef->textbuf); if (ef->textbufinfo) @@ -120,6 +116,8 @@ void BKE_curve_editfont_free(Curve *cu) MEM_freeN(ef); cu->editfont = NULL; } + + MEM_SAFE_FREE(cu->selboxes); } void BKE_curve_editNurb_keyIndex_free(EditNurb *editnurb) @@ -230,6 +228,7 @@ Curve *BKE_curve_copy(Curve *cu) cun->editnurb = NULL; cun->editfont = NULL; cun->selboxes = NULL; + cun->lastsel = NULL; #if 0 // XXX old animation system /* single user ipo too */ @@ -579,6 +578,26 @@ Nurb *BKE_nurb_duplicate(Nurb *nu) return newnu; } +/* copy the nurb but allow for different number of points (to be copied after this) */ +Nurb *BKE_nurb_copy(Nurb *src, int pntsu, int pntsv) +{ + Nurb *newnu = (Nurb *)MEM_mallocN(sizeof(Nurb), "copyNurb"); + memcpy(newnu, src, sizeof(Nurb)); + + if (pntsu == 1) SWAP(int, pntsu, pntsv); + newnu->pntsu = pntsu; + newnu->pntsv = pntsv; + + if (src->bezt) { + newnu->bezt = (BezTriple *)MEM_mallocN(pntsu * pntsv * sizeof(BezTriple), "copyNurb2"); + } + else { + newnu->bp = (BPoint *)MEM_mallocN(pntsu * pntsv * sizeof(BPoint), "copyNurb3"); + } + + return newnu; +} + void BKE_nurbList_duplicate(ListBase *lb1, ListBase *lb2) { Nurb *nu, *nun; diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index a183872552d..8aeacda8100 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -335,9 +335,10 @@ void defvert_normalize_lock_single(MDeformVert *dvert, } /* Same as defvert_normalize() if no locked vgroup is a member of the subset */ -void defvert_normalize_lock_map(MDeformVert *dvert, - const bool *vgroup_subset, const int vgroup_tot, - const bool *lock_flags, const int defbase_tot) +void defvert_normalize_lock_map( + MDeformVert *dvert, + const bool *vgroup_subset, const int vgroup_tot, + const bool *lock_flags, const int defbase_tot) { if (dvert->totweight == 0) { /* nothing */ @@ -447,7 +448,7 @@ int *defgroup_flip_map(Object *ob, int *flip_map_len, const bool use_default) } else { bDeformGroup *dg; - char name[sizeof(dg->name)]; + char name_flip[sizeof(dg->name)]; int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__); for (i = 0; i < defbase_tot; i++) { @@ -461,9 +462,10 @@ int *defgroup_flip_map(Object *ob, int *flip_map_len, const bool use_default) if (use_default) map[i] = i; - flip_side_name(name, dg->name, FALSE); - if (strcmp(name, dg->name)) { - flip_num = defgroup_name_index(ob, name); + BKE_deform_flip_side_name(name_flip, dg->name, false); + + if (!STREQ(name_flip, dg->name)) { + flip_num = defgroup_name_index(ob, name_flip); if (flip_num >= 0) { map[i] = flip_num; map[flip_num] = i; /* save an extra lookup */ @@ -485,7 +487,7 @@ int *defgroup_flip_map_single(Object *ob, int *flip_map_len, const bool use_defa } else { bDeformGroup *dg; - char name[sizeof(dg->name)]; + char name_flip[sizeof(dg->name)]; int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__); for (i = 0; i < defbase_tot; i++) { @@ -494,9 +496,9 @@ int *defgroup_flip_map_single(Object *ob, int *flip_map_len, const bool use_defa dg = BLI_findlink(&ob->defbase, defgroup); - flip_side_name(name, dg->name, FALSE); - if (strcmp(name, dg->name)) { - flip_num = defgroup_name_index(ob, name); + BKE_deform_flip_side_name(name_flip, dg->name, false); + if (!STREQ(name_flip, dg->name)) { + flip_num = defgroup_name_index(ob, name_flip); if (flip_num != -1) { map[defgroup] = flip_num; @@ -514,11 +516,12 @@ int defgroup_flip_index(Object *ob, int index, const bool use_default) int flip_index = -1; if (dg) { - char name[sizeof(dg->name)]; - flip_side_name(name, dg->name, 0); + char name_flip[sizeof(dg->name)]; + BKE_deform_flip_side_name(name_flip, dg->name, false); - if (strcmp(name, dg->name)) - flip_index = defgroup_name_index(ob, name); + if (!STREQ(name_flip, dg->name)) { + flip_index = defgroup_name_index(ob, name_flip); + } } return (flip_index == -1 && use_default) ? index : flip_index; @@ -602,7 +605,8 @@ void BKE_deform_split_prefix(const char string[MAX_VGROUP_NAME], char pre[MAX_VG /* finds the best possible flipped name. For renaming; check for unique names afterwards */ /* if strip_number: removes number extensions * note: don't use sizeof() for 'name' or 'from_name' */ -void flip_side_name(char name[MAX_VGROUP_NAME], const char from_name[MAX_VGROUP_NAME], int strip_number) +void BKE_deform_flip_side_name(char name[MAX_VGROUP_NAME], const char from_name[MAX_VGROUP_NAME], + const bool strip_number) { int len; char prefix[MAX_VGROUP_NAME] = ""; /* The part before the facing */ @@ -624,7 +628,7 @@ void flip_side_name(char name[MAX_VGROUP_NAME], const char from_name[MAX_VGROUP_ if (isdigit(name[len - 1])) { index = strrchr(name, '.'); // last occurrence if (index && isdigit(index[1])) { // doesnt handle case bone.1abc2 correct..., whatever! - if (strip_number == 0) { + if (strip_number == false) { BLI_strncpy(number, index, sizeof(number)); } *index = 0; diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index caa5bf90584..c3538b141b5 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -34,7 +34,7 @@ * to three loops per triangle. the derivedmesh stores a cache of tessellations * for each face. this cache will smartly update as needed (though at first * it'll simply be more brute force). keeping track of face/edge counts may - * be a small problbm. + * be a small problem. * * this won't be the most efficient thing, considering that internal edges and * faces of tessellations are exposed. looking up an edge by index in particular @@ -888,23 +888,47 @@ static void emdm_pass_attrib_vertex_glsl(DMVertexAttribs *attribs, BMLoop *loop, { BMVert *eve = loop->v; int i; + const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}; if (attribs->totorco) { - const float *orco = attribs->orco.array[BM_elem_index_get(eve)]; - glVertexAttrib3fvARB(attribs->orco.gl_index, orco); + int index = BM_elem_index_get(eve); + const float *orco = (attribs->orco.array) ? attribs->orco.array[index] : zero; + + if (attribs->orco.gl_texco) + glTexCoord3fv(orco); + else + glVertexAttrib3fvARB(attribs->orco.gl_index, orco); } for (i = 0; i < attribs->tottface; i++) { - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, attribs->tface[i].em_offset); - glVertexAttrib2fvARB(attribs->tface[i].gl_index, luv->uv); + const float *uv; + + if (attribs->tface[i].em_offset != -1) { + const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, attribs->tface[i].em_offset); + uv = luv->uv; + } + else { + uv = zero; + } + + if (attribs->tface[i].gl_texco) + glTexCoord2fv(uv); + else + glVertexAttrib2fvARB(attribs->tface[i].gl_index, uv); } for (i = 0; i < attribs->totmcol; i++) { - const MLoopCol *cp = BM_ELEM_CD_GET_VOID_P(loop, attribs->mcol[i].em_offset); GLubyte col[4]; - col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; + if (attribs->mcol[i].em_offset != -1) { + const MLoopCol *cp = BM_ELEM_CD_GET_VOID_P(loop, attribs->mcol[i].em_offset); + col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; + } + else { + col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0; + } glVertexAttrib4ubvARB(attribs->mcol[i].gl_index, col); } if (attribs->tottang) { - const float *tang = attribs->tang.array[i * 4 + index_in_face]; + int index = i * 4 + index_in_face; + const float *tang = (attribs->tang.array) ? attribs->tang.array[index] : zero; glVertexAttrib4fvARB(attribs->tang.gl_index, tang); } } @@ -1020,38 +1044,6 @@ static void emDM_drawFacesGLSL(DerivedMesh *dm, dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL); } -/* emdm_pass_attrib_vertex_glsl's note about em_offset use applies here */ -static void emdm_pass_attrib_vertex_mat(DMVertexAttribs *attribs, BMLoop *loop, int index_in_face) -{ - BMVert *eve = loop->v; - int i; - - if (attribs->totorco) { - float *orco = attribs->orco.array[BM_elem_index_get(eve)]; - if (attribs->orco.gl_texco) - glTexCoord3fv(orco); - else - glVertexAttrib3fvARB(attribs->orco.gl_index, orco); - } - for (i = 0; i < attribs->tottface; i++) { - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, attribs->tface[i].em_offset); - if (attribs->tface[i].gl_texco) - glTexCoord2fv(luv->uv); - else - glVertexAttrib2fvARB(attribs->tface[i].gl_index, luv->uv); - } - for (i = 0; i < attribs->totmcol; i++) { - const MLoopCol *cp = BM_ELEM_CD_GET_VOID_P(loop, attribs->mcol[i].em_offset); - GLubyte col[4]; - col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; - glVertexAttrib4ubvARB(attribs->mcol[i].gl_index, col); - } - if (attribs->tottang) { - float *tang = attribs->tang.array[i * 4 + index_in_face]; - glVertexAttrib4fvARB(attribs->tang.gl_index, tang); - } -} - static void emDM_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void *userData, int, void *attribs), bool (*setFace)(void *userData, int index), void *userData) @@ -1105,21 +1097,21 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm, if (vertexCos) glNormal3fv(polyNos[BM_elem_index_get(efa)]); else glNormal3fv(efa->no); - emdm_pass_attrib_vertex_mat(&attribs, ltri[0], 0); + emdm_pass_attrib_vertex_glsl(&attribs, ltri[0], 0); if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]); else glVertex3fv(ltri[0]->v->co); - emdm_pass_attrib_vertex_mat(&attribs, ltri[1], 1); + emdm_pass_attrib_vertex_glsl(&attribs, ltri[1], 1); if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]); else glVertex3fv(ltri[1]->v->co); - emdm_pass_attrib_vertex_mat(&attribs, ltri[2], 2); + emdm_pass_attrib_vertex_glsl(&attribs, ltri[2], 2); if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]); else glVertex3fv(ltri[2]->v->co); } else { - emdm_pass_attrib_vertex_mat(&attribs, ltri[0], 0); + emdm_pass_attrib_vertex_glsl(&attribs, ltri[0], 0); if (vertexCos) { glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]); glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]); @@ -1129,7 +1121,7 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm, glVertex3fv(ltri[0]->v->co); } - emdm_pass_attrib_vertex_mat(&attribs, ltri[1], 1); + emdm_pass_attrib_vertex_glsl(&attribs, ltri[1], 1); if (vertexCos) { glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]); glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]); @@ -1139,7 +1131,7 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm, glVertex3fv(ltri[1]->v->co); } - emdm_pass_attrib_vertex_mat(&attribs, ltri[2], 2); + emdm_pass_attrib_vertex_glsl(&attribs, ltri[2], 2); if (vertexCos) { glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]); glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]); @@ -1241,7 +1233,8 @@ static void emDM_getVert(DerivedMesh *dm, int index, MVert *r_vert) return; } - ev = bmdm->em->vert_index[index]; /* should be EDBM_vert_at_index() */ + BLI_assert((bm->elem_table_dirty & BM_VERT) == 0); + ev = bm->vtable[index]; /* should be BM_vert_at_index() */ // ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */ bmvert_to_mvert(bm, ev, r_vert); @@ -1263,7 +1256,10 @@ static void emDM_getVertCo(DerivedMesh *dm, int index, float r_co[3]) copy_v3_v3(r_co, bmdm->vertexCos[index]); } else { - BMVert *ev = bmdm->em->vert_index[index]; /* should be EDBM_vert_at_index() */ + BMVert *ev; + + BLI_assert((bm->elem_table_dirty & BM_VERT) == 0); + ev = bm->vtable[index]; /* should be BM_vert_at_index() */ // ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */ copy_v3_v3(r_co, ev->co); } @@ -1285,7 +1281,10 @@ static void emDM_getVertNo(DerivedMesh *dm, int index, float r_no[3]) copy_v3_v3(r_no, bmdm->vertexNos[index]); } else { - BMVert *ev = bmdm->em->vert_index[index]; /* should be EDBM_vert_at_index() */ + BMVert *ev; + + BLI_assert((bm->elem_table_dirty & BM_VERT) == 0); + ev = bm->vtable[index]; /* should be BM_vert_at_index() */ // ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */ copy_v3_v3(r_no, ev->no); } @@ -1306,7 +1305,10 @@ static void emDM_getPolyNo(DerivedMesh *dm, int index, float r_no[3]) copy_v3_v3(r_no, bmdm->polyNos[index]); } else { - BMFace *efa = bmdm->em->face_index[index]; /* should be EDBM_vert_at_index() */ + BMFace *efa; + + BLI_assert((bm->elem_table_dirty & BM_FACE) == 0); + efa = bm->ftable[index]; /* should be BM_vert_at_index() */ // efa = BM_face_at_index(bm, index); /* warning, does list loop, _not_ ideal */ copy_v3_v3(r_no, efa->no); } @@ -1324,7 +1326,8 @@ static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *r_edge) return; } - e = bmdm->em->edge_index[index]; /* should be EDBM_edge_at_index() */ + BLI_assert((bm->elem_table_dirty & BM_EDGE) == 0); + e = bm->etable[index]; /* should be BM_edge_at_index() */ // e = BM_edge_at_index(bm, index); /* warning, does list loop, _not_ ideal */ r_edge->flag = BM_edge_flag_to_mflag(e); @@ -1848,7 +1851,7 @@ static void statvis_calc_thickness( BM_mesh_elem_index_ensure(bm, BM_VERT); } - bmtree = BKE_bmbvh_new(em, 0, vertexCos, false); + bmtree = BKE_bmbvh_new_from_editmesh(em, 0, vertexCos, false); for (i = 0; i < tottri; i++) { BMFace *f_hit; @@ -1948,7 +1951,7 @@ static void statvis_calc_intersect( BM_mesh_elem_index_ensure(bm, BM_VERT); } - bmtree = BKE_bmbvh_new(em, 0, vertexCos, false); + bmtree = BKE_bmbvh_new_from_editmesh(em, 0, vertexCos, false); BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { BMFace *f_hit; diff --git a/source/blender/blenkernel/intern/editmesh.c b/source/blender/blenkernel/intern/editmesh.c index 6a89d16d7bf..88cef0ec031 100644 --- a/source/blender/blenkernel/intern/editmesh.c +++ b/source/blender/blenkernel/intern/editmesh.c @@ -78,10 +78,6 @@ BMEditMesh *BKE_editmesh_copy(BMEditMesh *em) * used.*/ em_copy->looptris = NULL; - em_copy->vert_index = NULL; - em_copy->edge_index = NULL; - em_copy->face_index = NULL; - return em_copy; } @@ -106,9 +102,8 @@ BMEditMesh *BKE_editmesh_from_object(Object *ob) static void editmesh_tessface_calc_intern(BMEditMesh *em) { - /* use this to avoid locking pthread for _every_ polygon - * and calling the fill function */ -#define USE_TESSFACE_SPEEDUP + /* allocating space before calculating the tessellation */ + BMesh *bm = em->bm; @@ -118,13 +113,6 @@ static void editmesh_tessface_calc_intern(BMEditMesh *em) const int looptris_tot_prev_alloc = em->looptris ? (MEM_allocN_len(em->looptris) / sizeof(*em->looptris)) : 0; BMLoop *(*looptris)[3]; - BMIter iter; - BMFace *efa; - BMLoop *l; - int i = 0; - - ScanFillContext sf_ctx; - MemArena *sf_arena = NULL; #if 0 /* note, we could be clever and re-use this array but would need to ensure @@ -140,7 +128,7 @@ static void editmesh_tessface_calc_intern(BMEditMesh *em) /* this means no reallocs for quad dominant models, for */ if ((em->looptris != NULL) && - /* (em->tottri >= looptris_tot)) */ + /* (*em->tottri >= looptris_tot)) */ /* check against alloc'd size incase we over alloc'd a little */ ((looptris_tot_prev_alloc >= looptris_tot) && (looptris_tot_prev_alloc <= looptris_tot * 2))) { @@ -153,136 +141,10 @@ static void editmesh_tessface_calc_intern(BMEditMesh *em) #endif - BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { - /* don't consider two-edged faces */ - if (UNLIKELY(efa->len < 3)) { - /* do nothing */ - } - -#ifdef USE_TESSFACE_SPEEDUP - - /* no need to ensure the loop order, we know its ok */ - - else if (efa->len == 3) { -#if 0 - int j; - BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) { - looptris[i][j] = l; - } - i += 1; -#else - /* more cryptic but faster */ - BMLoop **l_ptr = looptris[i++]; - l_ptr[0] = l = BM_FACE_FIRST_LOOP(efa); - l_ptr[1] = l = l->next; - l_ptr[2] = l->next; -#endif - } - else if (efa->len == 4) { -#if 0 - BMLoop *ltmp[4]; - int j; - BLI_array_grow_items(looptris, 2); - BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) { - ltmp[j] = l; - } - - looptris[i][0] = ltmp[0]; - looptris[i][1] = ltmp[1]; - looptris[i][2] = ltmp[2]; - i += 1; - - looptris[i][0] = ltmp[0]; - looptris[i][1] = ltmp[2]; - looptris[i][2] = ltmp[3]; - i += 1; -#else - /* more cryptic but faster */ - BMLoop **l_ptr_a = looptris[i++]; - BMLoop **l_ptr_b = looptris[i++]; - (l_ptr_a[0] = l_ptr_b[0] = l = BM_FACE_FIRST_LOOP(efa)); - (l_ptr_a[1] = l = l->next); - (l_ptr_a[2] = l_ptr_b[1] = l = l->next); - ( l_ptr_b[2] = l->next); -#endif - } - -#endif /* USE_TESSFACE_SPEEDUP */ - - else { - int j; - BMLoop *l_iter; - BMLoop *l_first; - - ScanFillVert *sf_vert, *sf_vert_last = NULL, *sf_vert_first = NULL; - /* ScanFillEdge *e; */ /* UNUSED */ - ScanFillFace *sf_tri; - int totfilltri; - - if (UNLIKELY(sf_arena == NULL)) { - sf_arena = BLI_memarena_new(BLI_SCANFILL_ARENA_SIZE, __func__); - } - - BLI_scanfill_begin_arena(&sf_ctx, sf_arena); - - /* scanfill time */ - j = 0; - l_iter = l_first = BM_FACE_FIRST_LOOP(efa); - do { - sf_vert = BLI_scanfill_vert_add(&sf_ctx, l_iter->v->co); - sf_vert->tmp.p = l_iter; - - if (sf_vert_last) { - /* e = */ BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert); - } - - sf_vert_last = sf_vert; - if (sf_vert_first == NULL) { - sf_vert_first = sf_vert; - } - - /*mark order */ - BM_elem_index_set(l_iter, j++); /* set_loop */ - - } while ((l_iter = l_iter->next) != l_first); - - /* complete the loop */ - BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert); - - totfilltri = BLI_scanfill_calc_ex(&sf_ctx, 0, efa->no); - BLI_assert(totfilltri <= efa->len - 2); - (void)totfilltri; - - for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) { - BMLoop **l_ptr = looptris[i++]; - BMLoop *l1 = sf_tri->v1->tmp.p; - BMLoop *l2 = sf_tri->v2->tmp.p; - BMLoop *l3 = sf_tri->v3->tmp.p; - - if (BM_elem_index_get(l1) > BM_elem_index_get(l2)) { SWAP(BMLoop *, l1, l2); } - if (BM_elem_index_get(l2) > BM_elem_index_get(l3)) { SWAP(BMLoop *, l2, l3); } - if (BM_elem_index_get(l1) > BM_elem_index_get(l2)) { SWAP(BMLoop *, l1, l2); } - - l_ptr[0] = l1; - l_ptr[1] = l2; - l_ptr[2] = l3; - } - - BLI_scanfill_end_arena(&sf_ctx, sf_arena); - } - } - - if (sf_arena) { - BLI_memarena_free(sf_arena); - sf_arena = NULL; - } - - em->tottri = i; em->looptris = looptris; - BLI_assert(em->tottri <= looptris_tot); - -#undef USE_TESSFACE_SPEEDUP + /* after allocating the em->looptris, we're ready to tessellate */ + BM_bmesh_calc_tessellation(em->bm, em->looptris, &em->tottri); } @@ -345,10 +207,6 @@ void BKE_editmesh_free(BMEditMesh *em) if (em->looptris) MEM_freeN(em->looptris); - if (em->vert_index) MEM_freeN(em->vert_index); - if (em->edge_index) MEM_freeN(em->edge_index); - if (em->face_index) MEM_freeN(em->face_index); - if (em->bm) BM_mesh_free(em->bm); } diff --git a/source/blender/blenkernel/intern/editmesh_bvh.c b/source/blender/blenkernel/intern/editmesh_bvh.c index cb65fd80fc4..1c0e508e9e6 100644 --- a/source/blender/blenkernel/intern/editmesh_bvh.c +++ b/source/blender/blenkernel/intern/editmesh_bvh.c @@ -44,7 +44,9 @@ struct BMBVHTree { BVHTree *tree; - BMEditMesh *em; + BMLoop *(*looptris)[3]; + int looptris_tot; + BMesh *bm; const float (*cos_cage)[3]; @@ -53,33 +55,39 @@ struct BMBVHTree { int flag; }; -BMBVHTree *BKE_bmbvh_new(BMEditMesh *em, int flag, const float (*cos_cage)[3], const bool cos_cage_free) +BMBVHTree *BKE_bmbvh_new_from_editmesh(BMEditMesh *em, int flag, const float (*cos_cage)[3], const bool cos_cage_free) +{ + return BKE_bmbvh_new(em->bm, em->looptris, em->tottri, flag, cos_cage, cos_cage_free); +} + +BMBVHTree *BKE_bmbvh_new(BMesh *bm, BMLoop *(*looptris)[3], int looptris_tot, int flag, const float (*cos_cage)[3], +const bool cos_cage_free) { /* could become argument */ const float epsilon = FLT_EPSILON * 2.0f; - struct BMLoop *(*looptris)[3] = em->looptris; BMBVHTree *bmtree = MEM_callocN(sizeof(*bmtree), "BMBVHTree"); float cos[3][3]; int i; int tottri; /* BKE_editmesh_tessface_calc() must be called already */ - BLI_assert(em->tottri != 0 || em->bm->totface == 0); + BLI_assert(looptris_tot != 0 || bm->totface == 0); if (cos_cage) { - BM_mesh_elem_index_ensure(em->bm, BM_VERT); + BM_mesh_elem_index_ensure(bm, BM_VERT); } - bmtree->em = em; - bmtree->bm = em->bm; + bmtree->looptris = looptris; + bmtree->looptris_tot = looptris_tot; + bmtree->bm = bm; bmtree->cos_cage = cos_cage; bmtree->cos_cage_free = cos_cage_free; bmtree->flag = flag; if (flag & (BMBVH_RESPECT_SELECT)) { tottri = 0; - for (i = 0; i < em->tottri; i++) { + for (i = 0; i < looptris_tot; i++) { if (BM_elem_flag_test(looptris[i][0]->f, BM_ELEM_SELECT)) { tottri++; } @@ -87,23 +95,23 @@ BMBVHTree *BKE_bmbvh_new(BMEditMesh *em, int flag, const float (*cos_cage)[3], c } else if (flag & (BMBVH_RESPECT_HIDDEN)) { tottri = 0; - for (i = 0; i < em->tottri; i++) { + for (i = 0; i < looptris_tot; i++) { if (!BM_elem_flag_test(looptris[i][0]->f, BM_ELEM_HIDDEN)) { tottri++; } } } else { - tottri = em->tottri; + tottri = looptris_tot; } bmtree->tree = BLI_bvhtree_new(tottri, epsilon, 8, 8); - for (i = 0; i < em->tottri; i++) { + for (i = 0; i < looptris_tot; i++) { if (flag & BMBVH_RESPECT_SELECT) { /* note, the arrays wont align now! take care */ - if (!BM_elem_flag_test(em->looptris[i][0]->f, BM_ELEM_SELECT)) { + if (!BM_elem_flag_test(looptris[i][0]->f, BM_ELEM_SELECT)) { continue; } } @@ -231,14 +239,14 @@ BMFace *BKE_bmbvh_ray_cast(BMBVHTree *bmtree, const float co[3], const float dir hit.index = -1; /* ok to leave 'uv' uninitialized */ - bmcb_data.looptris = (const BMLoop *(*)[3])bmtree->em->looptris; + bmcb_data.looptris = (const BMLoop *(*)[3])bmtree->looptris; bmcb_data.cos_cage = (const float (*)[3])bmtree->cos_cage; BLI_bvhtree_ray_cast(bmtree->tree, co, dir, radius, &hit, bmbvh_ray_cast_cb, &bmcb_data); if (hit.index != -1 && hit.dist != dist) { if (r_hitout) { if (bmtree->flag & BMBVH_RETURN_ORIG) { - BMLoop **ltri = bmtree->em->looptris[hit.index]; + BMLoop **ltri = bmtree->looptris[hit.index]; interp_v3_v3v3v3_uv(r_hitout, ltri[0]->v->co, ltri[1]->v->co, ltri[2]->v->co, bmcb_data.uv); } else { @@ -254,7 +262,7 @@ BMFace *BKE_bmbvh_ray_cast(BMBVHTree *bmtree, const float co[3], const float dir *r_dist = hit.dist; } - return bmtree->em->looptris[hit.index][0]->f; + return bmtree->looptris[hit.index][0]->f; } return NULL; @@ -327,7 +335,7 @@ BMFace *BKE_bmbvh_find_face_segment(BMBVHTree *bmtree, const float co_a[3], cons hit.index = -1; /* ok to leave 'uv' uninitialized */ - bmcb_data.looptris = (const BMLoop *(*)[3])bmtree->em->looptris; + bmcb_data.looptris = (const BMLoop *(*)[3])bmtree->looptris; bmcb_data.cos_cage = (const float (*)[3])bmtree->cos_cage; bmcb_data.co_a = co_a; bmcb_data.co_b = co_b; @@ -337,7 +345,7 @@ BMFace *BKE_bmbvh_find_face_segment(BMBVHTree *bmtree, const float co_a[3], cons /* duplicate of BKE_bmbvh_ray_cast() */ if (r_hitout) { if (bmtree->flag & BMBVH_RETURN_ORIG) { - BMLoop **ltri = bmtree->em->looptris[hit.index]; + BMLoop **ltri = bmtree->looptris[hit.index]; interp_v3_v3v3v3_uv(r_hitout, ltri[0]->v->co, ltri[1]->v->co, ltri[2]->v->co, bmcb_data.uv); } else { @@ -354,7 +362,7 @@ BMFace *BKE_bmbvh_find_face_segment(BMBVHTree *bmtree, const float co_a[3], cons *r_fac = hit.dist / dist; } - return bmtree->em->looptris[hit.index][0]->f; + return bmtree->looptris[hit.index][0]->f; } return NULL; @@ -410,13 +418,13 @@ BMVert *BKE_bmbvh_find_vert_closest(BMBVHTree *bmtree, const float co[3], const hit.dist = maxdist_sq; hit.index = -1; - bmcb_data.looptris = (const BMLoop *(*)[3])bmtree->em->looptris; + bmcb_data.looptris = (const BMLoop *(*)[3])bmtree->looptris; bmcb_data.cos_cage = (const float (*)[3])bmtree->cos_cage; bmcb_data.maxdist = maxdist_sq; BLI_bvhtree_find_nearest(bmtree->tree, co, &hit, bmbvh_find_vert_closest_cb, &bmcb_data); if (hit.index != -1) { - BMLoop **ltri = bmtree->em->looptris[hit.index]; + BMLoop **ltri = bmtree->looptris[hit.index]; return ltri[bmcb_data.index_tri]->v; } diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index dbdf30ea63d..a40d7401566 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -2139,11 +2139,39 @@ float evaluate_fcurve(FCurve *fcu, float evaltime) /* if there is a driver (only if this F-Curve is acting as 'driver'), evaluate it to find value to use as "evaltime" * since drivers essentially act as alternative input (i.e. in place of 'time') for F-Curves - * - this value will also be returned as the value of the 'curve', if there are no keyframes */ if (fcu->driver) { /* evaltime now serves as input for the curve */ - evaltime = cvalue = evaluate_driver(fcu->driver, evaltime); + evaltime = evaluate_driver(fcu->driver, evaltime); + + /* only do a default 1-1 mapping if it's unlikely that anything else will set a value... */ + if (fcu->totvert == 0) { + FModifier *fcm; + bool do_linear = true; + + /* out-of-range F-Modifiers will block, as will those which just plain overwrite the values + * XXX: additive is a bit more dicey; it really depends then if things are in range or not... + */ + for (fcm = fcu->modifiers.first; fcm; fcm = fcm->next) { + /* if there are range-restrictions, we must definitely block [#36950] */ + if ((fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) == 0 || + ((fcm->sfra <= evaltime) && (fcm->efra >= evaltime)) ) + { + /* within range: here it probably doesn't matter, though we'd want to check on additive... */ + } + else { + /* outside range: modifier shouldn't contribute to the curve here, though it does in other areas, + * so neither should the driver! + */ + do_linear = false; + } + } + + /* only copy over results if none of the modifiers disagreed with this */ + if (do_linear) { + cvalue = evaltime; + } + } } /* evaluate modifiers which modify time to evaluate the base curve at */ diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index f24d84df2e8..f489adc7445 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -315,25 +315,13 @@ static void build_underline(Curve *cu, float x1, float y1, float x2, float y2, i MEM_freeN(nu2); return; } - nu2->bp = bp; - nu2->bp[0].vec[0] = x1; - nu2->bp[0].vec[1] = y1; - nu2->bp[0].vec[2] = 0; - nu2->bp[0].vec[3] = 1.0f; - nu2->bp[1].vec[0] = x2; - nu2->bp[1].vec[1] = y1; - nu2->bp[1].vec[2] = 0; - nu2->bp[1].vec[3] = 1.0f; - nu2->bp[2].vec[0] = x2; - nu2->bp[2].vec[1] = y2; - nu2->bp[2].vec[2] = 0; - nu2->bp[2].vec[3] = 1.0f; - nu2->bp[3].vec[0] = x1; - nu2->bp[3].vec[1] = y2; - nu2->bp[3].vec[2] = 0; - nu2->bp[3].vec[3] = 1.0f; - + copy_v4_fl4(bp[0].vec, x1, y1, 0.0f, 1.0f); + copy_v4_fl4(bp[1].vec, x2, y1, 0.0f, 1.0f); + copy_v4_fl4(bp[2].vec, x2, y2, 0.0f, 1.0f); + copy_v4_fl4(bp[3].vec, x1, y2, 0.0f, 1.0f); + + nu2->bp = bp; BLI_addtail(&(cu->nurb), nu2); } diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 4d17bd286b4..42e146301a2 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -38,6 +38,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BLI_math_vector.h" #include "BLF_translation.h" @@ -182,7 +183,7 @@ bGPDlayer *gpencil_layer_addnew(bGPdata *gpd, const char *name, int setactive) BLI_addtail(&gpd->layers, gpl); /* set basic settings */ - gpl->color[3] = 0.9f; + copy_v4_v4(gpl->color, U.gpencil_new_layer_col); gpl->thickness = 3; /* auto-name */ diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index 6f275e4ec75..594c918b4c2 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -641,7 +641,7 @@ int IDP_InsertToGroup(IDProperty *group, IDProperty *previous, IDProperty *pnew) * IDP_FreeProperty(prop); //free all subdata * MEM_freeN(prop); //free property struct itself */ -void IDP_RemFromGroup(IDProperty *group, IDProperty *prop) +void IDP_RemoveFromGroup(IDProperty *group, IDProperty *prop) { BLI_assert(group->type == IDP_GROUP); @@ -649,6 +649,16 @@ void IDP_RemFromGroup(IDProperty *group, IDProperty *prop) BLI_remlink(&group->data.group, prop); } +/** + * Removes the property from the group and frees it. + */ +void IDP_FreeFromGroup(IDProperty *group, IDProperty *prop) +{ + IDP_RemoveFromGroup(group, prop); + IDP_FreeProperty(prop); + MEM_freeN(prop); +} + IDProperty *IDP_GetPropertyFromGroup(IDProperty *prop, const char *name) { BLI_assert(prop->type == IDP_GROUP); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 01b41eb22cd..6a411f8c308 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -191,17 +191,21 @@ void BKE_image_de_interlace(Image *ima, int odd) /* ***************** ALLOC & FREE, DATA MANAGING *************** */ -static void image_free_buffers(Image *ima) +static void image_free_cahced_frames(Image *image) { ImBuf *ibuf; - - while ((ibuf = BLI_pophead(&ima->ibufs))) { + while ((ibuf = BLI_pophead(&image->ibufs))) { if (ibuf->userdata) { MEM_freeN(ibuf->userdata); ibuf->userdata = NULL; } IMB_freeImBuf(ibuf); } +} + +static void image_free_buffers(Image *ima) +{ + image_free_cahced_frames(ima); if (ima->anim) IMB_free_anim(ima->anim); ima->anim = NULL; @@ -2237,7 +2241,7 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal) #else /* image buffers for non-sequence multilayer will share buffers with RenderResult, * however sequence multilayer will own buffers. Such logic makes switching from - * single multilayer file to sequence completely instable + * single multilayer file to sequence completely unstable * since changes in nodes seems this workaround isn't needed anymore, all sockets * are nicely detecting anyway, but freeing buffers always here makes multilayer * sequences behave stable @@ -2505,26 +2509,22 @@ static ImBuf *image_load_sequence_multilayer(Image *ima, ImageUser *iuser, int f /* check for new RenderResult */ if (ima->rr == NULL || frame != ima->rr->framenr) { - /* copy to survive not found multilayer image */ - RenderResult *oldrr = ima->rr; + if (ima->rr) { + /* Cached image buffers shares pointers with render result, + * need to ensure there's no image buffers are hanging around + * with dead links after freeing the render result. + */ + image_free_cahced_frames(ima); + RE_FreeRenderResult(ima->rr); + ima->rr = NULL; + } - ima->rr = NULL; ibuf = image_load_sequence_file(ima, iuser, frame); if (ibuf) { /* actually an error */ ima->type = IMA_TYPE_IMAGE; printf("error, multi is normal image\n"); } - // printf("loaded new result %p\n", ima->rr); - /* free result if new one found */ - if (ima->rr) { - // if (oldrr) printf("freed previous result %p\n", oldrr); - if (oldrr) RE_FreeRenderResult(oldrr); - } - else { - ima->rr = oldrr; - } - } if (ima->rr) { RenderPass *rpass = BKE_image_multilayer_index(ima->rr, iuser); diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index ecc4a03d255..8ef3b7ef23d 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -712,17 +712,6 @@ static const char *world_adrcodes_to_paths(int adrcode, int *array_index) return "mist.start"; case WO_MISTHI: return "mist.height"; - - case WO_STAR_R: - case WO_STAR_G: - case WO_STAR_B: - printf("WARNING: WO_STAR_R/G/B deprecated\n"); - return NULL; - - case WO_STARDIST: - return "stars.min_distance"; - case WO_STARSIZE: - return "stars.size"; default: /* for now, we assume that the others were MTex channels */ return mtex_adrcodes_to_paths(adrcode, array_index); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index c856d8cfea4..b20b4294f84 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -462,7 +462,7 @@ void BKE_mask_point_handle(MaskSplinePoint *point, float handle[2]) handle[1] = (point->bezt.vec[1][1] - vec[0]); } -void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], int keep_direction, +void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], bool keep_direction, float orig_handle[2], float orig_vec[3][3]) { BezTriple *bezt = &point->bezt; @@ -1443,7 +1443,7 @@ void BKE_mask_spline_ensure_deform(MaskSpline *spline) } } -void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const int do_newframe) +void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const bool do_newframe) { /* animation if available */ if (do_newframe) { @@ -1521,7 +1521,7 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const int do } } -void BKE_mask_evaluate(Mask *mask, const float ctime, const int do_newframe) +void BKE_mask_evaluate(Mask *mask, const float ctime, const bool do_newframe) { MaskLayer *masklay; @@ -1562,10 +1562,10 @@ void BKE_mask_update_display(Mask *mask, float ctime) } #endif - BKE_mask_evaluate(mask, ctime, FALSE); + BKE_mask_evaluate(mask, ctime, false); } -void BKE_mask_evaluate_all_masks(Main *bmain, float ctime, const int do_newframe) +void BKE_mask_evaluate_all_masks(Main *bmain, float ctime, const bool do_newframe) { Mask *mask; @@ -1772,7 +1772,7 @@ int BKE_mask_layer_shape_find_frame_range(MaskLayer *masklay, const float frame, } } -MaskLayerShape *BKE_mask_layer_shape_varify_frame(MaskLayer *masklay, const int frame) +MaskLayerShape *BKE_mask_layer_shape_verify_frame(MaskLayer *masklay, const int frame) { MaskLayerShape *masklay_shape; @@ -1835,8 +1835,8 @@ 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) +bool BKE_mask_layer_shape_spline_from_index(MaskLayer *masklay, int index, + MaskSpline **r_masklay_shape, int *r_index) { MaskSpline *spline; @@ -1844,12 +1844,12 @@ int BKE_mask_layer_shape_spline_from_index(MaskLayer *masklay, int index, if (index < spline->tot_point) { *r_masklay_shape = spline; *r_index = index; - return TRUE; + return true; } index -= spline->tot_point; } - return FALSE; + return false; } int BKE_mask_layer_shape_spline_to_index(MaskLayer *masklay, MaskSpline *spline) @@ -1891,7 +1891,7 @@ static void interp_weights_uv_v2_apply(const float uv[2], float r_pt[2], const f /* when a new points added - resize all shapekey array */ void BKE_mask_layer_shape_changed_add(MaskLayer *masklay, int index, - int do_init, int do_init_interpolate) + bool do_init, bool do_init_interpolate) { MaskLayerShape *masklay_shape; diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index a4b59153e2b..83c257dbd56 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -1637,22 +1637,6 @@ static void polygonize(PROCESS *process, MetaBall *mb) } } -/* could move to math api */ -BLI_INLINE void copy_v3_fl3(float v[3], float x, float y, float z) -{ - v[0] = x; - v[1] = y; - v[2] = z; -} - -/* TODO(sergey): Perhaps it could be general utility function in mathutils. */ -static bool has_zero_axis_m4(float matrix[4][4]) -{ - return len_squared_v3(matrix[0]) < FLT_EPSILON || - len_squared_v3(matrix[1]) < FLT_EPSILON || - len_squared_v3(matrix[2]) < FLT_EPSILON; -} - static float init_meta(PROCESS *process, Scene *scene, Object *ob) /* return totsize */ { Scene *sce_iter = scene; diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index a77f768835a..e6fca21f2af 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -708,26 +708,32 @@ bool BKE_mesh_uv_cdlayer_rename(Mesh *me, const char *old_name, const char *new_ return false; } else { - lidx = lidx_start + (fidx - fidx_start); + lidx = fidx; } } - pidx = pidx_start + (lidx - lidx_start); + pidx = lidx; } else { if (lidx == -1) { - lidx = lidx_start + (pidx - pidx_start); + lidx = pidx; } if (fidx == -1 && do_tessface) { - fidx = fidx_start + (pidx - pidx_start); + fidx = pidx; } } #if 0 /* For now, we do not consider mismatch in indices (i.e. same name leading to (relative) different indices). */ - else if ((pidx - pidx_start) != (lidx - lidx_start)) { - lidx = lidx_start + (pidx - pidx_start); + else if (pidx != lidx) { + lidx = pidx; } #endif + /* Go back to absolute indices! */ + pidx += pidx_start; + lidx += lidx_start; + if (fidx != -1) + fidx += fidx_start; + return BKE_mesh_uv_cdlayer_rename_index(me, pidx, lidx, fidx, new_name, do_tessface); } } @@ -1345,6 +1351,8 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, mloopuv->uv[1] = (v % dl->nr) / (float)orco_sizeu; /* cyclic correction */ + if ((i == 1 || i == 2) && mloopuv->uv[0] == 0.0f) + mloopuv->uv[0] = 1.0f; if ((i == 0 || i == 1) && mloopuv->uv[1] == 0.0f) mloopuv->uv[1] = 1.0f; } diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index 47b8e053bf7..1e74ce23c2c 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -379,7 +379,8 @@ void BKE_mesh_normals_loop_split(MVert *mverts, const int UNUSED(numVerts), MEdg if ((e2l[0] | e2l[1]) == 0) { /* 'Empty' edge until now, set e2l[0] (and e2l[1] to INDEX_UNSET to tag it as unset). */ e2l[0] = ml_curr_index; - e2l[1] = INDEX_UNSET; + /* We have to check this here too, else we might miss some flat faces!!! */ + e2l[1] = (mp->flag & ME_SMOOTH) ? INDEX_UNSET : INDEX_INVALID; } else if (e2l[1] == INDEX_UNSET) { /* Second loop using this edge, time to test its sharpness. @@ -945,7 +946,7 @@ bool BKE_mesh_center_centroid(Mesh *me, float cent[3]) * \{ */ -/* ngon version wip, based on EDBM_uv_vert_map_create */ +/* ngon version wip, based on BM_uv_vert_map_create */ /* this replaces the non bmesh function (in trunk) which takes MTFace's, if we ever need it back we could * but for now this replaces it because its unused. */ diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index 1c9576d74d0..a4f5529ee43 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -922,7 +922,7 @@ bool BKE_mesh_validate_all_customdata(CustomData *vdata, CustomData *edata, { bool is_valid = true; bool is_change_v, is_change_e, is_change_l, is_change_p; - int tot_texpoly, tot_uvloop; + int tot_texpoly, tot_uvloop, tot_vcolloop; CustomDataMask mask = check_meshmask ? CD_MASK_MESH : 0; is_valid &= mesh_validate_customdata(vdata, mask, do_verbose, do_fixes, &is_change_v); @@ -932,10 +932,23 @@ bool BKE_mesh_validate_all_customdata(CustomData *vdata, CustomData *edata, tot_texpoly = CustomData_number_of_layers(pdata, CD_MTEXPOLY); tot_uvloop = CustomData_number_of_layers(ldata, CD_MLOOPUV); + tot_vcolloop = CustomData_number_of_layers(ldata, CD_MLOOPCOL); if (tot_texpoly != tot_uvloop) { PRINT_ERR("\tCustomDataLayer mismatch, tot_texpoly(%d), tot_uvloop(%d)\n", tot_texpoly, tot_uvloop); } + if (tot_texpoly > MAX_MTFACE) { + PRINT_ERR("\tMore UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n", + MAX_MTFACE, tot_texpoly - MAX_MTFACE); + } + if (tot_uvloop > MAX_MTFACE) { + PRINT_ERR("\tMore UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n", + MAX_MTFACE, tot_uvloop - MAX_MTFACE); + } + if (tot_vcolloop > MAX_MCOL) { + PRINT_ERR("\tMore VCol layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n", + MAX_MCOL, tot_vcolloop - MAX_MCOL); + } *r_change = (is_change_v || is_change_e || is_change_l || is_change_p); @@ -989,10 +1002,25 @@ void BKE_mesh_cd_validate(Mesh *me) { int totlayer_mtex = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY); int totlayer_uv = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); + int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); int mtex_index = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY); int uv_index = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV); int i; + /* XXX For now, do not delete those, just warn they are not really usable. */ + if (UNLIKELY(totlayer_mtex > MAX_MTFACE)) { + printf("WARNING! More UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n", + MAX_MTFACE, totlayer_mtex - MAX_MTFACE); + } + if (UNLIKELY(totlayer_uv > MAX_MTFACE)) { + printf("WARNING! More UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n", + MAX_MTFACE, totlayer_uv - MAX_MTFACE); + } + if (UNLIKELY(totlayer_mcol > MAX_MCOL)) { + printf("WARNING! More VCol layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n", + MAX_MCOL, totlayer_mcol - MAX_MCOL); + } + if (LIKELY(totlayer_mtex == totlayer_uv)) { /* pass */ } diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index c0df306a3fa..869dbe032c9 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -959,9 +959,6 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node) { bNodeLink *link, *link_next; - if (node->internal_links.first == NULL) - return; - /* store link pointers in output sockets, for efficient lookup */ for (link = node->internal_links.first; link; link = link->next) link->tosock->link = link; @@ -1675,8 +1672,8 @@ static void free_localized_node_groups(bNodeTree *ntree) for (node = ntree->nodes.first; node; node = node->next) { if (node->type == NODE_GROUP && node->id) { bNodeTree *ngroup = (bNodeTree *)node->id; - if (BLI_findindex(&G.main->nodetree, ngroup) == -1) { - /* ntree is not in library, i.e. localized node group: free it */ + if (ngroup->flag & NTREE_IS_LOCALIZED) { + /* ntree is a localized copy: free it */ ntreeFreeTree_ex(ngroup, false); MEM_freeN(ngroup); } @@ -1963,6 +1960,7 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree) * Note: previews are not copied here. */ ltree = ntreeCopyTree_internal(ntree, NULL, FALSE, FALSE, FALSE); + ltree->flag |= NTREE_IS_LOCALIZED; for (node = ltree->nodes.first; node; node = node->next) { if (node->type == NODE_GROUP && node->id) { @@ -3091,14 +3089,14 @@ void nodeSynchronizeID(bNode *node, bool copy_to_id) /* ************* node type access ********** */ -const char *nodeLabel(bNode *node) +void nodeLabel(bNodeTree *ntree, bNode *node, char *label, int maxlen) { if (node->label[0] != '\0') - return node->label; + BLI_strncpy(label, node->label, maxlen); else if (node->typeinfo->labelfunc) - return node->typeinfo->labelfunc(node); + node->typeinfo->labelfunc(ntree, node, label, maxlen); else - return IFACE_(node->typeinfo->ui_name); + BLI_strncpy(label, IFACE_(node->typeinfo->ui_name), maxlen); } static void node_type_base_defaults(bNodeType *ntype) @@ -3269,7 +3267,7 @@ void node_type_storage(bNodeType *ntype, ntype->freefunc = freefunc; } -void node_type_label(struct bNodeType *ntype, const char *(*labelfunc)(struct bNode *)) +void node_type_label(struct bNodeType *ntype, void (*labelfunc)(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen)) { ntype->labelfunc = labelfunc; } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 8c2475369de..45d9d144f55 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -32,7 +32,7 @@ #include <string.h> #include <math.h> -#include <stdio.h> +#include <stdio.h> #include "MEM_guardedalloc.h" @@ -194,6 +194,28 @@ void BKE_object_free_modifiers(Object *ob) BKE_object_free_softbody(ob); } +void BKE_object_modifier_hook_reset(Object *ob, HookModifierData *hmd) +{ + /* reset functionality */ + if (hmd->object) { + bPoseChannel *pchan = BKE_pose_channel_find_name(hmd->object->pose, hmd->subtarget); + + if (hmd->subtarget[0] && pchan) { + float imat[4][4], mat[4][4]; + + /* calculate the world-space matrix for the pose-channel target first, then carry on as usual */ + mul_m4_m4m4(mat, hmd->object->obmat, pchan->pose_mat); + + invert_m4_m4(imat, mat); + mul_m4_m4m4(hmd->parentinv, imat, ob->obmat); + } + else { + invert_m4_m4(hmd->object->imat, hmd->object->obmat); + mul_m4_m4m4(hmd->parentinv, hmd->object->imat, ob->obmat); + } + } +} + bool BKE_object_support_modifier_type_check(Object *ob, int modifier_type) { ModifierTypeInfo *mti; @@ -234,6 +256,11 @@ void BKE_object_link_modifiers(struct Object *ob_dst, struct Object *ob_src) if (!BKE_object_support_modifier_type_check(ob_dst, md->type)) continue; + + if (md->type == eModifierType_Skin) { + /* ensure skin-node customdata exists */ + modifier_skin_customdata_ensure(ob_dst); + } nmd = modifier_new(md->type); BLI_strncpy(nmd->name, md->name, sizeof(nmd->name)); @@ -568,6 +595,9 @@ void BKE_object_unlink(Object *ob) } } } + + if (tpsys->parent == ob) + tpsys->parent = NULL; } if (ob->pd) DAG_id_tag_update(&obt->id, OB_RECALC_DATA); @@ -1277,6 +1307,11 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, int copy_caches) obn->mode = 0; obn->sculpt = NULL; + /* Proxies are not to be copied. */ + obn->proxy_from = NULL; + obn->proxy_group = NULL; + obn->proxy = NULL; + /* increase user numbers */ id_us_plus((ID *)obn->data); id_us_plus((ID *)obn->gpd); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 526d54a97fa..41217110cd8 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2006,6 +2006,12 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, pa->lifetime = 100.0f; } else { + /* initialize the lifetime, in case the texture coordinates + * are from Particles/Strands, which would cause undefined values + */ + pa->lifetime = part->lifetime * (1.0f - part->randlife * PSYS_FRAND(p + 21)); + pa->dietime = pa->time + pa->lifetime; + /* get possible textural influence */ psys_get_texture(sim, pa, &ptex, PAMAP_LIFE, cfra); @@ -2844,10 +2850,10 @@ static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *fo continue; } - /* Find vector to neighbour. Exclude particles that are more than 2h + /* Find vector to neighbor. Exclude particles that are more than 2h * away. Can't use current state here because it may have changed on * another thread - so do own mini integration. Unlike basic_integrate, - * SPH integration depends on neighbouring particles. - z0r */ + * SPH integration depends on neighboring particles. - z0r */ madd_v3_v3v3fl(co, npa->prev_state.co, npa->prev_state.vel, state->time); sub_v3_v3v3(vec, co, state->co); rij = normalize_v3(vec); diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 45a29f6cc90..c9822600fe7 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -1283,6 +1283,11 @@ void BKE_pbvh_node_mark_rebuild_draw(PBVHNode *node) node->flag |= PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw; } +void BKE_pbvh_node_mark_redraw(PBVHNode *node) +{ + node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw; +} + void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden) { BLI_assert(node->flag & PBVH_Leaf); diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 334ef9b2d3d..381237f713c 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -1426,7 +1426,7 @@ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) } } -/* Used when cancelling transforms - return rigidbody and object to initial states */ +/* Used when canceling transforms - return rigidbody and object to initial states */ void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) { RigidBodyOb *rbo = ob->rigidbody_object; diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 41e43c00457..985eae18570 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -157,6 +157,7 @@ Scene *BKE_scene_copy(Scene *sce, int type) lb = scen->r.layers; scen->r = sce->r; scen->r.layers = lb; + scen->r.actlay = 0; scen->unit = sce->unit; scen->physics_settings = sce->physics_settings; scen->gm = sce->gm; @@ -443,7 +444,6 @@ Scene *BKE_scene_add(Main *bmain, const char *name) sce->r.blurfac = 0.5; sce->r.frs_sec = 24; sce->r.frs_sec_base = 1; - sce->r.edgeint = 10; sce->r.ocres = 128; /* OCIO_TODO: for forwards compatibility only, so if no tonecurve are used, @@ -503,6 +503,8 @@ Scene *BKE_scene_add(Main *bmain, const char *name) sce->toolsettings->normalsize = 0.1; sce->toolsettings->autokey_mode = U.autokey_mode; + sce->toolsettings->snap_node_mode = SCE_SNAP_MODE_GRID; + sce->toolsettings->skgen_resolution = 100; sce->toolsettings->skgen_threshold_internal = 0.01f; sce->toolsettings->skgen_threshold_external = 0.01f; @@ -874,18 +876,35 @@ Object *BKE_scene_camera_switch_find(Scene *scene) TimeMarker *m; int cfra = scene->r.cfra; int frame = -(MAXFRAME + 1); + int min_frame = MAXFRAME + 1; Object *camera = NULL; + Object *first_camera = NULL; for (m = scene->markers.first; m; m = m->next) { - if (m->camera && (m->camera->restrictflag & OB_RESTRICT_RENDER) == 0 && (m->frame <= cfra) && (m->frame > frame)) { - camera = m->camera; - frame = m->frame; + if (m->camera && (m->camera->restrictflag & OB_RESTRICT_RENDER) == 0) { + if ((m->frame <= cfra) && (m->frame > frame)) { + camera = m->camera; + frame = m->frame; - if (frame == cfra) - break; + if (frame == cfra) + break; + } + if (m->frame < min_frame) { + first_camera = m->camera; + min_frame = m->frame; + } } } + + if (camera == NULL) { + /* If there's no marker to the left of current frame, + * use camera from left-most marker to solve all sort + * of Schrodinger uncertainties. + */ + return first_camera; + } + return camera; } #endif @@ -1285,7 +1304,7 @@ 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); + 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 @@ -1484,16 +1503,6 @@ void BKE_scene_disable_color_management(Scene *scene) int BKE_scene_check_color_management_enabled(const Scene *scene) { - /* TODO(sergey): shouldn't be needed. but we're currently far to close to the release, - * so better be extra-safe than sorry. - * - * Will remove the check after the release. - */ - if (!scene) { - BLI_assert(!"Shouldn't happen!"); - return TRUE; - } - return strcmp(scene->display_settings.display_device, "None") != 0; } diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index dd7e847feaf..49b237fc3ea 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -463,6 +463,7 @@ void BKE_sequencer_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, int make_ if (!STREQ(float_colorspace, to_colorspace)) { IMB_colormanagement_transform_threaded(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, true); + sequencer_imbuf_assign_spaces(scene, ibuf); } } } @@ -1854,7 +1855,6 @@ void BKE_sequencer_color_balance_apply(StripColorBalance *cb, ImBuf *ibuf, float init_data.cb = cb; init_data.ibuf = ibuf; init_data.mul = mul; - init_data.mask = NULL; init_data.make_float = make_float; init_data.mask = mask_input; @@ -2342,7 +2342,7 @@ static ImBuf *seq_render_mask(SeqRenderData context, Mask *mask, float nr, short mask_temp = BKE_mask_copy_nolib(mask); - BKE_mask_evaluate(mask_temp, mask->sfra + nr, TRUE); + BKE_mask_evaluate(mask_temp, mask->sfra + nr, true); maskbuf = MEM_mallocN(sizeof(float) * context.rectx * context.recty, __func__); diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 5c9c564998e..3a6912157fd 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -136,7 +136,7 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc) nearest.index = -1; nearest.dist = FLT_MAX; #ifndef __APPLE__ -#pragma omp parallel for default(none) private(i) firstprivate(nearest) shared(treeData,calc) schedule(static) +#pragma omp parallel for default(none) private(i) firstprivate(nearest) shared(treeData, calc) schedule(static) #endif for (i = 0; i < calc->numVerts; ++i) { float *co = calc->vertexCos[i]; @@ -331,7 +331,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc) { #ifndef __APPLE__ -#pragma omp parallel for private(i,hit) schedule(static) +#pragma omp parallel for private(i, hit) schedule(static) #endif for (i = 0; i < calc->numVerts; ++i) { float *co = calc->vertexCos[i]; @@ -441,7 +441,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) /* Find the nearest vertex */ #ifndef __APPLE__ -#pragma omp parallel for default(none) private(i) firstprivate(nearest) shared(calc,treeData) schedule(static) +#pragma omp parallel for default(none) private(i) firstprivate(nearest) shared(calc, treeData) schedule(static) #endif for (i = 0; i < calc->numVerts; ++i) { float *co = calc->vertexCos[i]; diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index fb0e22abf2a..23f7dd6ccfb 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -84,6 +84,7 @@ #include "BKE_pointcache.h" #include "BKE_scene.h" #include "BKE_smoke.h" +#include "BKE_texture.h" #include "RE_shader_ext.h" @@ -275,21 +276,21 @@ static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object * /* define grid resolutions from longest domain side */ if (size[0] >= MAX2(size[1], size[2])) { scale = res / size[0]; - sds->scale = size[0] / fabs(ob->size[0]); + sds->scale = size[0] / fabsf(ob->size[0]); sds->base_res[0] = res; sds->base_res[1] = (int)(size[1] * scale + 0.5f); sds->base_res[2] = (int)(size[2] * scale + 0.5f); } else if (size[1] >= MAX2(size[0], size[2])) { scale = res / size[1]; - sds->scale = size[1] / fabs(ob->size[1]); + sds->scale = size[1] / fabsf(ob->size[1]); sds->base_res[0] = (int)(size[0] * scale + 0.5f); sds->base_res[1] = res; sds->base_res[2] = (int)(size[2] * scale + 0.5f); } else { scale = res / size[2]; - sds->scale = size[2] / fabs(ob->size[2]); + sds->scale = size[2] / fabsf(ob->size[2]); sds->base_res[0] = (int)(size[0] * scale + 0.5f); sds->base_res[1] = (int)(size[1] * scale + 0.5f); sds->base_res[2] = res; @@ -1108,7 +1109,7 @@ static void em_freeData(EmissionMap *em) static void em_combineMaps(EmissionMap *output, EmissionMap *em2, int hires_multiplier, int additive, float sample_size) { - int i, x,y,z; + int i, x, y, z; /* copyfill input 1 struct and clear output for new allocation */ EmissionMap em1; @@ -1226,7 +1227,7 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke float solid = sfs->particle_size * 0.5f; float smooth = 0.5f; /* add 0.5 cells of linear falloff to reduce aliasing */ int hires_multiplier = 1; - int i,z; + int i, z; KDTree *tree; sim.scene = scene; @@ -1337,7 +1338,7 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke float hr = 1.0f / ((float)hires_multiplier); /* slightly adjust high res antialias smoothness based on number of divisions * to allow smaller details but yet not differing too much from the low res size */ - float hr_smooth = smooth * pow(hr, 1.0f/3.0f); + const float hr_smooth = smooth * powf(hr, 1.0f / 3.0f); /* setup loop bounds */ for (i = 0; i < 3; i++) { @@ -1418,27 +1419,6 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke } } -/* TODO(sergey): de-duplicate with get_texture_value from modifier utils */ -/* NOTE: Skips color management, because result is only used for value now, not for color. */ -static void get_texture_value(Tex *texture, float tex_co[3], TexResult *texres) -{ - int result_type; - - /* no node textures for now */ - result_type = multitex_ext_safe(texture, tex_co, texres, NULL, false); - - /* if the texture gave an RGB value, we assume it didn't give a valid - * intensity, since this is in the context of modifiers don't use perceptual color conversion. - * if the texture didn't give an RGB value, copy the intensity across - */ - if (result_type & TEX_RGB) { - texres->tin = (1.0f / 3.0f) * (texres->tr + texres->tg + texres->tb); - } - else { - copy_v3_fl(&texres->tr, texres->tin); - } -} - static void sample_derivedmesh(SmokeFlowSettings *sfs, MVert *mvert, MTFace *tface, MFace *mface, float *influence_map, float *velocity_map, int index, int base_res[3], float flow_center[3], BVHTreeFromMesh *treeData, float ray_start[3], float *vert_vel, int has_velocity, int defgrp_index, MDeformVert *dvert, float x, float y, float z) { @@ -1550,7 +1530,7 @@ static void sample_derivedmesh(SmokeFlowSettings *sfs, MVert *mvert, MTFace *tfa tex_co[2] = sfs->texture_offset; } texres.nor = NULL; - get_texture_value(sfs->noise_texture, tex_co, &texres); + BKE_texture_get_value(NULL, sfs->noise_texture, tex_co, &texres, false); sample_str *= texres.tin; } } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 9a38a5f87b8..900d92d1637 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -1817,6 +1817,64 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes) } } +static void ccgdm_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert) +{ + const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + int b; + + /* orco texture coordinates */ + if (attribs->totorco) { + /*const*/ float (*array)[3] = attribs->orco.array; + const float *orco = (array) ? array[index] : zero; + + if (attribs->orco.gl_texco) + glTexCoord3fv(orco); + else + glVertexAttrib3fvARB(attribs->orco.gl_index, orco); + } + + /* uv texture coordinates */ + for (b = 0; b < attribs->tottface; b++) { + const float *uv; + + if (attribs->tface[b].array) { + MTFace *tf = &attribs->tface[b].array[a]; + uv = tf->uv[vert]; + } + else { + uv = zero; + } + + if (attribs->tface[b].gl_texco) + glTexCoord2fv(uv); + else + glVertexAttrib2fvARB(attribs->tface[b].gl_index, uv); + } + + /* vertex colors */ + for (b = 0; b < attribs->totmcol; b++) { + GLubyte col[4]; + + if (attribs->mcol[b].array) { + MCol *cp = &attribs->mcol[b].array[a * 4 + vert]; + col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; + } + else { + col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0; + } + + glVertexAttrib4ubvARB(attribs->mcol[b].gl_index, col); + } + + /* tangent for normal mapping */ + if (attribs->tottang) { + /*const*/ float (*array)[4] = attribs->tang.array; + const float *tang = (array) ? array[a * 4 + vert] : zero; + + glVertexAttrib4fvARB(attribs->tang.gl_index, tang); + } +} + /* Only used by non-editmesh types */ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial, @@ -1833,7 +1891,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int gridFaces = gridSize - 1; int edgeSize = ccgSubSurf_getEdgeSize(ss); DMFlagMat *faceFlags = ccgdm->faceFlags; - int a, b, i, do_draw, numVerts, matnr, new_matnr, totface; + int a, i, do_draw, numVerts, matnr, new_matnr, totface; CCG_key_top_level(&key, ss); ccgdm_pbvh_update(ccgdm); @@ -1842,25 +1900,11 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, matnr = -1; #define PASSATTRIB(dx, dy, vert) { \ - if (attribs.totorco) { \ + if (attribs.totorco) \ index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize); \ - glVertexAttrib3fvARB(attribs.orco.gl_index, \ - attribs.orco.array[index]); \ - } \ - for (b = 0; b < attribs.tottface; b++) { \ - MTFace *tf = &attribs.tface[b].array[a]; \ - glVertexAttrib2fvARB(attribs.tface[b].gl_index, tf->uv[vert]); \ - } \ - for (b = 0; b < attribs.totmcol; b++) { \ - MCol *cp = &attribs.mcol[b].array[a * 4 + vert]; \ - GLubyte col[4]; \ - col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; \ - glVertexAttrib4ubvARB(attribs.mcol[b].gl_index, col); \ - } \ - if (attribs.tottang) { \ - float *tang = attribs.tang.array[a * 4 + vert]; \ - glVertexAttrib4fvARB(attribs.tang.gl_index, tang); \ - } \ + else \ + index = 0; \ + ccgdm_draw_attrib_vertex(&attribs, a, index, vert); \ } (void)0 totface = ccgSubSurf_getNumFaces(ss); @@ -1984,7 +2028,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, int gridFaces = gridSize - 1; int edgeSize = ccgSubSurf_getEdgeSize(ss); DMFlagMat *faceFlags = ccgdm->faceFlags; - int a, b, i, numVerts, matnr, new_matnr, totface; + int a, i, numVerts, matnr, new_matnr, totface; CCG_key_top_level(&key, ss); ccgdm_pbvh_update(ccgdm); @@ -1992,31 +2036,11 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, matnr = -1; #define PASSATTRIB(dx, dy, vert) { \ - if (attribs.totorco) { \ + if (attribs.totorco) \ index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize); \ - if (attribs.orco.gl_texco) \ - glTexCoord3fv(attribs.orco.array[index]); \ - else \ - glVertexAttrib3fvARB(attribs.orco.gl_index, \ - attribs.orco.array[index]); \ - } \ - for (b = 0; b < attribs.tottface; b++) { \ - MTFace *tf = &attribs.tface[b].array[a]; \ - if (attribs.tface[b].gl_texco) \ - glTexCoord2fv(tf->uv[vert]); \ - else \ - glVertexAttrib2fvARB(attribs.tface[b].gl_index, tf->uv[vert]); \ - } \ - for (b = 0; b < attribs.totmcol; b++) { \ - MCol *cp = &attribs.mcol[b].array[a * 4 + vert]; \ - GLubyte col[4]; \ - col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; \ - glVertexAttrib4ubvARB(attribs.mcol[b].gl_index, col); \ - } \ - if (attribs.tottang) { \ - float *tang = attribs.tang.array[a * 4 + vert]; \ - glVertexAttrib4fvARB(attribs.tang.gl_index, tang); \ - } \ + else \ + index = 0; \ + ccgdm_draw_attrib_vertex(&attribs, a, index, vert); \ } (void)0 totface = ccgSubSurf_getNumFaces(ss); @@ -3183,9 +3207,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, /* reuse of ccgDM_getNumTessFaces is intentional here: subsurf polys are just created from tessfaces */ ccgdm->dm.getNumPolys = ccgDM_getNumTessFaces; - ccgdm->dm.getNumGrids = ccgDM_getNumGrids; - ccgdm->dm.getPBVH = ccgDM_getPBVH; - ccgdm->dm.getVert = ccgDM_getFinalVert; ccgdm->dm.getEdge = ccgDM_getFinalEdge; ccgdm->dm.getTessFace = ccgDM_getFinalFace; diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 22b0fe7bc24..ccbccac85cf 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -68,6 +68,9 @@ #include "BKE_node.h" #include "BKE_animsys.h" #include "BKE_colortools.h" +#include "BKE_scene.h" + +#include "RE_shader_ext.h" /* ****************** Mapping ******************* */ @@ -1436,3 +1439,27 @@ bool BKE_texture_dependsOnTime(const struct Tex *texture) } /* ------------------------------------------------------------------------- */ + +void BKE_texture_get_value(Scene *scene, Tex *texture, float *tex_co, TexResult *texres, bool use_color_management) +{ + int result_type; + bool do_color_manage = false; + + if (scene && use_color_management) { + do_color_manage = BKE_scene_check_color_management_enabled(scene); + } + + /* no node textures for now */ + result_type = multitex_ext_safe(texture, tex_co, texres, NULL, do_color_manage); + + /* if the texture gave an RGB value, we assume it didn't give a valid + * intensity, since this is in the context of modifiers don't use perceptual color conversion. + * if the texture didn't give an RGB value, copy the intensity across + */ + if (result_type & TEX_RGB) { + texres->tin = (1.0f / 3.0f) * (texres->tr + texres->tg + texres->tb); + } + else { + copy_v3_fl(&texres->tr, texres->tin); + } +} diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index b8711f6e5f6..d519b93f963 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -36,6 +36,7 @@ #include "MEM_guardedalloc.h" +#include "DNA_anim_types.h" #include "DNA_gpencil_types.h" #include "DNA_camera_types.h" #include "DNA_movieclip_types.h" @@ -53,6 +54,7 @@ #include "BLF_translation.h" +#include "BKE_fcurve.h" #include "BKE_global.h" #include "BKE_tracking.h" #include "BKE_movieclip.h" @@ -62,6 +64,8 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" +#include "RNA_access.h" + #include "raskter.h" #include "libmv-capi.h" @@ -212,7 +216,6 @@ void BKE_tracking_settings_init(MovieTracking *tracking) tracking->settings.default_algorithm_flag |= TRACK_ALGORITHM_FLAG_USE_BRUTE; tracking->settings.dist = 1; tracking->settings.object_distance = 1; - tracking->settings.reconstruction_success_threshold = 1e-3f; tracking->stabilization.scaleinf = 1.0f; tracking->stabilization.locinf = 1.0f; @@ -591,6 +594,7 @@ MovieTrackingTrack *BKE_tracking_track_add(MovieTracking *tracking, ListBase *tr track->frames_limit = settings->default_frames_limit; track->flag = settings->default_flag; track->algorithm_flag = settings->default_algorithm_flag; + track->weight = 1.0f; memset(&marker, 0, sizeof(marker)); marker.pos[0] = x; @@ -3264,23 +3268,6 @@ static int point_markers_correspondences_on_both_image(MovieTrackingPlaneTrack * return correspondence_index; } -/* TODO(sergey): Make it generic function available for everyone. */ -BLI_INLINE void mat3f_from_mat3d(float mat_float[3][3], double mat_double[3][3]) -{ - /* Keep it stupid simple for better data flow in CPU. */ - mat_float[0][0] = mat_double[0][0]; - mat_float[0][1] = mat_double[0][1]; - mat_float[0][2] = mat_double[0][2]; - - mat_float[1][0] = mat_double[1][0]; - mat_float[1][1] = mat_double[1][1]; - mat_float[1][2] = mat_double[1][2]; - - mat_float[2][0] = mat_double[2][0]; - mat_float[2][1] = mat_double[2][1]; - mat_float[2][2] = mat_double[2][2]; -} - /* NOTE: frame number should be in clip space, not scene space */ static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_track, int start_frame, int direction, bool retrack) @@ -3342,7 +3329,7 @@ static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_trac libmv_homography2DFromCorrespondencesEuc(x1, x2, num_correspondences, H_double); - mat3f_from_mat3d(H, H_double); + copy_m3_m3d(H, H_double); for (i = 0; i < 4; i++) { float vec[3] = {0.0f, 0.0f, 1.0f}, vec2[3]; @@ -3446,7 +3433,7 @@ void BKE_tracking_homography_between_two_quads(/*const*/ float reference_corners libmv_homography2DFromCorrespondencesEuc(x1, x2, 4, H_double); - mat3f_from_mat3d(H, H_double); + copy_m3_m3d(H, H_double); } /*********************** Camera solving *************************/ @@ -3473,9 +3460,6 @@ typedef struct MovieReconstructContext { TracksMap *tracks_map; - float success_threshold; - bool use_fallback_reconstruction; - int sfra, efra; } MovieReconstructContext; @@ -3488,7 +3472,7 @@ typedef struct ReconstructProgressData { } ReconstructProgressData; /* Create new libmv Tracks structure from blender's tracks list. */ -static struct libmv_Tracks *libmv_tracks_new(ListBase *tracksbase, int width, int height) +static struct libmv_Tracks *libmv_tracks_new(MovieClip *clip, ListBase *tracksbase, int width, int height) { int tracknr = 0; MovieTrackingTrack *track; @@ -3496,15 +3480,28 @@ static struct libmv_Tracks *libmv_tracks_new(ListBase *tracksbase, int width, in track = tracksbase->first; while (track) { + FCurve *weight_fcurve; int a = 0; + weight_fcurve = id_data_find_fcurve(&clip->id, track, &RNA_MovieTrackingTrack, + "weight", 0, NULL); + for (a = 0; a < track->markersnr; a++) { MovieTrackingMarker *marker = &track->markers[a]; if ((marker->flag & MARKER_DISABLED) == 0) { + float weight = track->weight; + + if (weight_fcurve) { + int scene_framenr = + BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr); + weight = evaluate_fcurve(weight_fcurve, scene_framenr); + } + libmv_tracksInsert(tracks, marker->framenr, tracknr, (marker->pos[0] + track->offset[0]) * width, - (marker->pos[1] + track->offset[1]) * height); + (marker->pos[1] + track->offset[1]) * height, + weight); } } @@ -3751,9 +3748,10 @@ bool BKE_tracking_reconstruction_check(MovieTracking *tracking, MovieTrackingObj * clip datablock, so editing this clip is safe during * reconstruction job is in progress. */ -MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieTracking *tracking, MovieTrackingObject *object, +MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieClip *clip, MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height) { + MovieTracking *tracking = &clip->tracking; MovieReconstructContext *context = MEM_callocN(sizeof(MovieReconstructContext), "MovieReconstructContext data"); MovieTrackingCamera *camera = &tracking->camera; ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); @@ -3780,9 +3778,6 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieTracking * context->k2 = camera->k2; context->k3 = camera->k3; - context->success_threshold = tracking->settings.reconstruction_success_threshold; - context->use_fallback_reconstruction = tracking->settings.reconstruction_flag & TRACKING_USE_FALLBACK_RECONSTRUCTION; - context->tracks_map = tracks_map_new(context->object_name, context->is_camera, num_tracks, 0); track = tracksbase->first; @@ -3817,7 +3812,7 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieTracking * context->sfra = sfra; context->efra = efra; - context->tracks = libmv_tracks_new(tracksbase, width, height * aspy); + context->tracks = libmv_tracks_new(clip, tracksbase, width, height * aspy); context->keyframe1 = keyframe1; context->keyframe2 = keyframe2; context->refine_flags = reconstruct_refine_intrinsics_get_flags(tracking, object); @@ -3877,9 +3872,6 @@ static void reconstructionOptionsFromContext(libmv_ReconstructionOptions *recons reconstruction_options->keyframe2 = context->keyframe2; reconstruction_options->refine_intrinsics = context->refine_flags; - - reconstruction_options->success_threshold = context->success_threshold; - reconstruction_options->use_fallback_reconstruction = context->use_fallback_reconstruction; } /* Solve camera/object motion and reconstruct 3D markers position diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index a69df62f505..64470542844 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -95,11 +95,6 @@ typedef struct bUnitDef { #define B_UNIT_DEF_SUPPRESS 1 /* Use for units that are not used enough to be translated into for common use */ #define B_UNIT_DEF_TENTH 2 /* Display a unit even if its value is 0.1, eg 0.1mm instead of 100um */ -/* workaround encoding issue with "µm", bug [#36090] */ -#define B_UNIT_CHAR_MICRO "\xb5" -#define UM B_UNIT_CHAR_MICRO"m" -#define US B_UNIT_CHAR_MICRO"s" - /* define a single unit */ typedef struct bUnitCollection { struct bUnitDef *units; @@ -121,7 +116,7 @@ static struct bUnitDef buMetricLenDef[] = { {"decimeter", "decimeters", "dm", NULL, "10 Centimeters", UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS}, {"centimeter", "centimeters", "cm", NULL, "Centimeters", UN_SC_CM, 0.0, B_UNIT_DEF_NONE}, {"millimeter", "millimeters", "mm", NULL, "Millimeters", UN_SC_MM, 0.0, B_UNIT_DEF_NONE | B_UNIT_DEF_TENTH}, - {"micrometer", "micrometers", UM, "um", "Micrometers", UN_SC_UM, 0.0, B_UNIT_DEF_NONE}, // micron too? + {"micrometer", "micrometers", "µm", "um", "Micrometers", UN_SC_UM, 0.0, B_UNIT_DEF_NONE}, /* These get displayed because of float precision problems in the transform header, * could work around, but for now probably people wont use these */ @@ -154,7 +149,7 @@ static struct bUnitDef buMetricAreaDef[] = { {"square decimeter", "square decimetees", "dm²", "dm2", "Square Decimeters", UN_SC_DM * UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS}, {"square centimeter", "square centimeters", "cm²", "cm2", "Square Centimeters", UN_SC_CM * UN_SC_CM, 0.0, B_UNIT_DEF_NONE}, {"square millimeter", "square millimeters", "mm²", "mm2", "Square Millimeters", UN_SC_MM * UN_SC_MM, 0.0, B_UNIT_DEF_NONE | B_UNIT_DEF_TENTH}, - {"square micrometer", "square micrometers", UM"²", "um2", "Square Micrometers", UN_SC_UM * UN_SC_UM, 0.0, B_UNIT_DEF_NONE}, + {"square micrometer", "square micrometers", "µm²", "um2", "Square Micrometers", UN_SC_UM * UN_SC_UM, 0.0, B_UNIT_DEF_NONE}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; static struct bUnitCollection buMetricAreaCollection = {buMetricAreaDef, 3, 0, sizeof(buMetricAreaDef) / sizeof(bUnitDef)}; @@ -180,7 +175,7 @@ static struct bUnitDef buMetricVolDef[] = { {"cubic decimeter", "cubic decimeters", "dm³", "dm3", "Cubic Decimeters", UN_SC_DM * UN_SC_DM * UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS}, {"cubic centimeter", "cubic centimeters", "cm³", "cm3", "Cubic Centimeters", UN_SC_CM * UN_SC_CM * UN_SC_CM, 0.0, B_UNIT_DEF_NONE}, {"cubic millimeter", "cubic millimeters", "mm³", "mm3", "Cubic Millimeters", UN_SC_MM * UN_SC_MM * UN_SC_MM, 0.0, B_UNIT_DEF_NONE | B_UNIT_DEF_TENTH}, - {"cubic micrometer", "cubic micrometers", UM"³", "um3", "Cubic Micrometers", UN_SC_UM * UN_SC_UM * UN_SC_UM, 0.0, B_UNIT_DEF_NONE}, + {"cubic micrometer", "cubic micrometers", "µm³", "um3", "Cubic Micrometers", UN_SC_UM * UN_SC_UM * UN_SC_UM, 0.0, B_UNIT_DEF_NONE}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; static struct bUnitCollection buMetricVolCollection = {buMetricVolDef, 3, 0, sizeof(buMetricVolDef) / sizeof(bUnitDef)}; @@ -258,7 +253,7 @@ static struct bUnitDef buNaturalTimeDef[] = { {"minute", "minutes", "min", "m", "Minutes", 60.0, 0.0, B_UNIT_DEF_NONE}, {"second", "seconds", "sec", "s", "Seconds", 1.0, 0.0, B_UNIT_DEF_NONE}, /* base unit */ {"millisecond", "milliseconds", "ms", NULL, "Milliseconds", 0.001, 0.0, B_UNIT_DEF_NONE}, - {"microsecond", "microseconds", US, "us", "Microseconds", 0.000001, 0.0, B_UNIT_DEF_NONE}, + {"microsecond", "microseconds", "µs", "us", "Microseconds", 0.000001, 0.0, B_UNIT_DEF_NONE}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; static struct bUnitCollection buNaturalTimeCollection = {buNaturalTimeDef, 3, 0, sizeof(buNaturalTimeDef) / sizeof(bUnitDef)}; @@ -278,7 +273,7 @@ static struct bUnitDef buCameraLenDef[] = { {"decimeter", "decimeters", "dm", NULL, "10 Centimeters", UN_SC_HM, 0.0, B_UNIT_DEF_SUPPRESS}, {"centimeter", "centimeters", "cm", NULL, "Centimeters", UN_SC_DAM, 0.0, B_UNIT_DEF_SUPPRESS}, {"millimeter", "millimeters", "mm", NULL, "Millimeters", UN_SC_M, 0.0, B_UNIT_DEF_NONE}, - {"micrometer", "micrometers", UM, "um", "Micrometers", UN_SC_MM, 0.0, B_UNIT_DEF_SUPPRESS}, // micron too? + {"micrometer", "micrometers", "µm", "um", "Micrometers", UN_SC_MM, 0.0, B_UNIT_DEF_SUPPRESS}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; static struct bUnitCollection buCameraLenCollection = {buCameraLenDef, 3, 0, sizeof(buCameraLenDef) / sizeof(bUnitDef)}; @@ -614,9 +609,10 @@ int bUnit_ReplaceString(char *str, int len_max, const char *str_prev, double sca int i; char *ch = str; - for (i = 0; (i >= len_max || *ch == '\0'); i++, ch++) + for (i = 0; (i < len_max) && (*ch != '\0'); i++, ch++) { if ((*ch >= 'A') && (*ch <= 'Z')) *ch += ('a' - 'A'); + } } for (unit = usys->units; unit->name; unit++) { diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 206f829eaa8..c5a932e4173 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -92,8 +92,6 @@ World *add_world(Main *bmain, const char *name) wrld->zeng = 0.01f; wrld->zenb = 0.01f; wrld->skytype = 0; - wrld->stardist = 15.0f; - wrld->starsize = 2.0f; wrld->exp = 0.0f; wrld->exposure = wrld->range = 1.0f; diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index 538c98cc899..bcf5e712eff 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -295,17 +295,7 @@ static const char **get_file_extensions(int format) } case FFMPEG_OGG: { - static const char *rv[] = { ".ogg", ".ogv", NULL }; - return rv; - } - case FFMPEG_MP3: - { - static const char *rv[] = { ".mp3", NULL }; - return rv; - } - case FFMPEG_WAV: - { - static const char *rv[] = { ".wav", NULL }; + static const char *rv[] = { ".ogv", ".ogg", NULL }; return rv; } default: @@ -875,12 +865,6 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report case FFMPEG_FLV: fmt->video_codec = CODEC_ID_FLV1; break; - case FFMPEG_MP3: - fmt->audio_codec = CODEC_ID_MP3; - /* fall-through */ - case FFMPEG_WAV: - fmt->video_codec = CODEC_ID_NONE; - break; case FFMPEG_MPEG4: default: fmt->video_codec = CODEC_ID_MPEG4; @@ -1254,9 +1238,7 @@ void BKE_ffmpeg_property_del(RenderData *rd, void *type, void *prop_) group = IDP_GetPropertyFromGroup(rd->ffcodecdata.properties, type); if (group && prop) { - IDP_RemFromGroup(group, prop); - IDP_FreeProperty(prop); - MEM_freeN(prop); + IDP_FreeFromGroup(group, prop); } } diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index b04af44156f..c83494790a8 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -60,6 +60,9 @@ void copy_m4_m4(float R[4][4], float A[4][4]); void copy_m3_m4(float R[3][3], float A[4][4]); void copy_m4_m3(float R[4][4], float A[3][3]); +/* double->float */ +void copy_m3_m3d(float R[3][3], double A[3][3]); + void swap_m3m3(float A[3][3], float B[3][3]); void swap_m4m4(float A[4][4], float B[4][4]); @@ -160,6 +163,8 @@ void svd_m4(float U[4][4], float s[4], float V[4][4], float A[4][4]); void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon); void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon); +bool has_zero_axis_m4(float matrix[4][4]); + /****************************** Transformations ******************************/ void scale_m3_fl(float R[3][3], float scale); diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 675ba88fc72..3ff81e478c9 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -82,6 +82,9 @@ MINLINE void copy_v4fl_v4db(float r[4], const double a[4]); MINLINE void copy_v2db_v2fl(double r[2], const float a[2]); MINLINE void copy_v3db_v3fl(double r[3], const float a[3]); MINLINE void copy_v4db_v4fl(double r[4], const float a[4]); +/* float args -> vec */ +MINLINE void copy_v3_fl3(float v[3], float x, float y, float z); +MINLINE void copy_v4_fl4(float v[4], float x, float y, float z, float w); /********************************* Arithmetic ********************************/ @@ -117,6 +120,9 @@ MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3]) ATTR_WA MINLINE float dot_m3_v3_row_x(float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT; MINLINE float dot_m3_v3_row_y(float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT; MINLINE float dot_m3_v3_row_z(float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT; +MINLINE float dot_m4_v3_row_x(float M[4][4], const float a[3]) ATTR_WARN_UNUSED_RESULT; +MINLINE float dot_m4_v3_row_y(float M[4][4], const float a[3]) ATTR_WARN_UNUSED_RESULT; +MINLINE float dot_m4_v3_row_z(float M[4][4], const float a[3]) ATTR_WARN_UNUSED_RESULT; MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f); MINLINE void madd_v3_v3v3(float r[3], const float a[3], const float b[3]); diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h index f8b9088fe3d..0fee9264191 100644 --- a/source/blender/blenlib/BLI_rect.h +++ b/source/blender/blenlib/BLI_rect.h @@ -74,6 +74,8 @@ bool BLI_rctf_isect_pt(const struct rctf *rect, const float x, const float y); bool BLI_rctf_isect_pt_v(const struct rctf *rect, const float xy[2]); bool BLI_rcti_isect_segment(const struct rcti *rect, const int s1[2], const int s2[2]); bool BLI_rctf_isect_segment(const struct rctf *rect, const float s1[2], const float s2[2]); +bool BLI_rcti_isect_circle(const struct rcti *rect, const float xy[2], const float radius); +bool BLI_rctf_isect_circle(const struct rctf *rect, const float xy[2], const float radius); bool BLI_rcti_inside_rcti(rcti *rct_a, const rcti *rct_b); bool BLI_rctf_inside_rctf(rctf *rct_a, const rctf *rct_b); void BLI_rcti_union(struct rcti *rcti1, const struct rcti *rcti2); diff --git a/source/blender/blenlib/BLI_sys_types.h b/source/blender/blenlib/BLI_sys_types.h index e544006fd69..0b7f07e3d36 100644 --- a/source/blender/blenlib/BLI_sys_types.h +++ b/source/blender/blenlib/BLI_sys_types.h @@ -116,7 +116,7 @@ typedef uint64_t u_int64_t; * use (bool, true / false) instead */ #ifdef HAVE_STDBOOL_H # include <stdbool.h> -#else +#elif !defined(__bool_true_false_are_defined) && !defined(__BOOL_DEFINED) # ifndef HAVE__BOOL # ifdef __cplusplus typedef bool _BLI_Bool; diff --git a/source/blender/blenlib/BLI_task.h b/source/blender/blenlib/BLI_task.h index f57d42858c7..c9cbaf997fb 100644 --- a/source/blender/blenlib/BLI_task.h +++ b/source/blender/blenlib/BLI_task.h @@ -88,8 +88,8 @@ void BLI_task_pool_cancel(TaskPool *pool); /* stop all worker threads */ void BLI_task_pool_stop(TaskPool *pool); -/* for worker threads, test if cancelled */ -bool BLI_task_pool_cancelled(TaskPool *pool); +/* for worker threads, test if canceled */ +bool BLI_task_pool_canceled(TaskPool *pool); /* optional userdata pointer to pass along to run function */ void *BLI_task_pool_userdata(TaskPool *pool); diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index c3a3c035ed3..9bf720c03ea 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -240,8 +240,13 @@ #define CLAMPIS(a, b, c) ((a) < (b) ? (b) : (a) > (c) ? (c) : (a)) -#define IS_EQ(a, b) ((fabs((double)(a) - (b)) >= (double) FLT_EPSILON) ? 0 : 1) -#define IS_EQF(a, b) ((fabsf((float)(a) - (b)) >= (float) FLT_EPSILON) ? 0 : 1) +#define IS_EQ(a, b) ( \ + CHECK_TYPE_INLINE(a, double), CHECK_TYPE_INLINE(b, double), \ + ((fabs((double)(a) - (b)) >= (double) FLT_EPSILON) ? false : true)) + +#define IS_EQF(a, b) ( \ + CHECK_TYPE_INLINE(a, float), CHECK_TYPE_INLINE(b, float), \ + ((fabsf((float)(a) - (b)) >= (float) FLT_EPSILON) ? false : true)) #define IS_EQT(a, b, c) ((a > b) ? (((a - b) <= c) ? 1 : 0) : ((((b - a) <= c) ? 1 : 0))) #define IN_RANGE(a, b, c) ((b < c) ? ((b < a && a < c) ? 1 : 0) : ((c < a && a < b) ? 1 : 0)) diff --git a/source/blender/blenlib/BLI_voronoi.h b/source/blender/blenlib/BLI_voronoi.h index 68d7398d89b..9d32061bf97 100644 --- a/source/blender/blenlib/BLI_voronoi.h +++ b/source/blender/blenlib/BLI_voronoi.h @@ -52,7 +52,7 @@ typedef struct VoronoiEdge { float f, g; /* directional coeffitients satisfying equation y = f * x + g (edge lies on this line) */ /* some edges consist of two parts, so we add the pointer to another part to connect them at the end of an algorithm */ - struct VoronoiEdge *neighbour; + struct VoronoiEdge *neighbor; } VoronoiEdge; typedef struct VoronoiTriangulationPoint { diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index fcca6cd59ba..f3ebddddc8c 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -136,7 +136,7 @@ BLI_INLINE void ghash_resize_buckets(GHash *gh, const unsigned int nbuckets) } /** - * Increase initial bucket size to match a reserved ammount. + * Increase initial bucket size to match a reserved amount. */ BLI_INLINE void ghash_buckets_reserve(GHash *gh, const unsigned int nentries_reserve) { diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c index 261e53f0f55..28539d9ca34 100644 --- a/source/blender/blenlib/intern/BLI_mempool.c +++ b/source/blender/blenlib/intern/BLI_mempool.c @@ -584,7 +584,7 @@ void BLI_mempool_clear_ex(BLI_mempool *pool, const int totelem_reserve) /* free all after pool->maxchunks */ - for (mpchunk = BLI_findlink(&pool->chunks, (int)maxchunks); mpchunk; mpchunk = mpchunk_next) { + for (mpchunk = BLI_findlink(&pool->chunks, (int)maxchunks); mpchunk; mpchunk = mpchunk_next) { mpchunk_next = mpchunk->next; BLI_remlink(&pool->chunks, mpchunk); mempool_chunk_free(mpchunk, pool->flag); diff --git a/source/blender/blenlib/intern/convexhull2d.c b/source/blender/blenlib/intern/convexhull2d.c index 5669a302bd8..2c29ef042a1 100644 --- a/source/blender/blenlib/intern/convexhull2d.c +++ b/source/blender/blenlib/intern/convexhull2d.c @@ -191,6 +191,8 @@ static int pointref_cmp_y(const void *a_, const void *b_) * \param points An array of 2D points. * \param n The number of points in points. * \param r_points An array of the convex hull vertex indices (max is n). + * _must_ be allocated as ``n * 2`` becauise of how its used internally, + * even though the final result will be no more then \a n in size. * \returns the number of points in r_points. */ int BLI_convexhull_2d(const float (*points)[2], const int n, int r_points[]) @@ -310,7 +312,7 @@ float BLI_convexhull_aabb_fit_points_2d(const float (*points)[2], unsigned int n float angle; - index_map = MEM_mallocN(sizeof(*index_map) * n, __func__); + index_map = MEM_mallocN(sizeof(*index_map) * n * 2, __func__); tot = BLI_convexhull_2d((const float (*)[2])points, (int)n, index_map); diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c index b26e007b3e6..50dcd01207d 100644 --- a/source/blender/blenlib/intern/edgehash.c +++ b/source/blender/blenlib/intern/edgehash.c @@ -137,7 +137,7 @@ BLI_INLINE void edgehash_resize_buckets(EdgeHash *eh, const unsigned int nbucket } /** - * Increase initial bucket size to match a reserved ammount. + * Increase initial bucket size to match a reserved amount. */ BLI_INLINE void edgehash_buckets_reserve(EdgeHash *eh, const unsigned int nentries_reserve) { diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index d24200fc0b7..1f52caac8e9 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -112,6 +112,22 @@ void copy_m4_m3(float m1[4][4], float m2[3][3]) /* no clear */ } +void copy_m3_m3d(float R[3][3], double A[3][3]) +{ + /* Keep it stupid simple for better data flow in CPU. */ + R[0][0] = A[0][0]; + R[0][1] = A[0][1]; + R[0][2] = A[0][2]; + + R[1][0] = A[1][0]; + R[1][1] = A[1][1]; + R[1][2] = A[1][2]; + + R[2][0] = A[2][0]; + R[2][1] = A[2][1]; + R[2][2] = A[2][2]; +} + void swap_m3m3(float m1[3][3], float m2[3][3]) { float t; @@ -2070,3 +2086,9 @@ void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon) } } +bool has_zero_axis_m4(float matrix[4][4]) +{ + return len_squared_v3(matrix[0]) < FLT_EPSILON || + len_squared_v3(matrix[1]) < FLT_EPSILON || + len_squared_v3(matrix[2]) < FLT_EPSILON; +} diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index 2eebe10dd58..41535cf32b6 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -1712,7 +1712,7 @@ float fov_to_focallength(float hfov, float sensor) return (sensor / 2.0f) / tanf(hfov * 0.5f); } -/* 'mod_inline(-3,4)= 1', 'fmod(-3,4)= -3' */ +/* 'mod_inline(-3, 4)= 1', 'fmod(-3, 4)= -3' */ static float mod_inline(float a, float b) { return a - (b * floorf(a / b)); diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index ce5d9657c7f..ace8e6b48c1 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -235,6 +235,22 @@ MINLINE void swap_v4_v4(float a[4], float b[4]) SWAP(float, a[3], b[3]); } +/* float args -> vec */ +MINLINE void copy_v3_fl3(float v[3], float x, float y, float z) +{ + v[0] = x; + v[1] = y; + v[2] = z; +} + +MINLINE void copy_v4_fl4(float v[4], float x, float y, float z, float w) +{ + v[0] = x; + v[1] = y; + v[2] = z; + v[3] = w; +} + /********************************* Arithmetic ********************************/ MINLINE void add_v2_fl(float r[2], float f) @@ -434,6 +450,22 @@ MINLINE float dot_m3_v3_row_z(float M[3][3], const float a[3]) return M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2]; } +/** + * Almost like mul_m4_v3(), misses adding translation. + */ +MINLINE float dot_m4_v3_row_x(float M[4][4], const float a[3]) +{ + return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2]; +} +MINLINE float dot_m4_v3_row_y(float M[4][4], const float a[3]) +{ + return M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2]; +} +MINLINE float dot_m4_v3_row_z(float M[4][4], const float a[3]) +{ + return M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2]; +} + MINLINE void madd_v2_v2fl(float r[2], const float a[2], float f) { r[0] += a[0] * f; diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index 02525e25dda..d36cd3cb394 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -216,6 +216,32 @@ bool BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[ } } +bool BLI_rcti_isect_circle(const rcti *rect, const float xy[2], const float radius) +{ + float dx, dy; + + if (xy[0] >= rect->xmin && xy[0] <= rect->xmax) dx = 0; + else dx = (xy[0] < rect->xmin) ? (rect->xmin - xy[0]) : (xy[0] - rect->xmax); + + if (xy[1] >= rect->ymin && xy[1] <= rect->ymax) dy = 0; + else dy = (xy[1] < rect->ymin) ? (rect->ymin - xy[1]) : (xy[1] - rect->ymax); + + return dx * dx + dy * dy <= radius * radius; +} + +bool BLI_rctf_isect_circle(const rctf *rect, const float xy[2], const float radius) +{ + float dx, dy; + + if (xy[0] >= rect->xmin && xy[0] <= rect->xmax) dx = 0; + else dx = (xy[0] < rect->xmin) ? (rect->xmin - xy[0]) : (xy[0] - rect->xmax); + + if (xy[1] >= rect->ymin && xy[1] <= rect->ymax) dy = 0; + else dy = (xy[1] < rect->ymin) ? (rect->ymin - xy[1]) : (xy[1] - rect->ymax); + + return dx * dx + dy * dy <= radius * radius; +} + void BLI_rctf_union(rctf *rct1, const rctf *rct2) { if (rct1->xmin > rct2->xmin) rct1->xmin = rct2->xmin; diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c index 7fa108b906f..4ae60abb2c8 100644 --- a/source/blender/blenlib/intern/task.c +++ b/source/blender/blenlib/intern/task.c @@ -402,7 +402,7 @@ void BLI_task_pool_stop(TaskPool *pool) BLI_assert(pool->num == 0); } -bool BLI_task_pool_cancelled(TaskPool *pool) +bool BLI_task_pool_canceled(TaskPool *pool) { return pool->do_cancel; } diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c index 64682965649..0b8f5dfdde5 100644 --- a/source/blender/blenlib/intern/threads.c +++ b/source/blender/blenlib/intern/threads.c @@ -166,7 +166,7 @@ TaskScheduler *BLI_task_scheduler_get(void) if (task_scheduler == NULL) { int tot_thread = BLI_system_thread_count(); - /* Do a lazy initialization, so it happes after + /* Do a lazy initialization, so it happens after * command line arguments parsing */ task_scheduler = BLI_task_scheduler_create(tot_thread); @@ -624,7 +624,7 @@ struct ThreadQueue { pthread_cond_t push_cond; pthread_cond_t finish_cond; volatile int nowait; - volatile int cancelled; + volatile int canceled; }; ThreadQueue *BLI_thread_queue_init(void) diff --git a/source/blender/blenlib/intern/voronoi.c b/source/blender/blenlib/intern/voronoi.c index 3f6adff1eda..731536ff0df 100644 --- a/source/blender/blenlib/intern/voronoi.c +++ b/source/blender/blenlib/intern/voronoi.c @@ -99,7 +99,7 @@ static VoronoiEdge *voronoiEdge_new(float start[2], float left[2], float right[2 copy_v2_v2(edge->left, left); copy_v2_v2(edge->right, right); - edge->neighbour = NULL; + edge->neighbor = NULL; edge->end[0] = 0; edge->end[1] = 0; @@ -395,7 +395,7 @@ static void voronoi_addParabola(VoronoiProcess *process, float site[2]) el = voronoiEdge_new(start, par->site, site); er = voronoiEdge_new(start, site, par->site); - el->neighbour = er; + el->neighbor = er; BLI_addtail(&process->edges, el); par->edge = er; @@ -682,9 +682,9 @@ void BLI_voronoi_compute(const VoronoiSite *sites, int sites_total, int width, i edge = process.edges.first; while (edge) { - if (edge->neighbour) { - copy_v2_v2(edge->start, edge->neighbour->end); - MEM_freeN(edge->neighbour); + if (edge->neighbor) { + copy_v2_v2(edge->start, edge->neighbor->end); + MEM_freeN(edge->neighbor); } edge = edge->next; diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt index f865962bac9..24b8df78258 100644 --- a/source/blender/blenloader/CMakeLists.txt +++ b/source/blender/blenloader/CMakeLists.txt @@ -66,4 +66,8 @@ if(WITH_INTERNATIONAL) add_definitions(-DWITH_INTERNATIONAL) endif() +if(WITH_CODEC_FFMPEG) + add_definitions(-DWITH_FFMPEG) +endif() + blender_add_lib(bf_blenloader "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/blenloader/SConscript b/source/blender/blenloader/SConscript index 3882cc1029a..bd002e59fa4 100644 --- a/source/blender/blenloader/SConscript +++ b/source/blender/blenloader/SConscript @@ -51,6 +51,9 @@ defs = [] if env['WITH_BF_INTERNATIONAL']: defs.append('WITH_INTERNATIONAL') +if env['WITH_BF_FFMPEG']: + defs.append('WITH_FFMPEG') + if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): env.BlenderLib('bf_blenloader', sources, incs, defs, libtype=['core', 'player'], priority = [167, 30]) #, cc_compileflags=['/WX']) else: diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 40d442f4e0b..2ad2ff1d7b0 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -40,6 +40,7 @@ #include <string.h> // for strrchr strncmp strstr #include <math.h> // for fabs #include <stdarg.h> /* for va_start/end */ +#include <time.h> /* for gmtime */ #include "BLI_utildefines.h" #ifndef WIN32 @@ -153,6 +154,7 @@ #include "BKE_tracking.h" #include "BKE_treehash.h" #include "BKE_sound.h" +#include "BKE_writeffmpeg.h" #include "IMB_imbuf.h" // for proxy / timecode versioning stuff @@ -3359,6 +3361,8 @@ static void lib_link_curve(FileData *fd, Main *main) cu->ipo = newlibadr_us(fd, cu->id.lib, cu->ipo); // XXX deprecated - old animation system cu->key = newlibadr_us(fd, cu->id.lib, cu->key); + + cu->selboxes = NULL; /* runtime, clear */ cu->id.flag -= LIB_NEED_LINK; } @@ -3700,7 +3704,7 @@ static void lib_link_particlesettings(FileData *fd, Main *main) /* if we have indexes, let's use them */ for (dw = part->dupliweights.first; dw; dw = dw->next) { GroupObject *go = (GroupObject *)BLI_findlink(&part->dup_group->gobject, dw->index); - dw->ob = go ? newlibadr(fd, part->id.lib, dw->ob) : NULL; + dw->ob = go ? go->ob : NULL; } } else { @@ -3806,7 +3810,7 @@ static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase for (; pt; pt=pt->next) pt->ob=newlibadr(fd, id->lib, pt->ob); - psys->parent = newlibadr_us(fd, id->lib, psys->parent); + psys->parent = newlibadr(fd, id->lib, psys->parent); psys->target_ob = newlibadr(fd, id->lib, psys->target_ob); if (psys->clmd) { @@ -3815,6 +3819,7 @@ static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase psys->clmd->point_cache = psys->pointcache; psys->clmd->ptcaches.first = psys->clmd->ptcaches.last= NULL; psys->clmd->coll_parms->group = newlibadr(fd, id->lib, psys->clmd->coll_parms->group); + psys->clmd->modifier.error = NULL; } } else { @@ -5937,6 +5942,14 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc /* not very nice, but could help */ if ((v3d->layact & v3d->lay) == 0) v3d->layact = v3d->lay; + /* its possible the current transform orientation has been removed */ + if (v3d->twmode >= V3D_MANIP_CUSTOM) { + const int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); + if (!BLI_findlink(&sc->scene->transform_spaces, selected_index)) { + v3d->twmode = V3D_MANIP_GLOBAL; + } + } + /* free render engines for now */ for (ar = sa->regionbase.first; ar; ar = ar->next) { RegionView3D *rv3d= ar->regiondata; @@ -7297,7 +7310,8 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead) bfd->main->subversionfile = fg->subversion; bfd->main->minversionfile = fg->minversion; bfd->main->minsubversionfile = fg->minsubversion; - bfd->main->revision = fg->revision; + bfd->main->build_commit_timestamp = fg->build_commit_timestamp; + BLI_strncpy(bfd->main->build_hash, fg->build_hash, sizeof(bfd->main->build_hash)); bfd->winpos = fg->winpos; bfd->fileflags = fg->fileflags; @@ -7931,8 +7945,21 @@ static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ - if (G.debug & G_DEBUG) - printf("read file %s\n Version %d sub %d svn r%d\n", fd->relabase, main->versionfile, main->subversionfile, main->revision); + if (G.debug & G_DEBUG) { + char build_commit_datetime[32]; + time_t temp_time = main->build_commit_timestamp; + struct tm *tm = gmtime(&temp_time); + if (LIKELY(tm)) { + strftime(build_commit_datetime, sizeof(build_commit_datetime), "%Y-%m-%d %H:%M", tm); + } + else { + BLI_strncpy(build_commit_datetime, "date-unknown", sizeof(build_commit_datetime)); + } + + printf("read file %s\n Version %d sub %d date %s hash %s\n", + fd->relabase, main->versionfile, main->subversionfile, + build_commit_datetime, main->build_hash); + } blo_do_versions_pre250(fd, lib, main); blo_do_versions_250(fd, lib, main); @@ -9095,17 +9122,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } } - - /* fallbck resection method settings */ - { - MovieClip *clip; - - for (clip = main->movieclip.first; clip; clip = clip->id.next) { - if (clip->tracking.settings.reconstruction_success_threshold == 0.0f) { - clip->tracking.settings.reconstruction_success_threshold = 1e-3f; - } - } - } } if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 7)) { @@ -9713,7 +9729,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } } - + if (!MAIN_VERSION_ATLEAST(main, 269, 1)) { /* Removal of Cycles SSS Compatible falloff */ FOREACH_NODETREE(main, ntree, id) { @@ -9730,6 +9746,120 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } FOREACH_NODETREE_END } + if (!MAIN_VERSION_ATLEAST(main, 269, 2)) { + /* Initialize CDL settings for Color Balance nodes */ + FOREACH_NODETREE(main, ntree, id) { + if (ntree->type == NTREE_COMPOSIT) { + bNode *node; + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_COLORBALANCE) { + NodeColorBalance *n = node->storage; + if (node->custom1 == 0) { + /* LGG mode stays the same, just init CDL settings */ + ntreeCompositColorBalanceSyncFromLGG(ntree, node); + } + else if (node->custom1 == 1) { + /* CDL previously used same variables as LGG, copy them over + * and then sync LGG for comparable results in both modes. + */ + copy_v3_v3(n->offset, n->lift); + copy_v3_v3(n->power, n->gamma); + copy_v3_v3(n->slope, n->gain); + ntreeCompositColorBalanceSyncFromCDL(ntree, node); + } + } + } + } + } FOREACH_NODETREE_END + } + + { + bScreen *sc; + ScrArea *sa; + SpaceLink *sl; + Scene *scene; + + /* Update files using invalid (outdated) outlinevis Outliner values. */ + for (sc = main->screen.first; sc; sc = sc->id.next) { + for (sa = sc->areabase.first; sa; sa = sa->next) { + for (sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_OUTLINER) { + SpaceOops *so = (SpaceOops *)sl; + + if (!ELEM11(so->outlinevis, SO_ALL_SCENES, SO_CUR_SCENE, SO_VISIBLE, SO_SELECTED, SO_ACTIVE, + SO_SAME_TYPE, SO_GROUPS, SO_LIBRARIES, SO_SEQUENCE, SO_DATABLOCKS, + SO_USERDEF)) + { + so->outlinevis = SO_ALL_SCENES; + } + } + } + } + } + + if (!DNA_struct_elem_find(fd->filesdna, "MovieTrackingTrack", "float", "weight")) { + MovieClip *clip; + for (clip = main->movieclip.first; clip; clip = clip->id.next) { + MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *tracking_object; + for (tracking_object = tracking->objects.first; + tracking_object; + tracking_object = tracking_object->next) + { + ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object); + MovieTrackingTrack *track; + for (track = tracksbase->first; + track; + track = track->next) + { + track->weight = 1.0f; + } + } + } + } + + if (!DNA_struct_elem_find(fd->filesdna, "TriangulateModifierData", "int", "quad_method")) { + Object *ob; + for (ob = main->object.first; ob; ob = ob->id.next) { + ModifierData *md; + for (md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Triangulate) { + TriangulateModifierData *tmd = (TriangulateModifierData *)md; + if ((tmd->flag & MOD_TRIANGULATE_BEAUTY)) { + tmd->quad_method = MOD_TRIANGULATE_QUAD_BEAUTY; + tmd->ngon_method = MOD_TRIANGULATE_NGON_BEAUTY; + } + else { + tmd->quad_method = MOD_TRIANGULATE_QUAD_FIXED; + tmd->ngon_method = MOD_TRIANGULATE_NGON_SCANFILL; + } + } + } + } + } + + for (scene = main->scene.first; scene; scene = scene->id.next) { + if (scene->gm.matmode == GAME_MAT_TEXFACE) { + scene->gm.matmode = GAME_MAT_MULTITEX; + } + } + + /* 'Increment' mode disabled for nodes, use true grid snapping instead */ + for (scene = main->scene.first; scene; scene = scene->id.next) { + if (scene->toolsettings->snap_node_mode == SCE_SNAP_MODE_INCREMENT) + scene->toolsettings->snap_node_mode = SCE_SNAP_MODE_GRID; + } + + /* Update for removed "sound-only" option in FFMPEG export settings. */ +#ifdef WITH_FFMPEG + for (scene = main->scene.first; scene; scene = scene->id.next) { + if (scene->r.ffcodecdata.type >= FFMPEG_INVALID) { + scene->r.ffcodecdata.type = FFMPEG_AVI; + } + } +#endif + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */ diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index 80e34f0fce4..62e3955ca60 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -2323,7 +2323,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) KeyBlock *kb; for (kb = key->block.first; kb; kb = kb->next) { - if (IS_EQF(kb->slidermin, kb->slidermax) && IS_EQ(kb->slidermax, 0)) + if (IS_EQF(kb->slidermin, kb->slidermax) && IS_EQF(kb->slidermax, 0.0f)) kb->slidermax = kb->slidermin + 1.0f; } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 44dc98fe537..dad8a60289e 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2904,9 +2904,6 @@ static void write_brushes(WriteData *wd, ListBase *idbase) writestruct(wd, ID_BR, "Brush", 1, brush); if (brush->id.properties) IDP_WriteProperty(brush->id.properties, wd); - writestruct(wd, DATA, "MTex", 1, &brush->mtex); - writestruct(wd, DATA, "MTex", 1, &brush->mask_mtex); - if (brush->curve) write_curvemapping(wd, brush->curve); } @@ -3265,7 +3262,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) char subvstr[8]; /* prevent mem checkers from complaining */ - fg.pads= fg.pad= 0; + fg.pads= 0; memset(fg.filename, 0, sizeof(fg.filename)); current_screen_compat(mainvar, &screen); @@ -3289,11 +3286,15 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) fg.minsubversion= BLENDER_MINSUBVERSION; #ifdef WITH_BUILDINFO { - extern char build_rev[]; - fg.revision= atoi(build_rev); + extern unsigned long build_commit_timestamp; + extern char build_hash[]; + /* TODO(sergey): Add branch name to file as well? */ + fg.build_commit_timestamp = build_commit_timestamp; + BLI_strncpy(fg.build_hash, build_hash, sizeof(fg.build_hash)); } #else - fg.revision= 0; + fg.build_commit_timestamp = 0; + BLI_strncpy(fg.build_hash, "unknown", sizeof(fg.build_hash)); #endif writestruct(wd, GLOB, "FileGlobal", 1, &fg); } diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index 67f95cca6aa..b80a10b43fe 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -119,6 +119,8 @@ set(SRC intern/bmesh_operator_api.h intern/bmesh_error.h + tools/bmesh_beautify.c + tools/bmesh_beautify.h tools/bmesh_bevel.c tools/bmesh_bevel.h tools/bmesh_bisect_plane.c diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index 90105b0dd81..9c43e5a2ee4 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -183,9 +183,28 @@ typedef struct BMesh { * BM_LOOP isn't handled so far. */ char elem_index_dirty; + /* flag array table as being dirty so we know when its safe to use it, + * or when it needs to be re-created */ + char elem_table_dirty; + + /* element pools */ struct BLI_mempool *vpool, *epool, *lpool, *fpool; + /* mempool lookup tables (optional) + * index tables, to map indices to elements via + * BM_mesh_elem_table_ensure and associated functions. don't + * touch this or read it directly.\ + * Use BM_mesh_elem_table_ensure(), BM_vert/edge/face_at_index() */ + BMVert **vtable; + BMEdge **etable; + BMFace **ftable; + + /* size of allocated tables */ + int vtable_tot; + int etable_tot; + int ftable_tot; + /* operator api stuff (must be all NULL or all alloc'd) */ struct BLI_mempool *vtoolflagpool, *etoolflagpool, *ftoolflagpool; diff --git a/source/blender/bmesh/bmesh_tools.h b/source/blender/bmesh/bmesh_tools.h index b2dac810bce..baffeb774b6 100644 --- a/source/blender/bmesh/bmesh_tools.h +++ b/source/blender/bmesh/bmesh_tools.h @@ -34,6 +34,7 @@ extern "C" { #endif +#include "tools/bmesh_beautify.h" #include "tools/bmesh_bevel.h" #include "tools/bmesh_bisect_plane.h" #include "tools/bmesh_decimate.h" diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 8441a6ec75f..0726af4b641 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -70,7 +70,9 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], /* disallow this flag for verts - its meaningless */ BLI_assert((create_flag & BM_CREATE_NO_DOUBLE) == 0); - bm->elem_index_dirty |= BM_VERT; /* may add to middle of the pool */ + /* may add to middle of the pool */ + bm->elem_index_dirty |= BM_VERT; + bm->elem_table_dirty |= BM_VERT; bm->totvert++; @@ -130,7 +132,9 @@ BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, BM_elem_index_set(e, -1); /* set_ok_invalid */ #endif - bm->elem_index_dirty |= BM_EDGE; /* may add to middle of the pool */ + /* may add to middle of the pool */ + bm->elem_index_dirty |= BM_EDGE; + bm->elem_table_dirty |= BM_EDGE; bm->totedge++; @@ -292,7 +296,9 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm, const eBMCreateFlag creat BM_elem_index_set(f, -1); /* set_ok_invalid */ #endif - bm->elem_index_dirty |= BM_FACE; /* may add to middle of the pool */ + /* may add to middle of the pool */ + bm->elem_index_dirty |= BM_FACE; + bm->elem_table_dirty |= BM_FACE; bm->totface++; @@ -562,6 +568,7 @@ static void bm_kill_only_vert(BMesh *bm, BMVert *v) { bm->totvert--; bm->elem_index_dirty |= BM_VERT; + bm->elem_table_dirty |= BM_VERT; BM_select_history_remove(bm, v); @@ -582,6 +589,7 @@ static void bm_kill_only_edge(BMesh *bm, BMEdge *e) { bm->totedge--; bm->elem_index_dirty |= BM_EDGE; + bm->elem_table_dirty |= BM_EDGE; BM_select_history_remove(bm, (BMElem *)e); @@ -605,6 +613,7 @@ static void bm_kill_only_face(BMesh *bm, BMFace *f) bm->totface--; bm->elem_index_dirty |= BM_FACE; + bm->elem_table_dirty |= BM_FACE; BM_select_history_remove(bm, (BMElem *)f); diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index cc2324ba34a..701fdf07710 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -213,6 +213,10 @@ void BM_mesh_data_free(BMesh *bm) BLI_mempool_destroy(bm->lpool); BLI_mempool_destroy(bm->fpool); + if (bm->vtable) MEM_freeN(bm->vtable); + if (bm->etable) MEM_freeN(bm->etable); + if (bm->ftable) MEM_freeN(bm->ftable); + /* destroy flag pool */ BM_mesh_elem_toolflags_clear(bm); @@ -623,6 +627,179 @@ void BM_mesh_elem_index_validate(BMesh *bm, const char *location, const char *fu } +/* debug check only - no need to optimize */ +#ifndef NDEBUG +bool BM_mesh_elem_table_check(BMesh *bm) +{ + BMIter iter; + BMElem *ele; + int i; + + if (bm->vtable && ((bm->elem_table_dirty & BM_VERT) == 0)) { + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) { + if (ele != (BMElem *)bm->vtable[i]) { + return false; + } + } + } + + if (bm->etable && ((bm->elem_table_dirty & BM_EDGE) == 0)) { + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) { + if (ele != (BMElem *)bm->etable[i]) { + return false; + } + } + } + + if (bm->ftable && ((bm->elem_table_dirty & BM_FACE) == 0)) { + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) { + if (ele != (BMElem *)bm->ftable[i]) { + return false; + } + } + } + + return true; +} +#endif + + + +void BM_mesh_elem_table_ensure(BMesh *bm, const char htype) +{ + /* assume if the array is non-null then its valid and no need to recalc */ + const char htype_needed = (((bm->vtable && ((bm->elem_table_dirty & BM_VERT) == 0)) ? 0 : BM_VERT) | + ((bm->etable && ((bm->elem_table_dirty & BM_EDGE) == 0)) ? 0 : BM_EDGE) | + ((bm->ftable && ((bm->elem_table_dirty & BM_FACE) == 0)) ? 0 : BM_FACE)) & htype; + + BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); + + /* in debug mode double check we didn't need to recalculate */ + BLI_assert(BM_mesh_elem_table_check(bm) == true); + + if (htype_needed & BM_VERT) { + if (bm->vtable && bm->totvert <= bm->vtable_tot && bm->totvert * 2 >= bm->vtable_tot) { + /* pass (re-use the array) */ + } + else { + if (bm->vtable) + MEM_freeN(bm->vtable); + bm->vtable = MEM_mallocN(sizeof(void **) * bm->totvert, "bm->vtable"); + bm->vtable_tot = bm->totvert; + } + bm->elem_table_dirty &= ~BM_VERT; + } + if (htype_needed & BM_EDGE) { + if (bm->etable && bm->totedge <= bm->etable_tot && bm->totedge * 2 >= bm->etable_tot) { + /* pass (re-use the array) */ + } + else { + if (bm->etable) + MEM_freeN(bm->etable); + bm->etable = MEM_mallocN(sizeof(void **) * bm->totedge, "bm->etable"); + bm->etable_tot = bm->totedge; + } + bm->elem_table_dirty &= ~BM_EDGE; + } + if (htype_needed & BM_FACE) { + if (bm->ftable && bm->totface <= bm->ftable_tot && bm->totface * 2 >= bm->ftable_tot) { + /* pass (re-use the array) */ + } + else { + if (bm->ftable) + MEM_freeN(bm->ftable); + bm->ftable = MEM_mallocN(sizeof(void **) * bm->totface, "bm->ftable"); + bm->ftable_tot = bm->totface; + } + bm->elem_table_dirty &= ~BM_FACE; + } + +#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT) + { +#pragma omp section + { + if (htype_needed & BM_VERT) { + BM_iter_as_array(bm, BM_VERTS_OF_MESH, NULL, (void **)bm->vtable, bm->totvert); + } + } +#pragma omp section + { + if (htype_needed & BM_EDGE) { + BM_iter_as_array(bm, BM_EDGES_OF_MESH, NULL, (void **)bm->etable, bm->totedge); + } + } +#pragma omp section + { + if (htype_needed & BM_FACE) { + BM_iter_as_array(bm, BM_FACES_OF_MESH, NULL, (void **)bm->ftable, bm->totface); + } + } + } +} + +/* use BM_mesh_elem_table_ensure where possible to avoid full rebuild */ +void BM_mesh_elem_table_init(BMesh *bm, const char htype) +{ + BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); + + /* force recalc */ + BM_mesh_elem_table_free(bm, BM_ALL_NOLOOP); + BM_mesh_elem_table_ensure(bm, htype); +} + +void BM_mesh_elem_table_free(BMesh *bm, const char htype) +{ + if (htype & BM_VERT) { + MEM_SAFE_FREE(bm->vtable); + } + + if (htype & BM_EDGE) { + MEM_SAFE_FREE(bm->etable); + } + + if (htype & BM_FACE) { + MEM_SAFE_FREE(bm->ftable); + } +} + +BMVert *BM_vert_at_index(BMesh *bm, const int index) +{ + BLI_assert((index >= 0) && (index < bm->totvert)); + BLI_assert((bm->elem_table_dirty & BM_VERT) == 0); + return bm->vtable[index]; +} + +BMEdge *BM_edge_at_index(BMesh *bm, const int index) +{ + BLI_assert((index >= 0) && (index < bm->totedge)); + BLI_assert((bm->elem_table_dirty & BM_EDGE) == 0); + return bm->etable[index]; +} + +BMFace *BM_face_at_index(BMesh *bm, const int index) +{ + BLI_assert((index >= 0) && (index < bm->totface)); + BLI_assert((bm->elem_table_dirty & BM_FACE) == 0); + return bm->ftable[index]; +} + + +BMVert *BM_vert_at_index_find(BMesh *bm, const int index) +{ + return BLI_mempool_findelem(bm->vpool, index); +} + +BMEdge *BM_edge_at_index_find(BMesh *bm, const int index) +{ + return BLI_mempool_findelem(bm->epool, index); +} + +BMFace *BM_face_at_index_find(BMesh *bm, const int index) +{ + return BLI_mempool_findelem(bm->fpool, index); +} + + /** * Return the amount of element of type 'type' in a given bmesh. */ @@ -828,18 +1005,3 @@ void BM_mesh_remap(BMesh *bm, int *vert_idx, int *edge_idx, int *face_idx) if (fptr_map) BLI_ghash_free(fptr_map, NULL, NULL); } - -BMVert *BM_vert_at_index(BMesh *bm, const int index) -{ - return BLI_mempool_findelem(bm->vpool, index); -} - -BMEdge *BM_edge_at_index(BMesh *bm, const int index) -{ - return BLI_mempool_findelem(bm->epool, index); -} - -BMFace *BM_face_at_index(BMesh *bm, const int index) -{ - return BLI_mempool_findelem(bm->fpool, index); -} diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h index 583b1589290..33431714660 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.h +++ b/source/blender/bmesh/intern/bmesh_mesh.h @@ -45,14 +45,29 @@ void bmesh_edit_end(BMesh *bm, const BMOpTypeFlag type_flag); void BM_mesh_elem_index_ensure(BMesh *bm, const char hflag); void BM_mesh_elem_index_validate(BMesh *bm, const char *location, const char *func, const char *msg_a, const char *msg_b); -int BM_mesh_elem_count(BMesh *bm, const char htype); -void BM_mesh_remap(BMesh *bm, int *vert_idx, int *edge_idx, int *face_idx); +#ifndef NDEBUG +bool BM_mesh_elem_table_check(BMesh *em); +#endif + +void BM_mesh_elem_table_ensure(BMesh *bm, const char htype); +void BM_mesh_elem_table_init(BMesh *bm, const char htype); +void BM_mesh_elem_table_free(BMesh *bm, const char htype); BMVert *BM_vert_at_index(BMesh *bm, const int index); BMEdge *BM_edge_at_index(BMesh *bm, const int index); BMFace *BM_face_at_index(BMesh *bm, const int index); +BMVert *BM_vert_at_index_find(BMesh *bm, const int index); +BMEdge *BM_edge_at_index_find(BMesh *bm, const int index); +BMFace *BM_face_at_index_find(BMesh *bm, const int index); + +// XXX + +int BM_mesh_elem_count(BMesh *bm, const char htype); + +void BM_mesh_remap(BMesh *bm, int *vert_idx, int *edge_idx, int *face_idx); + typedef struct BMAllocTemplate { int totvert, totedge, totloop, totface; } BMAllocTemplate; diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index 3ffdd0f86a6..4dc155e68c2 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -231,49 +231,24 @@ bool BM_disk_dissolve(BMesh *bm, BMVert *v) * to be reconsidered. * * If the windings do not match the winding of the new face will follow - * \a f1's winding (i.e. \a f2 will be reversed before the join). + * \a f_a's winding (i.e. \a f_b will be reversed before the join). * * \return pointer to the combined face */ -BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e, const bool do_del) +BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f_a, BMFace *f_b, BMEdge *e, const bool do_del) { - BMLoop *l1, *l2; - BMEdge *jed = NULL; - BMFace *faces[2] = {f1, f2}; - - jed = e; - if (!jed) { - BMLoop *l_first; - /* search for an edge that has both these faces in its radial cycle */ - l1 = l_first = BM_FACE_FIRST_LOOP(f1); - do { - if (l1->radial_next->f == f2) { - jed = l1->e; - break; - } - } while ((l1 = l1->next) != l_first); - } + BMFace *faces[2] = {f_a, f_b}; - if (UNLIKELY(!jed)) { - BMESH_ASSERT(0); - return NULL; - } - - l1 = jed->l; - - if (UNLIKELY(!l1)) { - BMESH_ASSERT(0); - return NULL; - } - - l2 = l1->radial_next; - if (l1->v == l2->v) { - bmesh_loop_reverse(bm, f2); - } + BMLoop *l_a = BM_face_edge_share_loop(f_a, e); + BMLoop *l_b = BM_face_edge_share_loop(f_b, e); - f1 = BM_faces_join(bm, faces, 2, do_del); + BLI_assert(l_a && l_b); + + if (l_a->v == l_b->v) { + bmesh_loop_reverse(bm, f_b); + } - return f1; + return BM_faces_join(bm, faces, 2, do_del); } /** @@ -849,7 +824,7 @@ void BM_edge_calc_rotate(BMEdge *e, const bool ccw, /* we could swap the verts _or_ the faces, swapping faces * gives more predictable results since that way the next vert * just stitches from face fa / fb */ - if (ccw) { + if (!ccw) { SWAP(BMFace *, fa, fb); } @@ -1074,7 +1049,7 @@ BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const bool ccw, const short check_f f_hflag_prev_2 = l2->f->head.hflag; /* don't delete the edge, manually remove the edge after so we can copy its attributes */ - f = BM_faces_join_pair(bm, l1->f, l2->f, NULL, true); + f = BM_faces_join_pair(bm, l1->f, l2->f, e, true); if (f == NULL) { return NULL; diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 775cb24b8c9..ef43d73d485 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -1028,7 +1028,8 @@ static BMOpDefine bmo_triangulate_def = { "triangulate", /* slots_in */ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, - {"use_beauty", BMO_OP_SLOT_BOOL}, + {"quad_method", BMO_OP_SLOT_INT}, + {"ngon_method", BMO_OP_SLOT_INT}, {{'\0'}}, }, /* slots_out */ @@ -1556,6 +1557,7 @@ static BMOpDefine bmo_bevel_def = { /* slots_in */ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input edges and vertices */ {"offset", BMO_OP_SLOT_FLT}, /* amount to offset beveled edge */ + {"offset_type", BMO_OP_SLOT_INT}, /* how to measure offset (enum) */ {"segments", BMO_OP_SLOT_INT}, /* number of segments in bevel */ {"vertex_only", BMO_OP_SLOT_BOOL}, /* only bevel vertices, not edges */ {{'\0'}}, diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h index 56d63694d88..b3d97947cab 100644 --- a/source/blender/bmesh/intern/bmesh_operators.h +++ b/source/blender/bmesh/intern/bmesh_operators.h @@ -117,6 +117,14 @@ enum { BMOP_POKE_BOUNDS }; +/* Bevel offset_type slot values */ +enum { + BEVEL_AMT_OFFSET, + BEVEL_AMT_WIDTH, + BEVEL_AMT_DEPTH, + BEVEL_AMT_PERCENT +}; + extern const BMOpDefine *bmo_opdefines[]; extern const int bmo_opdefines_total; diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index e4c1180d433..3db6ba0e7c9 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -29,6 +29,9 @@ */ #include "DNA_listBase.h" +#include "DNA_modifier_types.h" + +#include "MEM_guardedalloc.h" #include "BLI_alloca.h" #include "BLI_math.h" @@ -37,6 +40,7 @@ #include "BLI_listbase.h" #include "bmesh.h" +#include "bmesh_tools.h" #include "intern/bmesh_private.h" @@ -803,33 +807,98 @@ bool BM_face_point_inside_test(BMFace *f, const float co[3]) /** * \brief BMESH TRIANGULATE FACE * - * Currently repeatedly find the best triangle (i.e. the most "open" one), provided it does not - * produces a "remaining" face with too much wide/narrow angles - * (using cos (i.e. dot product of normalized vectors) of angles). + * Breaks all quads and ngons down to triangles. + * It uses scanfill for the ngons splitting, and + * the beautify operator when use_beauty is true. * * \param r_faces_new if non-null, must be an array of BMFace pointers, - * with a length equal to (f->len - 2). It will be filled with the new - * triangles. + * with a length equal to (f->len - 3). It will be filled with the new + * triangles (not including the original triangle). * * \note use_tag tags new flags and edges. */ -#define SF_EDGE_IS_BOUNDARY 0xff void BM_face_triangulate(BMesh *bm, BMFace *f, BMFace **r_faces_new, MemArena *sf_arena, - const bool UNUSED(use_beauty), const bool use_tag) + const int quad_method, + const int ngon_method, + const bool use_tag) { - int nf_i = 0; BMLoop *l_iter, *l_first, *l_new; BMFace *f_new; + int orig_f_len = f->len; + int nf_i = 0; + BMEdge **edge_array; + int edge_array_len; + bool use_beauty = (ngon_method == MOD_TRIANGULATE_NGON_BEAUTY); + +#define SF_EDGE_IS_BOUNDARY 0xff BLI_assert(BM_face_is_normal_valid(f)); if (f->len == 4) { + BMVert *v1, *v2; l_first = BM_FACE_FIRST_LOOP(f); - f_new = BM_face_split(bm, f, l_first->v, l_first->next->next->v, &l_new, NULL, false); + switch (quad_method) { + case MOD_TRIANGULATE_QUAD_FIXED: + { + v1 = l_first->v; + v2 = l_first->next->next->v; + break; + } + case MOD_TRIANGULATE_QUAD_ALTERNATE: + { + v1 = l_first->next->v; + v2 = l_first->prev->v; + break; + } + case MOD_TRIANGULATE_QUAD_SHORTEDGE: + { + BMVert *v3, *v4; + float d1, d2; + + v1 = l_first->v; + v2 = l_first->next->next->v; + v3 = l_first->next->v; + v4 = l_first->prev->v; + + d1 = len_squared_v3v3(v1->co, v2->co); + d2 = len_squared_v3v3(v3->co, v4->co); + + if (d2 < d1) { + v1 = v3; + v2 = v4; + } + break; + } + case MOD_TRIANGULATE_QUAD_BEAUTY: + default: + { + BMVert *v3, *v4; + float cost; + + v1 = l_first->next->v; + v2 = l_first->next->next->v; + v3 = l_first->prev->v; + v4 = l_first->v; + + cost = BM_verts_calc_rotate_beauty(v1, v2, v3, v4, 0, 0); + + if (cost < 0.0f) { + v1 = v4; + //v2 = v2; + } + else { + //v1 = v1; + v2 = v3; + } + break; + } + } + + f_new = BM_face_split(bm, f, v1, v2, &l_new, NULL, false); copy_v3_v3(f_new->no, f->no); if (use_tag) { @@ -904,35 +973,115 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, if (use_tag) { BM_elem_flag_enable(f_new, BM_ELEM_TAG); } - if (r_faces_new && sf_tri->next) { + if (r_faces_new) { r_faces_new[nf_i++] = f_new; } } } - if (use_tag) { + if (use_beauty || use_tag) { ScanFillEdge *sf_edge; + edge_array = BLI_array_alloca(edge_array, orig_f_len - 3); + edge_array_len = 0; + for (sf_edge = sf_ctx.filledgebase.first; sf_edge; sf_edge = sf_edge->next) { + BMLoop *l1 = sf_edge->v1->tmp.p; + BMLoop *l2 = sf_edge->v2->tmp.p; + + BMEdge *e = BM_edge_exists(l1->v, l2->v); if (sf_edge->tmp.c != SF_EDGE_IS_BOUNDARY) { - BMLoop *l1 = sf_edge->v1->tmp.p; - BMLoop *l2 = sf_edge->v2->tmp.p; - BMEdge *e = BM_edge_exists(l1->v, l2->v); - BM_elem_flag_enable(e, BM_ELEM_TAG); + if (use_beauty) { + BM_elem_index_set(e, edge_array_len); /* set_dirty */ + edge_array[edge_array_len] = e; + edge_array_len++; + } + + if (use_tag) { + BM_elem_flag_enable(e, BM_ELEM_TAG); + } + } + else if (use_tag) { + BM_elem_flag_disable(e, BM_ELEM_TAG); } } + } - if (sf_ctx.fillfacebase.first) { + if ((!use_beauty) || (!r_faces_new)) { /* we can't delete the real face, because some of the callers expect it to remain valid. * so swap data and delete the last created tri */ bmesh_face_swap_data(bm, f, f_new); BM_face_kill(bm, f_new); } + if (use_beauty) { + bm->elem_index_dirty |= BM_EDGE; + BM_mesh_beautify_fill(bm, edge_array, edge_array_len, 0, 0, 0, 0); + + if (r_faces_new) { + /* beautify deletes and creates new faces + * we need to re-populate the r_faces_new array + * with the new faces + */ + int i; + + +#define FACE_USED_TEST(f) (BM_elem_index_get(f) == -2) +#define FACE_USED_SET(f) BM_elem_index_set(f, -2) + + nf_i = 0; + for (i = 0; i < edge_array_len; i++) { + BMFace *f_a, *f_b; + BMEdge *e = edge_array[i]; + const bool ok = BM_edge_face_pair(e, &f_a, &f_b); + + BLI_assert(ok); + + if (FACE_USED_TEST(f_a) == false) { + FACE_USED_SET(f_a); + + if (nf_i < edge_array_len) { + r_faces_new[nf_i++] = f_a; + } + else { + f_new = f_a; + break; + } + } + + if (FACE_USED_TEST(f_b) == false) { + FACE_USED_SET(f_b); + + if (nf_i < edge_array_len) { + r_faces_new[nf_i++] = f_b; + } + else { + f_new = f_b; + break; + } + } + } + +#undef FACE_USED_TEST +#undef FACE_USED_SET + + /* nf_i doesn't include the last face */ + BLI_assert(nf_i == orig_f_len - 3); + + /* we can't delete the real face, because some of the callers expect it to remain valid. + * so swap data and delete the last created tri */ + bmesh_face_swap_data(bm, f, f_new); + BM_face_kill(bm, f_new); + } + } + /* garbage collection */ BLI_scanfill_end_arena(&sf_ctx, sf_arena); } + +#undef SF_EDGE_IS_BOUNDARY + } /** @@ -1121,3 +1270,160 @@ void BM_face_as_array_loop_quad(BMFace *f, BMLoop *r_loops[4]) r_loops[2] = l; l = l->next; r_loops[3] = l; } + + +/** + * \brief BM_bmesh_calc_tessellation get the looptris and its number from a certain bmesh + * \param looptris + * + * \note \a looptris Must be pre-allocated to at least the size of given by: poly_to_tri_count + */ +void BM_bmesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptris_tot) +{ + /* use this to avoid locking pthread for _every_ polygon + * and calling the fill function */ +#define USE_TESSFACE_SPEEDUP + + /* this assumes all faces can be scan-filled, which isn't always true, + * worst case we over alloc a little which is acceptable */ + const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop); + + BMIter iter; + BMFace *efa; + BMLoop *l; + int i = 0; + + ScanFillContext sf_ctx; + MemArena *sf_arena = NULL; + + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + /* don't consider two-edged faces */ + if (UNLIKELY(efa->len < 3)) { + /* do nothing */ + } + +#ifdef USE_TESSFACE_SPEEDUP + + /* no need to ensure the loop order, we know its ok */ + + else if (efa->len == 3) { +#if 0 + int j; + BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) { + looptris[i][j] = l; + } + i += 1; +#else + /* more cryptic but faster */ + BMLoop **l_ptr = looptris[i++]; + l_ptr[0] = l = BM_FACE_FIRST_LOOP(efa); + l_ptr[1] = l = l->next; + l_ptr[2] = l->next; +#endif + } + else if (efa->len == 4) { +#if 0 + BMLoop *ltmp[4]; + int j; + BLI_array_grow_items(looptris, 2); + BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) { + ltmp[j] = l; + } + + looptris[i][0] = ltmp[0]; + looptris[i][1] = ltmp[1]; + looptris[i][2] = ltmp[2]; + i += 1; + + looptris[i][0] = ltmp[0]; + looptris[i][1] = ltmp[2]; + looptris[i][2] = ltmp[3]; + i += 1; +#else + /* more cryptic but faster */ + BMLoop **l_ptr_a = looptris[i++]; + BMLoop **l_ptr_b = looptris[i++]; + (l_ptr_a[0] = l_ptr_b[0] = l = BM_FACE_FIRST_LOOP(efa)); + (l_ptr_a[1] = l = l->next); + (l_ptr_a[2] = l_ptr_b[1] = l = l->next); + ( l_ptr_b[2] = l->next); +#endif + } + +#endif /* USE_TESSFACE_SPEEDUP */ + + else { + int j; + BMLoop *l_iter; + BMLoop *l_first; + + ScanFillVert *sf_vert, *sf_vert_last = NULL, *sf_vert_first = NULL; + /* ScanFillEdge *e; */ /* UNUSED */ + ScanFillFace *sf_tri; + int totfilltri; + + if (UNLIKELY(sf_arena == NULL)) { + sf_arena = BLI_memarena_new(BLI_SCANFILL_ARENA_SIZE, __func__); + } + + BLI_scanfill_begin_arena(&sf_ctx, sf_arena); + + /* scanfill time */ + j = 0; + l_iter = l_first = BM_FACE_FIRST_LOOP(efa); + do { + sf_vert = BLI_scanfill_vert_add(&sf_ctx, l_iter->v->co); + sf_vert->tmp.p = l_iter; + + if (sf_vert_last) { + /* e = */ BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert); + } + + sf_vert_last = sf_vert; + if (sf_vert_first == NULL) { + sf_vert_first = sf_vert; + } + + /*mark order */ + BM_elem_index_set(l_iter, j++); /* set_loop */ + + } while ((l_iter = l_iter->next) != l_first); + + /* complete the loop */ + BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert); + + totfilltri = BLI_scanfill_calc_ex(&sf_ctx, 0, efa->no); + BLI_assert(totfilltri <= efa->len - 2); + (void)totfilltri; + + for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) { + BMLoop **l_ptr = looptris[i++]; + BMLoop *l1 = sf_tri->v1->tmp.p; + BMLoop *l2 = sf_tri->v2->tmp.p; + BMLoop *l3 = sf_tri->v3->tmp.p; + + if (BM_elem_index_get(l1) > BM_elem_index_get(l2)) { SWAP(BMLoop *, l1, l2); } + if (BM_elem_index_get(l2) > BM_elem_index_get(l3)) { SWAP(BMLoop *, l2, l3); } + if (BM_elem_index_get(l1) > BM_elem_index_get(l2)) { SWAP(BMLoop *, l1, l2); } + + l_ptr[0] = l1; + l_ptr[1] = l2; + l_ptr[2] = l3; + } + + BLI_scanfill_end_arena(&sf_ctx, sf_arena); + } + } + + if (sf_arena) { + BLI_memarena_free(sf_arena); + sf_arena = NULL; + } + + *r_looptris_tot = looptris_tot; + + BLI_assert(i <= looptris_tot); + +#undef USE_TESSFACE_SPEEDUP + +} diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h index b7117621273..4b3b7f4b837 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.h +++ b/source/blender/bmesh/intern/bmesh_polygon.h @@ -29,6 +29,8 @@ #include "BLI_compiler_attrs.h" +void BM_bmesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptris_tot); + int BM_face_calc_tessellation(const BMFace *f, BMLoop **r_loops, int (*r_index)[3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); void BM_face_calc_normal(const BMFace *f, float r_no[3]) ATTR_NONNULL(); void BM_face_calc_normal_vcos(BMesh *bm, BMFace *f, float r_no[3], @@ -54,7 +56,8 @@ bool BM_face_point_inside_test(BMFace *f, const float co[3]) ATTR_WARN_UNUSED_R void BM_face_triangulate(BMesh *bm, BMFace *f, BMFace **newfaces, struct MemArena *sf_arena, - const bool use_beauty, const bool use_tag) ATTR_NONNULL(1, 2); + const int quad_method, const int ngon_method, + const bool use_tag) ATTR_NONNULL(1, 2); void BM_face_legal_splits(BMFace *f, BMLoop *(*loops)[2], int len) ATTR_NONNULL(); diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c index 238b7b4aaaa..aca2f96dc18 100644 --- a/source/blender/bmesh/intern/bmesh_walkers_impl.c +++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c @@ -37,7 +37,7 @@ #include "intern/bmesh_walkers_private.h" /* pop into stack memory (common operation) */ -#define BMW_state_remove_r(walker, owalk) { \ +#define BMW_state_remove_r(walker, owalk) { \ memcpy(owalk, BMW_current_state(walker), sizeof(*(owalk))); \ BMW_state_remove(walker); \ } (void)0 diff --git a/source/blender/bmesh/operators/bmo_beautify.c b/source/blender/bmesh/operators/bmo_beautify.c index bd20e384234..d9ab30bfcfa 100644 --- a/source/blender/bmesh/operators/bmo_beautify.c +++ b/source/blender/bmesh/operators/bmo_beautify.c @@ -25,426 +25,19 @@ * * Beautify the mesh by rotating edges between triangles * to more attractive positions until no more rotations can be made. - * - * In principle this is very simple however there is the possibility of - * going into an eternal loop where edges keep rotating. - * To avoid this - each edge stores a set of it previous - * states so as not to rotate back. - * - * TODO - * - Take face normals into account. */ #include "BLI_math.h" -#include "BLI_heap.h" #include "MEM_guardedalloc.h" #include "bmesh.h" +#include "bmesh_tools.h" #include "intern/bmesh_operators_private.h" -#include "BLI_strict_flags.h" - -// #define DEBUG_TIME - -#ifdef DEBUG_TIME -# include "PIL_time.h" -# include "PIL_time_utildefines.h" -#endif - -enum { - VERT_RESTRICT_TAG = (1 << 0), -}; - -/* -------------------------------------------------------------------- */ -/* GSet for edge rotation */ - -typedef struct EdRotState { - int v1, v2; /* edge vert, small -> large */ - int f1, f2; /* face vert, small -> large */ -} EdRotState; - -static unsigned int erot_gsetutil_hash(const void *ptr) -{ - const EdRotState *e_state = (const EdRotState *)ptr; - unsigned int - hash = BLI_ghashutil_inthash(SET_INT_IN_POINTER(e_state->v1)); - hash ^= BLI_ghashutil_inthash(SET_INT_IN_POINTER(e_state->v2)); - hash ^= BLI_ghashutil_inthash(SET_INT_IN_POINTER(e_state->f1)); - hash ^= BLI_ghashutil_inthash(SET_INT_IN_POINTER(e_state->f2)); - return hash; -} -static int erot_gsetutil_cmp(const void *a, const void *b) -{ - const EdRotState *e_state_a = (const EdRotState *)a; - const EdRotState *e_state_b = (const EdRotState *)b; - if (e_state_a->v1 < e_state_b->v1) return -1; - else if (e_state_a->v1 > e_state_b->v1) return 1; - else if (e_state_a->v2 < e_state_b->v2) return -1; - else if (e_state_a->v2 > e_state_b->v2) return 1; - else if (e_state_a->f1 < e_state_b->f1) return -1; - else if (e_state_a->f1 > e_state_b->f1) return 1; - else if (e_state_a->f2 < e_state_b->f2) return -1; - else if (e_state_a->f2 > e_state_b->f2) return 1; - else return 0; -} - -static GSet *erot_gset_new(void) -{ - return BLI_gset_new(erot_gsetutil_hash, erot_gsetutil_cmp, __func__); -} - -/* ensure v0 is smaller */ -#define EDGE_ORD(v0, v1) \ - if (v0 > v1) { \ - v0 ^= v1; \ - v1 ^= v0; \ - v0 ^= v1; \ - } (void)0 - -static void erot_state_ex(const BMEdge *e, int v_index[2], int f_index[2]) -{ - BLI_assert(BM_edge_is_manifold((BMEdge *)e)); - BLI_assert(BM_vert_in_edge(e, e->l->prev->v) == false); - BLI_assert(BM_vert_in_edge(e, e->l->radial_next->prev->v) == false); - - /* verts of the edge */ - v_index[0] = BM_elem_index_get(e->v1); - v_index[1] = BM_elem_index_get(e->v2); - EDGE_ORD(v_index[0], v_index[1]); - - /* verts of each of the 2 faces attached to this edge - * (that are not apart of this edge) */ - f_index[0] = BM_elem_index_get(e->l->prev->v); - f_index[1] = BM_elem_index_get(e->l->radial_next->prev->v); - EDGE_ORD(f_index[0], f_index[1]); -} - -static void erot_state_current(const BMEdge *e, EdRotState *e_state) -{ - erot_state_ex(e, &e_state->v1, &e_state->f1); -} - -static void erot_state_alternate(const BMEdge *e, EdRotState *e_state) -{ - erot_state_ex(e, &e_state->f1, &e_state->v1); -} - -/* -------------------------------------------------------------------- */ -/* Calculate the improvement of rotating the edge */ - -/** - * \return a negative value means the edge can be rotated. - */ -static float bm_edge_calc_rotate_beauty__area( - const float v1[3], const float v2[3], const float v3[3], const float v4[3]) -{ - /* not a loop (only to be able to break out) */ - do { - float v1_xy[2], v2_xy[2], v3_xy[2], v4_xy[2]; - - /* first get the 2d values */ - { - bool is_zero_a, is_zero_b; - float no[3]; - float axis_mat[3][3]; - - // printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f); - BLI_assert((ELEM3(v1, v2, v3, v4) == false) && - (ELEM3(v2, v1, v3, v4) == false) && - (ELEM3(v3, v1, v2, v4) == false) && - (ELEM3(v4, v1, v2, v3) == false)); - - is_zero_a = area_tri_v3(v2, v3, v4) <= FLT_EPSILON; - is_zero_b = area_tri_v3(v2, v4, v1) <= FLT_EPSILON; - - if (LIKELY(is_zero_a == false && is_zero_b == false)) { - float no_a[3], no_b[3]; - normal_tri_v3(no_a, v2, v3, v4); /* a */ - normal_tri_v3(no_b, v2, v4, v1); /* b */ - add_v3_v3v3(no, no_a, no_b); - if (UNLIKELY(normalize_v3(no) <= FLT_EPSILON)) { - break; - } - } - else if (is_zero_a == false) { - normal_tri_v3(no, v2, v3, v4); /* a */ - } - else if (is_zero_b == false) { - normal_tri_v3(no, v2, v4, v1); /* b */ - } - else { - /* both zero area, no useful normal can be calculated */ - break; - } - - // { float a = angle_normalized_v3v3(no_a, no_b); printf("~ %.7f\n", a); fflush(stdout);} - - axis_dominant_v3_to_m3(axis_mat, no); - mul_v2_m3v3(v1_xy, axis_mat, v1); - mul_v2_m3v3(v2_xy, axis_mat, v2); - mul_v2_m3v3(v3_xy, axis_mat, v3); - mul_v2_m3v3(v4_xy, axis_mat, v4); - } - - // printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f); - - if (is_quad_convex_v2(v1_xy, v2_xy, v3_xy, v4_xy)) { - /* testing rule: the area divided by the perimeter, - * check if (1-3) beats the existing (2-4) edge rotation */ - float area_a, area_b; - float prim_a, prim_b; - float fac_24, fac_13; - - float len_12, len_23, len_34, len_41, len_24, len_13; - - /* edges around the quad */ - len_12 = len_v2v2(v1_xy, v2_xy); - len_23 = len_v2v2(v2_xy, v3_xy); - len_34 = len_v2v2(v3_xy, v4_xy); - len_41 = len_v2v2(v4_xy, v1_xy); - /* edges crossing the quad interior */ - len_13 = len_v2v2(v1_xy, v3_xy); - len_24 = len_v2v2(v2_xy, v4_xy); - - /* edge (2-4), current state */ - area_a = area_tri_v2(v2_xy, v3_xy, v4_xy); - area_b = area_tri_v2(v2_xy, v4_xy, v1_xy); - prim_a = len_23 + len_34 + len_24; - prim_b = len_24 + len_41 + len_12; - fac_24 = (area_a / prim_a) + (area_b / prim_b); - - /* edge (1-3), new state */ - area_a = area_tri_v2(v1_xy, v2_xy, v3_xy); - area_b = area_tri_v2(v1_xy, v3_xy, v4_xy); - prim_a = len_12 + len_23 + len_13; - prim_b = len_34 + len_41 + len_13; - fac_13 = (area_a / prim_a) + (area_b / prim_b); - - /* negative number if (1-3) is an improved state */ - return fac_24 - fac_13; - } - } while (false); - - return FLT_MAX; -} - -static float bm_edge_calc_rotate_beauty__angle( - const float v1[3], const float v2[3], const float v3[3], const float v4[3]) -{ - /* not a loop (only to be able to break out) */ - do { - float no_a[3], no_b[3]; - float angle_24, angle_13; - - /* edge (2-4), current state */ - normal_tri_v3(no_a, v2, v3, v4); - normal_tri_v3(no_b, v2, v4, v1); - angle_24 = angle_normalized_v3v3(no_a, no_b); - - /* edge (1-3), new state */ - /* only check new state for degenerate outcome */ - if ((normal_tri_v3(no_a, v1, v2, v3) == 0.0f) || - (normal_tri_v3(no_b, v1, v3, v4) == 0.0f)) - { - break; - } - angle_13 = angle_normalized_v3v3(no_a, no_b); - - return angle_13 - angle_24; - } while (false); - - return FLT_MAX; -} - -static float bm_edge_calc_rotate_beauty(const BMEdge *e, const short flag, const short method) -{ - /* not a loop (only to be able to break out) */ - do { - const float *v1, *v2, *v3, *v4; - - v1 = e->l->prev->v->co; /* first face co */ - v2 = e->l->v->co; /* e->v1 or e->v2*/ - v3 = e->l->radial_next->prev->v->co; /* second face co */ - v4 = e->l->next->v->co; /* e->v1 or e->v2*/ - - if (flag & VERT_RESTRICT_TAG) { - BMVert *v_a = e->l->prev->v, *v_b = e->l->radial_next->prev->v; - if (BM_elem_flag_test(v_a, BM_ELEM_TAG) == BM_elem_flag_test(v_b, BM_ELEM_TAG)) { - break; - } - } - - if (UNLIKELY(v1 == v3)) { - // printf("This should never happen, but does sometimes!\n"); - break; - } - - switch (method) { - case 0: - return bm_edge_calc_rotate_beauty__area(v1, v2, v3, v4); - default: - return bm_edge_calc_rotate_beauty__angle(v1, v2, v3, v4); - } - } while (false); - - return FLT_MAX; -} - -/* -------------------------------------------------------------------- */ -/* Update the edge cost of rotation in the heap */ - -/* recalc an edge in the heap (surrounding geometry has changed) */ -static void bm_edge_update_beauty_cost_single(BMEdge *e, Heap *eheap, HeapNode **eheap_table, GSet **edge_state_arr, - const short flag, const short method) -{ - if (BM_elem_flag_test(e, BM_ELEM_TAG)) { - const int i = BM_elem_index_get(e); - GSet *e_state_set = edge_state_arr[i]; - - if (eheap_table[i]) { - BLI_heap_remove(eheap, eheap_table[i]); - eheap_table[i] = NULL; - } - - /* check if we can add it back */ - BLI_assert(BM_edge_is_manifold(e) == true); - //BLI_assert(BMO_elem_flag_test(bm, e->l->f, FACE_MARK) && - // BMO_elem_flag_test(bm, e->l->radial_next->f, FACE_MARK)); - - /* check we're not moving back into a state we have been in before */ - if (e_state_set != NULL) { - EdRotState e_state_alt; - erot_state_alternate(e, &e_state_alt); - if (BLI_gset_haskey(e_state_set, (void *)&e_state_alt)) { - // printf(" skipping, we already have this state\n"); - return; - } - } - - { - /* recalculate edge */ - const float cost = bm_edge_calc_rotate_beauty(e, flag, method); - if (cost < 0.0f) { - eheap_table[i] = BLI_heap_insert(eheap, cost, e); - } - else { - eheap_table[i] = NULL; - } - } - } -} - -/* we have rotated an edge, tag other edges and clear this one */ -static void bm_edge_update_beauty_cost(BMEdge *e, Heap *eheap, HeapNode **eheap_table, GSet **edge_state_arr, - const short flag, const short method) -{ - BMLoop *l; - BLI_assert(e->l->f->len == 3 && - e->l->radial_next->f->len == 3); - - l = e->l; - bm_edge_update_beauty_cost_single(l->next->e, eheap, eheap_table, edge_state_arr, flag, method); - bm_edge_update_beauty_cost_single(l->prev->e, eheap, eheap_table, edge_state_arr, flag, method); - l = l->radial_next; - bm_edge_update_beauty_cost_single(l->next->e, eheap, eheap_table, edge_state_arr, flag, method); - bm_edge_update_beauty_cost_single(l->prev->e, eheap, eheap_table, edge_state_arr, flag, method); -} - -/* -------------------------------------------------------------------- */ -/* Beautify Fill */ - #define ELE_NEW 1 #define FACE_MARK 2 -/** - * \note All edges in \a edge_array must be tagged and - * have their index values set according to their position in the array. - */ -static void bm_mesh_beautify_fill(BMesh *bm, BMEdge **edge_array, const int edge_array_len, - const short flag, const short method) -{ - Heap *eheap; /* edge heap */ - HeapNode **eheap_table; /* edge index aligned table pointing to the eheap */ - - GSet **edge_state_arr = MEM_callocN((size_t)edge_array_len * sizeof(GSet *), __func__); - BLI_mempool *edge_state_pool = BLI_mempool_create(sizeof(EdRotState), 512, 512, BLI_MEMPOOL_SYSMALLOC); - int i; - -#ifdef DEBUG_TIME - TIMEIT_START(beautify_fill); -#endif - - eheap = BLI_heap_new_ex((unsigned int)edge_array_len); - eheap_table = MEM_mallocN(sizeof(HeapNode *) * (size_t)edge_array_len, __func__); - - /* build heap */ - for (i = 0; i < edge_array_len; i++) { - BMEdge *e = edge_array[i]; - const float cost = bm_edge_calc_rotate_beauty(e, flag, method); - if (cost < 0.0f) { - eheap_table[i] = BLI_heap_insert(eheap, cost, e); - } - else { - eheap_table[i] = NULL; - } - } - - while (BLI_heap_is_empty(eheap) == false) { - BMEdge *e = BLI_heap_popmin(eheap); - i = BM_elem_index_get(e); - eheap_table[i] = NULL; - - e = BM_edge_rotate(bm, e, false, BM_EDGEROT_CHECK_EXISTS); - if (LIKELY(e)) { - GSet *e_state_set = edge_state_arr[i]; - - /* add the new state into the set so we don't move into this state again - * note: we could add the previous state too but this isn't essential) - * for avoiding eternal loops */ - EdRotState *e_state = BLI_mempool_alloc(edge_state_pool); - erot_state_current(e, e_state); - if (UNLIKELY(e_state_set == NULL)) { - edge_state_arr[i] = e_state_set = erot_gset_new(); /* store previous state */ - } - BLI_assert(BLI_gset_haskey(e_state_set, (void *)e_state) == false); - BLI_gset_insert(e_state_set, e_state); - - - // printf(" %d -> %d, %d\n", i, BM_elem_index_get(e->v1), BM_elem_index_get(e->v2)); - - /* maintain the index array */ - edge_array[i] = e; - BM_elem_index_set(e, i); - - /* recalculate faces connected on the heap */ - bm_edge_update_beauty_cost(e, eheap, eheap_table, edge_state_arr, flag, method); - - /* update flags */ - BMO_elem_flag_enable(bm, e, ELE_NEW); - BMO_elem_flag_enable(bm, e->l->f, FACE_MARK | ELE_NEW); - BMO_elem_flag_enable(bm, e->l->radial_next->f, FACE_MARK | ELE_NEW); - } - } - - BLI_heap_free(eheap, NULL); - MEM_freeN(eheap_table); - - for (i = 0; i < edge_array_len; i++) { - if (edge_state_arr[i]) { - BLI_gset_free(edge_state_arr[i], NULL); - } - } - - MEM_freeN(edge_state_arr); - BLI_mempool_destroy(edge_state_pool); - -#ifdef DEBUG_TIME - TIMEIT_END(beautify_fill); -#endif -} - - void bmo_beautify_fill_exec(BMesh *bm, BMOperator *op) { BMIter iter; @@ -486,9 +79,10 @@ void bmo_beautify_fill_exec(BMesh *bm, BMOperator *op) } bm->elem_index_dirty |= BM_EDGE; - bm_mesh_beautify_fill(bm, edge_array, edge_array_len, flag, method); + BM_mesh_beautify_fill(bm, edge_array, edge_array_len, flag, method, ELE_NEW, FACE_MARK | ELE_NEW); MEM_freeN(edge_array); BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_EDGE | BM_FACE, ELE_NEW); } + diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c index eef470e0d85..4eec15d4d7e 100644 --- a/source/blender/bmesh/operators/bmo_bevel.c +++ b/source/blender/bmesh/operators/bmo_bevel.c @@ -35,9 +35,10 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) { - const float offset = BMO_slot_float_get(op->slots_in, "offset"); - const int seg = BMO_slot_int_get(op->slots_in, "segments"); - const bool vonly = BMO_slot_bool_get(op->slots_in, "vertex_only"); + const float offset = BMO_slot_float_get(op->slots_in, "offset"); + const int offset_type = BMO_slot_int_get(op->slots_in, "offset_type"); + const int seg = BMO_slot_int_get(op->slots_in, "segments"); + const bool vonly = BMO_slot_bool_get(op->slots_in, "vertex_only"); if (offset > 0) { BMOIter siter; @@ -58,7 +59,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) } } - BM_mesh_bevel(bm, offset, seg, vonly, false, false, NULL, -1); + BM_mesh_bevel(bm, offset, offset_type, seg, vonly, false, false, NULL, -1); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG); } diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c index cf36e88ea98..ae645b97874 100644 --- a/source/blender/bmesh/operators/bmo_dissolve.c +++ b/source/blender/bmesh/operators/bmo_dissolve.c @@ -440,13 +440,18 @@ void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op) BMO_error_raise(bm, op, BMERR_DISSOLVEVERTS_FAILED, msg); } - /* clean up any remainin */ - BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) { + /* clean up any remaining */ + /* note: don't use BM_ITER_MESH_MUTABLE here, even though vertices are removed (T37559) */ + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BMO_elem_flag_test(bm, v, VERT_MARK)) { if (!BM_vert_dissolve(bm, v)) { BMO_error_raise(bm, op, BMERR_DISSOLVEVERTS_FAILED, NULL); return; } +#ifdef DEBUG + /* workaround debug assert */ + iter.count = bm->totvert; +#endif } } diff --git a/source/blender/bmesh/operators/bmo_fill_grid.c b/source/blender/bmesh/operators/bmo_fill_grid.c index a4b1237bc5d..50d25202f7e 100644 --- a/source/blender/bmesh/operators/bmo_fill_grid.c +++ b/source/blender/bmesh/operators/bmo_fill_grid.c @@ -142,11 +142,11 @@ static void bm_loop_pair_from_verts(BMVert *v_a, BMVert *v_b, static void bm_loop_pair_test_copy(BMLoop *l_pair_a[2], BMLoop *l_pair_b[2]) { /* if the first one is set, we know the second is too */ - if (l_pair_a[0] && l_pair_b[0] == NULL) { + if (l_pair_a[0] && l_pair_b[0] == NULL) { l_pair_b[0] = l_pair_a[1]; l_pair_b[1] = l_pair_a[0]; } - else if (l_pair_b[0] && l_pair_a[0] == NULL) { + else if (l_pair_b[0] && l_pair_a[0] == NULL) { l_pair_a[0] = l_pair_b[1]; l_pair_a[1] = l_pair_b[0]; } @@ -633,7 +633,12 @@ void bmo_grid_fill_exec(BMesh *bm, BMOperator *op) goto cleanup; } - BM_mesh_edgeloops_find_path(bm, &eloops_rail, bm_edge_test_rail_cb, (void *)bm, v_a_first, v_b_last); + /* We may find a first path, but not a second one! See geometry attached to bug [#37388]. */ + if (BM_mesh_edgeloops_find_path(bm, &eloops_rail, bm_edge_test_rail_cb, bm, v_a_first, v_b_last) == false) { + BMO_error_raise(bm, op, BMERR_INVALID_SELECTION, + "Loops are not connected by wire/boundary edges"); + goto cleanup; + } /* Check flipping by comparing path length */ estore_rail_a = eloops_rail.first; @@ -656,7 +661,7 @@ void bmo_grid_fill_exec(BMesh *bm, BMOperator *op) BM_edgeloop_free(estore_rail_a); estore_rail_a = estore_rail_b; - /* reverse so these so both are sorted the same way */ + /* reverse so both are sorted the same way */ BM_edgeloop_flip(bm, estore_b); SWAP(BMVert *, v_b_first, v_b_last); diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c index ca45289520b..a1de265bc56 100644 --- a/source/blender/bmesh/operators/bmo_triangulate.c +++ b/source/blender/bmesh/operators/bmo_triangulate.c @@ -42,13 +42,15 @@ void bmo_triangulate_exec(BMesh *bm, BMOperator *op) { - const bool use_beauty = BMO_slot_bool_get(op->slots_in, "use_beauty"); + const int quad_method = BMO_slot_int_get(op->slots_in, "quad_method"); + const int ngon_method = BMO_slot_int_get(op->slots_in, "ngon_method"); + BMOpSlot *slot_facemap_out = BMO_slot_get(op->slots_out, "face_map.out"); BM_mesh_elem_hflag_disable_all(bm, BM_FACE | BM_EDGE, BM_ELEM_TAG, false); BMO_slot_buffer_hflag_enable(bm, op->slots_in, "faces", BM_FACE, BM_ELEM_TAG, false); - BM_mesh_triangulate(bm, use_beauty, true, op, slot_facemap_out); + BM_mesh_triangulate(bm, quad_method, ngon_method, true, op, slot_facemap_out); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_TAG); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG); diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index c89fee71cbc..600386893dd 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -145,19 +145,23 @@ void bmo_rotate_edges_exec(BMesh *bm, BMOperator *op) BMO_elem_flag_test(bm, fb, FACE_TAINT) == false) { + /* don't touch again (faces will be freed so run before rotating the edge) */ + BMO_elem_flag_enable(bm, fa, FACE_TAINT); + BMO_elem_flag_enable(bm, fb, FACE_TAINT); + if (!(e2 = BM_edge_rotate(bm, e, use_ccw, check_flag))) { + + BMO_elem_flag_disable(bm, fa, FACE_TAINT); + BMO_elem_flag_disable(bm, fb, FACE_TAINT); #if 0 BMO_error_raise(bm, op, BMERR_INVALID_SELECTION, "Could not rotate edge"); return; #endif + continue; } BMO_elem_flag_enable(bm, e2, EDGE_OUT); - - /* don't touch again */ - BMO_elem_flag_enable(bm, fa, FACE_TAINT); - BMO_elem_flag_enable(bm, fb, FACE_TAINT); } } } diff --git a/source/blender/bmesh/operators/bmo_wireframe.c b/source/blender/bmesh/operators/bmo_wireframe.c index 2e5db5210c4..94b35426e2b 100644 --- a/source/blender/bmesh/operators/bmo_wireframe.c +++ b/source/blender/bmesh/operators/bmo_wireframe.c @@ -172,9 +172,9 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op) BMIter itersub; /* filled only with boundary verts */ - BMVert **verts_src = MEM_mallocN(sizeof(BMVert **) * totvert_orig, __func__); - BMVert **verts_neg = MEM_mallocN(sizeof(BMVert **) * totvert_orig, __func__); - BMVert **verts_pos = MEM_mallocN(sizeof(BMVert **) * totvert_orig, __func__); + BMVert **verts_src = MEM_mallocN(sizeof(BMVert *) * totvert_orig, __func__); + BMVert **verts_neg = MEM_mallocN(sizeof(BMVert *) * totvert_orig, __func__); + BMVert **verts_pos = MEM_mallocN(sizeof(BMVert *) * totvert_orig, __func__); /* will over-alloc, but makes for easy lookups by index to keep aligned */ BMVert **verts_boundary = use_boundary ? @@ -210,7 +210,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op) } /* setup tags, all faces and verts will be tagged which will be duplicated */ - BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false); + BM_mesh_elem_hflag_disable_all(bm, BM_FACE | BM_EDGE, BM_ELEM_TAG, false); BMO_ITER (f_src, &oiter, op->slots_in, "faces", BM_FACE) { verts_loop_tot += f_src->len; diff --git a/source/blender/bmesh/tools/bmesh_beautify.c b/source/blender/bmesh/tools/bmesh_beautify.c new file mode 100644 index 00000000000..cad5e1beeff --- /dev/null +++ b/source/blender/bmesh/tools/bmesh_beautify.c @@ -0,0 +1,445 @@ +/* + * ***** 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): Joseph Eagar. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/bmesh/tools/bmesh_beautify.c + * \ingroup bmesh + * + * Beautify the mesh by rotating edges between triangles + * to more attractive positions until no more rotations can be made. + * + * In principle this is very simple however there is the possibility of + * going into an eternal loop where edges keep rotating. + * To avoid this - each edge stores a set of it previous + * states so as not to rotate back. + * + * TODO + * - Take face normals into account. + */ + +#include "BLI_math.h" +#include "BLI_heap.h" + +#include "MEM_guardedalloc.h" + +#include "bmesh.h" +#include "bmesh_beautify.h" /* own include */ + + +// #define DEBUG_TIME + +#ifdef DEBUG_TIME +# include "PIL_time.h" +# include "PIL_time_utildefines.h" +#endif + +/* -------------------------------------------------------------------- */ +/* GSet for edge rotation */ + +typedef struct EdRotState { + int v1, v2; /* edge vert, small -> large */ + int f1, f2; /* face vert, small -> large */ +} EdRotState; + +static unsigned int erot_gsetutil_hash(const void *ptr) +{ + const EdRotState *e_state = (const EdRotState *)ptr; + unsigned int + hash = BLI_ghashutil_inthash(SET_INT_IN_POINTER(e_state->v1)); + hash ^= BLI_ghashutil_inthash(SET_INT_IN_POINTER(e_state->v2)); + hash ^= BLI_ghashutil_inthash(SET_INT_IN_POINTER(e_state->f1)); + hash ^= BLI_ghashutil_inthash(SET_INT_IN_POINTER(e_state->f2)); + return hash; +} +static int erot_gsetutil_cmp(const void *a, const void *b) +{ + const EdRotState *e_state_a = (const EdRotState *)a; + const EdRotState *e_state_b = (const EdRotState *)b; + if (e_state_a->v1 < e_state_b->v1) return -1; + else if (e_state_a->v1 > e_state_b->v1) return 1; + else if (e_state_a->v2 < e_state_b->v2) return -1; + else if (e_state_a->v2 > e_state_b->v2) return 1; + else if (e_state_a->f1 < e_state_b->f1) return -1; + else if (e_state_a->f1 > e_state_b->f1) return 1; + else if (e_state_a->f2 < e_state_b->f2) return -1; + else if (e_state_a->f2 > e_state_b->f2) return 1; + else return 0; +} + +static GSet *erot_gset_new(void) +{ + return BLI_gset_new(erot_gsetutil_hash, erot_gsetutil_cmp, __func__); +} + +/* ensure v0 is smaller */ +#define EDGE_ORD(v0, v1) \ + if (v0 > v1) { \ + v0 ^= v1; \ + v1 ^= v0; \ + v0 ^= v1; \ + } (void)0 + +static void erot_state_ex(const BMEdge *e, int v_index[2], int f_index[2]) +{ + BLI_assert(BM_edge_is_manifold((BMEdge *)e)); + BLI_assert(BM_vert_in_edge(e, e->l->prev->v) == false); + BLI_assert(BM_vert_in_edge(e, e->l->radial_next->prev->v) == false); + + /* verts of the edge */ + v_index[0] = BM_elem_index_get(e->v1); + v_index[1] = BM_elem_index_get(e->v2); + EDGE_ORD(v_index[0], v_index[1]); + + /* verts of each of the 2 faces attached to this edge + * (that are not apart of this edge) */ + f_index[0] = BM_elem_index_get(e->l->prev->v); + f_index[1] = BM_elem_index_get(e->l->radial_next->prev->v); + EDGE_ORD(f_index[0], f_index[1]); +} + +static void erot_state_current(const BMEdge *e, EdRotState *e_state) +{ + erot_state_ex(e, &e_state->v1, &e_state->f1); +} + +static void erot_state_alternate(const BMEdge *e, EdRotState *e_state) +{ + erot_state_ex(e, &e_state->f1, &e_state->v1); +} + +/* -------------------------------------------------------------------- */ +/* Calculate the improvement of rotating the edge */ + +/** + * \return a negative value means the edge can be rotated. + */ +static float bm_edge_calc_rotate_beauty__area( + const float v1[3], const float v2[3], const float v3[3], const float v4[3]) +{ + /* not a loop (only to be able to break out) */ + do { + float v1_xy[2], v2_xy[2], v3_xy[2], v4_xy[2]; + + /* first get the 2d values */ + { + bool is_zero_a, is_zero_b; + float no[3]; + float axis_mat[3][3]; + + // printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f); + BLI_assert((ELEM3(v1, v2, v3, v4) == false) && + (ELEM3(v2, v1, v3, v4) == false) && + (ELEM3(v3, v1, v2, v4) == false) && + (ELEM3(v4, v1, v2, v3) == false)); + + is_zero_a = area_tri_v3(v2, v3, v4) <= FLT_EPSILON; + is_zero_b = area_tri_v3(v2, v4, v1) <= FLT_EPSILON; + + if (LIKELY(is_zero_a == false && is_zero_b == false)) { + float no_a[3], no_b[3]; + normal_tri_v3(no_a, v2, v3, v4); /* a */ + normal_tri_v3(no_b, v2, v4, v1); /* b */ + add_v3_v3v3(no, no_a, no_b); + if (UNLIKELY(normalize_v3(no) <= FLT_EPSILON)) { + break; + } + } + else if (is_zero_a == false) { + normal_tri_v3(no, v2, v3, v4); /* a */ + } + else if (is_zero_b == false) { + normal_tri_v3(no, v2, v4, v1); /* b */ + } + else { + /* both zero area, no useful normal can be calculated */ + break; + } + + // { float a = angle_normalized_v3v3(no_a, no_b); printf("~ %.7f\n", a); fflush(stdout);} + + axis_dominant_v3_to_m3(axis_mat, no); + mul_v2_m3v3(v1_xy, axis_mat, v1); + mul_v2_m3v3(v2_xy, axis_mat, v2); + mul_v2_m3v3(v3_xy, axis_mat, v3); + mul_v2_m3v3(v4_xy, axis_mat, v4); + } + + // printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f); + + if (is_quad_convex_v2(v1_xy, v2_xy, v3_xy, v4_xy)) { + /* testing rule: the area divided by the perimeter, + * check if (1-3) beats the existing (2-4) edge rotation */ + float area_a, area_b; + float prim_a, prim_b; + float fac_24, fac_13; + + float len_12, len_23, len_34, len_41, len_24, len_13; + + /* edges around the quad */ + len_12 = len_v2v2(v1_xy, v2_xy); + len_23 = len_v2v2(v2_xy, v3_xy); + len_34 = len_v2v2(v3_xy, v4_xy); + len_41 = len_v2v2(v4_xy, v1_xy); + /* edges crossing the quad interior */ + len_13 = len_v2v2(v1_xy, v3_xy); + len_24 = len_v2v2(v2_xy, v4_xy); + + /* edge (2-4), current state */ + area_a = area_tri_v2(v2_xy, v3_xy, v4_xy); + area_b = area_tri_v2(v2_xy, v4_xy, v1_xy); + prim_a = len_23 + len_34 + len_24; + prim_b = len_24 + len_41 + len_12; + fac_24 = (area_a / prim_a) + (area_b / prim_b); + + /* edge (1-3), new state */ + area_a = area_tri_v2(v1_xy, v2_xy, v3_xy); + area_b = area_tri_v2(v1_xy, v3_xy, v4_xy); + prim_a = len_12 + len_23 + len_13; + prim_b = len_34 + len_41 + len_13; + fac_13 = (area_a / prim_a) + (area_b / prim_b); + + /* negative number if (1-3) is an improved state */ + return fac_24 - fac_13; + } + } while (false); + + return FLT_MAX; +} + +static float bm_edge_calc_rotate_beauty__angle( + const float v1[3], const float v2[3], const float v3[3], const float v4[3]) +{ + /* not a loop (only to be able to break out) */ + do { + float no_a[3], no_b[3]; + float angle_24, angle_13; + + /* edge (2-4), current state */ + normal_tri_v3(no_a, v2, v3, v4); + normal_tri_v3(no_b, v2, v4, v1); + angle_24 = angle_normalized_v3v3(no_a, no_b); + + /* edge (1-3), new state */ + /* only check new state for degenerate outcome */ + if ((normal_tri_v3(no_a, v1, v2, v3) == 0.0f) || + (normal_tri_v3(no_b, v1, v3, v4) == 0.0f)) + { + break; + } + angle_13 = angle_normalized_v3v3(no_a, no_b); + + return angle_13 - angle_24; + } while (false); + + return FLT_MAX; +} + +float BM_verts_calc_rotate_beauty( +const BMVert *v1, const BMVert *v2, const BMVert *v3, const BMVert *v4, const short flag, const short method) +{ + /* not a loop (only to be able to break out) */ + do { + if (flag & VERT_RESTRICT_TAG) { + const BMVert *v_a = v1, *v_b = v3; + if (BM_elem_flag_test(v_a, BM_ELEM_TAG) == BM_elem_flag_test(v_b, BM_ELEM_TAG)) { + break; + } + } + + if (UNLIKELY(v1 == v3)) { + // printf("This should never happen, but does sometimes!\n"); + break; + } + + switch (method) { + case 0: + return bm_edge_calc_rotate_beauty__area(v1->co, v2->co, v3->co, v4->co); + default: + return bm_edge_calc_rotate_beauty__angle(v1->co, v2->co, v3->co, v4->co); + } + } while (false); + + return FLT_MAX; +} + +static float bm_edge_calc_rotate_beauty(const BMEdge *e, const short flag, const short method) +{ + const BMVert *v1, *v2, *v3, *v4; + v1 = e->l->prev->v; /* first vert co */ + v2 = e->l->v; /* e->v1 or e->v2*/ + v3 = e->l->radial_next->prev->v; /* second vert co */ + v4 = e->l->next->v; /* e->v1 or e->v2*/ + + return BM_verts_calc_rotate_beauty(v1, v2, v3, v4, flag, method); +} + +/* -------------------------------------------------------------------- */ +/* Update the edge cost of rotation in the heap */ + +/* recalc an edge in the heap (surrounding geometry has changed) */ +static void bm_edge_update_beauty_cost_single(BMEdge *e, Heap *eheap, HeapNode **eheap_table, GSet **edge_state_arr, + const short flag, const short method) +{ + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + const int i = BM_elem_index_get(e); + GSet *e_state_set = edge_state_arr[i]; + + if (eheap_table[i]) { + BLI_heap_remove(eheap, eheap_table[i]); + eheap_table[i] = NULL; + } + + /* check if we can add it back */ + BLI_assert(BM_edge_is_manifold(e) == true); + + /* check we're not moving back into a state we have been in before */ + if (e_state_set != NULL) { + EdRotState e_state_alt; + erot_state_alternate(e, &e_state_alt); + if (BLI_gset_haskey(e_state_set, (void *)&e_state_alt)) { + // printf(" skipping, we already have this state\n"); + return; + } + } + + { + /* recalculate edge */ + const float cost = bm_edge_calc_rotate_beauty(e, flag, method); + if (cost < 0.0f) { + eheap_table[i] = BLI_heap_insert(eheap, cost, e); + } + else { + eheap_table[i] = NULL; + } + } + } +} + +/* we have rotated an edge, tag other edges and clear this one */ +static void bm_edge_update_beauty_cost(BMEdge *e, Heap *eheap, HeapNode **eheap_table, GSet **edge_state_arr, + const short flag, const short method) +{ + BMLoop *l; + BLI_assert(e->l->f->len == 3 && + e->l->radial_next->f->len == 3); + + l = e->l; + bm_edge_update_beauty_cost_single(l->next->e, eheap, eheap_table, edge_state_arr, flag, method); + bm_edge_update_beauty_cost_single(l->prev->e, eheap, eheap_table, edge_state_arr, flag, method); + l = l->radial_next; + bm_edge_update_beauty_cost_single(l->next->e, eheap, eheap_table, edge_state_arr, flag, method); + bm_edge_update_beauty_cost_single(l->prev->e, eheap, eheap_table, edge_state_arr, flag, method); +} + +/* -------------------------------------------------------------------- */ +/* Beautify Fill */ + +/** + * \note All edges in \a edge_array must be tagged and + * have their index values set according to their position in the array. + */ +void BM_mesh_beautify_fill(BMesh *bm, BMEdge **edge_array, const int edge_array_len, + const short flag, const short method, + const short oflag_edge, const short oflag_face) +{ + Heap *eheap; /* edge heap */ + HeapNode **eheap_table; /* edge index aligned table pointing to the eheap */ + + GSet **edge_state_arr = MEM_callocN((size_t)edge_array_len * sizeof(GSet *), __func__); + BLI_mempool *edge_state_pool = BLI_mempool_create(sizeof(EdRotState), 512, 512, BLI_MEMPOOL_SYSMALLOC); + int i; + +#ifdef DEBUG_TIME + TIMEIT_START(beautify_fill); +#endif + + eheap = BLI_heap_new_ex((unsigned int)edge_array_len); + eheap_table = MEM_mallocN(sizeof(HeapNode *) * (size_t)edge_array_len, __func__); + + /* build heap */ + for (i = 0; i < edge_array_len; i++) { + BMEdge *e = edge_array[i]; + const float cost = bm_edge_calc_rotate_beauty(e, flag, method); + if (cost < 0.0f) { + eheap_table[i] = BLI_heap_insert(eheap, cost, e); + } + else { + eheap_table[i] = NULL; + } + } + + while (BLI_heap_is_empty(eheap) == false) { + BMEdge *e = BLI_heap_popmin(eheap); + i = BM_elem_index_get(e); + eheap_table[i] = NULL; + + e = BM_edge_rotate(bm, e, false, BM_EDGEROT_CHECK_EXISTS); + if (LIKELY(e)) { + GSet *e_state_set = edge_state_arr[i]; + + /* add the new state into the set so we don't move into this state again + * note: we could add the previous state too but this isn't essential) + * for avoiding eternal loops */ + EdRotState *e_state = BLI_mempool_alloc(edge_state_pool); + erot_state_current(e, e_state); + if (UNLIKELY(e_state_set == NULL)) { + edge_state_arr[i] = e_state_set = erot_gset_new(); /* store previous state */ + } + BLI_assert(BLI_gset_haskey(e_state_set, (void *)e_state) == false); + BLI_gset_insert(e_state_set, e_state); + + + // printf(" %d -> %d, %d\n", i, BM_elem_index_get(e->v1), BM_elem_index_get(e->v2)); + + /* maintain the index array */ + edge_array[i] = e; + BM_elem_index_set(e, i); + + /* recalculate faces connected on the heap */ + bm_edge_update_beauty_cost(e, eheap, eheap_table, edge_state_arr, flag, method); + + /* update flags */ + if (oflag_edge) + BMO_elem_flag_enable(bm, e, oflag_edge); + if (oflag_face) { + BMO_elem_flag_enable(bm, e->l->f, oflag_face); + BMO_elem_flag_enable(bm, e->l->radial_next->f, oflag_face); + } + } + } + + BLI_heap_free(eheap, NULL); + MEM_freeN(eheap_table); + + for (i = 0; i < edge_array_len; i++) { + if (edge_state_arr[i]) { + BLI_gset_free(edge_state_arr[i], NULL); + } + } + + MEM_freeN(edge_state_arr); + BLI_mempool_destroy(edge_state_pool); + +#ifdef DEBUG_TIME + TIMEIT_END(beautify_fill); +#endif +} + diff --git a/source/blender/bmesh/tools/bmesh_beautify.h b/source/blender/bmesh/tools/bmesh_beautify.h new file mode 100644 index 00000000000..7cc17008b50 --- /dev/null +++ b/source/blender/bmesh/tools/bmesh_beautify.h @@ -0,0 +1,42 @@ +/* + * ***** 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): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BMESH_BEAUTIFY_H__ +#define __BMESH_BEAUTIFY_H__ + +/** \file blender/bmesh/tools/bmesh_beautify.h + * \ingroup bmesh + */ + +enum { + VERT_RESTRICT_TAG = (1 << 0), +}; + +void BM_mesh_beautify_fill(BMesh *bm, BMEdge **edge_array, const int edge_array_len, + const short flag, const short method, + const short oflag_edge, const short oflag_face); + +float BM_verts_calc_rotate_beauty(const BMVert *v1, const BMVert *v2, + const BMVert *v3, const BMVert *v4, + const short flag, const short method); + +#endif /* __BMESH_BEAUTIFY_H__ */ diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index bb3fe129e0b..5e68e468fb8 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -73,7 +73,8 @@ typedef struct EdgeHalf { struct BoundVert *leftv; /* left boundary vert (looking along edge to end) */ struct BoundVert *rightv; /* right boundary vert, if beveled */ int seg; /* how many segments for the bevel */ - float offset; /* offset for this edge */ + float offset_l; /* offset for this edge, on left side */ + float offset_r; /* offset for this edge, on right side */ bool is_bev; /* is this edge beveled? */ bool is_rev; /* is e->v2 the vertex at this end? */ bool is_seam; /* is e a seam for custom loopdata (e.g., UVs)? */ @@ -128,9 +129,11 @@ typedef struct BevelParams { MemArena *mem_arena; /* use for all allocs while bevel runs, if we need to free we can switch to mempool */ float offset; /* blender units to offset each side of a beveled edge */ + int offset_type; /* how offset is measured; enum defined in bmesh_operators.h */ int seg; /* number of segments in beveled edge profile */ bool vertex_only; /* bevel vertices only */ bool use_weights; /* bevel amount affected by weights on edges or verts */ + bool preserve_widths; /* should bevel prefer widths over angles, if forced to choose? */ const struct MDeformVert *dvert; /* vertex group array, maybe set if vertex_only */ int vertex_group; /* vertex group index, maybe set if vertex_only */ } BevelParams; @@ -206,6 +209,28 @@ static EdgeHalf *find_edge_half(BevVert *bv, BMEdge *bme) return NULL; } +/* find the BevVert corresponding to BMVert bmv */ +static BevVert *find_bevvert(BevelParams *bp, BMVert *bmv) +{ + return BLI_ghash_lookup(bp->vert_hash, bmv); +} + +/* Find the EdgeHalf representing the other end of e->e. + * That may not have been constructed yet, in which case return NULL. */ +static EdgeHalf *find_other_end_edge_half(BevelParams *bp, EdgeHalf *e) +{ + BevVert *bvother; + EdgeHalf *eother; + + bvother = find_bevvert(bp, e->is_rev ? e->e->v1 : e->e->v2); + if (bvother) { + eother = find_edge_half(bvother, e->e); + BLI_assert(eother != NULL); + return eother; + } + return NULL; +} + /* Return the next EdgeHalf after from_e that is beveled. * If from_e is NULL, find the first beveled edge. */ static EdgeHalf *next_bev(BevVert *bv, EdgeHalf *from_e) @@ -223,12 +248,6 @@ static EdgeHalf *next_bev(BevVert *bv, EdgeHalf *from_e) return NULL; } -/* find the BevVert corresponding to BMVert bmv */ -static BevVert *find_bevvert(BevelParams *bp, BMVert *bmv) -{ - return BLI_ghash_lookup(bp->vert_hash, bmv); -} - /* Return a good representative face (for materials, etc.) for faces * created around/near BoundVert v */ static BMFace *boundvert_rep_face(BoundVert *v) @@ -449,14 +468,12 @@ static void slide_dist(EdgeHalf *e, BMVert *v, float d, float slideco[3]) * Calculate the meeting point between the offset edges for e1 and e2, putting answer in meetco. * e1 and e2 share vertex v and face f (may be NULL) and viewed from the normal side of * the bevel vertex, e1 precedes e2 in CCW order. - * If on_right is true, offset edge is on right of both edges, where e1 enters v and - * e2 leave it. If on_right is false, then the offset edge is on the left. + * Offset edge is on right of both edges, where e1 enters v and e2 leave it. * When offsets are equal, the new point is on the edge bisector, with length offset/sin(angle/2), * but if the offsets are not equal (allowing for this, as bevel modifier has edge weights that may * lead to different offsets) then meeting point can be found be intersecting offset lines. */ -static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, - int on_right, float meetco[3]) +static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, float meetco[3]) { float dir1[3], dir2[3], norm_v[3], norm_perp1[3], norm_perp2[3], off1a[3], off1b[3], off2a[3], off2b[3], isect2[3], ang; @@ -469,7 +486,7 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, if (ang < 100.0f * BEVEL_EPSILON) { /* special case: e1 and e2 are parallel; put offset point perp to both, from v. * need to find a suitable plane. - * if offsets are different, we're out of luck: just use e1->offset */ + * if offsets are different, we're out of luck: just use e1->offset_r */ if (f) copy_v3_v3(norm_v, f->no); else @@ -477,26 +494,25 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, cross_v3_v3v3(norm_perp1, dir1, norm_v); normalize_v3(norm_perp1); copy_v3_v3(off1a, v->co); - madd_v3_v3fl(off1a, norm_perp1, e1->offset); + madd_v3_v3fl(off1a, norm_perp1, e1->offset_r); copy_v3_v3(meetco, off1a); } else if (fabsf(ang - (float)M_PI) < 100.0f * BEVEL_EPSILON) { /* special case e1 and e2 are antiparallel, so bevel is into * a zero-area face. Just make the offset point on the * common line, at offset distance from v. */ - slide_dist(e2, v, e2->offset, meetco); + slide_dist(e2, v, e2->offset_l, meetco); } else { - /* get normal to plane where meet point should be */ + /* Get normal to plane where meet point should be, + * using cross product instead of f->no in case f is non-planar. + * If e1-v-e2 is a reflex angle (viewed from vertex normal side), need to flip*/ cross_v3_v3v3(norm_v, dir2, dir1); normalize_v3(norm_v); - if (!on_right) + if (dot_v3v3(norm_v, v->no) < 0.0f) negate_v3(norm_v); /* get vectors perp to each edge, perp to norm_v, and pointing into face */ - if (f) { - copy_v3_v3(norm_v, f->no); - } cross_v3_v3v3(norm_perp1, dir1, norm_v); cross_v3_v3v3(norm_perp2, dir2, norm_v); normalize_v3(norm_perp1); @@ -504,10 +520,10 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, /* get points that are offset distances from each line, then another point on each line */ copy_v3_v3(off1a, v->co); - madd_v3_v3fl(off1a, norm_perp1, e1->offset); + madd_v3_v3fl(off1a, norm_perp1, e1->offset_r); add_v3_v3v3(off1b, off1a, dir1); copy_v3_v3(off2a, v->co); - madd_v3_v3fl(off2a, norm_perp2, e2->offset); + madd_v3_v3fl(off2a, norm_perp2, e2->offset_l); add_v3_v3v3(off2b, off2a, dir2); /* intersect the lines; by construction they should be on the same plane and not parallel */ @@ -520,19 +536,40 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, } } +/* Like offset_in_two planes, but for the case where we prefer to solve the problem + * of not meeting at the same point by choosing to change the bevel offset on one + * of the appropriate side of either e1 or e2, in order that the lines can meet on emid. */ +static void offset_on_edge_between(BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, + BMVert *v, float meetco[3]) +{ + BLI_assert(e1->is_bev && e2->is_bev && !emid->is_bev); + + /* If have to change offset of e1 or e2, which one? + * Prefer the one whose other end hasn't been constructed yet. + * Following will choose to change e2 if both have already been constructed. */ + if (find_other_end_edge_half(bp, e1)) { + offset_meet(e1, emid, v, e1->fnext, meetco); + /* now e2's left offset is probably different */ + e2->offset_l = dist_to_line_v3(meetco, v->co, BM_edge_other_vert(e2->e, v)->co); + } + else { + offset_meet(emid, e2, v, emid->fnext, meetco); + /* now e1's right offset is probably different */ + e1->offset_r = dist_to_line_v3(meetco, v->co, BM_edge_other_vert(e1->e, v)->co); + } +} + /* Like offset_meet, but with a mid edge between them that is used * to calculate the planes in which to run the offset lines. - * They may not meet exactly: the offsets for the edges may be different - * or both the planes and the lines may be angled so that they can't meet. + * They may not meet exactly: the lines may be angled so that they can't meet, + * probably because one or both faces is non-planar. * In that case, pick a close point on emid, which should be the dividing - * edge between the two planes. - * TODO: should have a global 'offset consistency' prepass to adjust offset - * widths so that all edges have the same offset at both ends. */ -static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, + * edge between the two planes. */ +static void offset_in_two_planes(BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, BMVert *v, float meetco[3]) { float dir1[3], dir2[3], dirmid[3], norm_perp1[3], norm_perp2[3], - off1a[3], off1b[3], off2a[3], off2b[3], isect2[3], co[3], + off1a[3], off1b[3], off2a[3], off2b[3], isect2[3], f1no[3], f2no[3], ang; int iret; @@ -545,6 +582,14 @@ static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, /* calculate face normals at corner in case faces are nonplanar */ cross_v3_v3v3(f1no, dirmid, dir1); cross_v3_v3v3(f2no, dirmid, dir2); + + /* if e1-v-emid or emid-v-e2 are reflex angles, need to flip corner normals */ + if (dot_v3v3(f1no, v->no) < 0.0f) + negate_v3(f1no); + if (dot_v3v3(f2no, v->no) < 0.0f) + negate_v3(f2no); + + /* get vectors perpendicular to e1 and e2, pointing into the proper faces */ cross_v3_v3v3(norm_perp1, dir1, f1no); normalize_v3(norm_perp1); cross_v3_v3v3(norm_perp2, dir2, f2no); @@ -552,19 +597,19 @@ static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, /* get points that are offset distances from each line, then another point on each line */ copy_v3_v3(off1a, v->co); - madd_v3_v3fl(off1a, norm_perp1, e1->offset); + madd_v3_v3fl(off1a, norm_perp1, e1->offset_r); sub_v3_v3v3(off1b, off1a, dir1); copy_v3_v3(off2a, v->co); - madd_v3_v3fl(off2a, norm_perp2, e2->offset); + madd_v3_v3fl(off2a, norm_perp2, e2->offset_l); add_v3_v3v3(off2b, off2a, dir2); ang = angle_v3v3(dir1, dir2); if (ang < 100.0f * BEVEL_EPSILON) { - /* lines are parallel; off1a is a good meet point */ - copy_v3_v3(meetco, off1a); + /* lines are parallel; put intersection on emid */ + offset_on_edge_between(bp, e1, e2, emid, v, meetco); } else if (fabsf(ang - (float)M_PI) < 100.0f * BEVEL_EPSILON) { - slide_dist(e2, v, e2->offset, meetco); + slide_dist(e2, v, e2->offset_l, meetco); } else { iret = isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2); @@ -573,11 +618,10 @@ static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, copy_v3_v3(meetco, off1a); } else if (iret == 2) { - /* lines are not coplanar; meetco and isect2 are nearest to first and second lines */ + /* lines are not coplanar and don't meet; meetco and isect2 are nearest to first and second lines */ if (len_v3v3(meetco, isect2) > 100.0f * BEVEL_EPSILON) { - /* offset lines don't meet: project average onto emid; this is not ideal (see TODO above) */ - mid_v3_v3v3(co, meetco, isect2); - closest_to_line_v3(meetco, co, v->co, BM_edge_other_vert(emid->e, v)->co); + /* offset lines don't meet so can't preserve widths; fallback on sliding along edge between */ + offset_on_edge_between(bp, e1, e2, emid, v, meetco); } } /* else iret == 1 and the lines are coplanar so meetco has the intersection */ @@ -612,7 +656,7 @@ static void offset_in_plane(EdgeHalf *e, const float plane_no[3], int left, floa cross_v3_v3v3(fdir, no, dir); normalize_v3(fdir); copy_v3_v3(r, v->co); - madd_v3_v3fl(r, fdir, e->offset); + madd_v3_v3fl(r, fdir, left? e->offset_l : e->offset_r); } /* Calculate the point on e where line (co_a, co_b) comes closest to and return it in projco */ @@ -818,7 +862,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv) v->efirst = v->elast = e; e->rightv = v; /* make artifical extra point along unbeveled edge, and form triangle */ - slide_dist(e->next, bv->v, e->offset, co); + slide_dist(e->next, bv->v, e->offset_l, co); v = add_new_bound_vert(mem_arena, vm, co); v->efirst = v->elast = e->next; e->next->leftv = e->next->rightv = v; @@ -828,14 +872,14 @@ static void build_boundary(BevelParams *bp, BevVert *bv) return; } - lastd = bp->vertex_only ? bv->offset : e->offset; + lastd = bp->vertex_only ? bv->offset : e->offset_l; vm->boundstart = NULL; do { if (e->is_bev) { /* handle only left side of beveled edge e here: next iteration should do right side */ if (e->prev->is_bev) { BLI_assert(e->prev != e); /* see: wire edge special case */ - offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co); + offset_meet(e->prev, e, bv->v, e->fprev, co); v = add_new_bound_vert(mem_arena, vm, co); v->efirst = e->prev; v->elast = v->ebev = e; @@ -847,7 +891,10 @@ static void build_boundary(BevelParams *bp, BevVert *bv) if (e->prev->prev->is_bev) { BLI_assert(e->prev->prev != e); /* see: edgecount 2, selcount 1 case */ /* find meet point between e->prev->prev and e and attach e->prev there */ - offset_in_two_planes(e->prev->prev, e, e->prev, bv->v, co); + if (bp->preserve_widths) + offset_in_two_planes(bp, e->prev->prev, e, e->prev, bv->v, co); + else + offset_on_edge_between(bp, e->prev->prev, e, e->prev, bv->v, co); v = add_new_bound_vert(mem_arena, vm, co); v->efirst = e->prev->prev; v->elast = v->ebev = e; @@ -857,7 +904,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv) } else { /* neither e->prev nor e->prev->prev are beveled: make on-edge on e->prev */ - offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co); + offset_meet(e->prev, e, bv->v, e->fprev, co); v = add_new_bound_vert(mem_arena, vm, co); v->efirst = e->prev; v->elast = v->ebev = e; @@ -875,7 +922,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv) } else if (e->prev->is_bev) { /* on-edge meet between e->prev and e */ - offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co); + offset_meet(e->prev, e, bv->v, e->fprev, co); v = add_new_bound_vert(mem_arena, vm, co); v->efirst = e->prev; v->elast = e; @@ -1921,6 +1968,19 @@ static void build_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv) } } +/* Return the angle between the two faces adjacent to e. + * If there are not two, return 0. */ +static float edge_face_angle(EdgeHalf *e) +{ + if (e->fprev && e->fnext) { + /* angle between faces is supplement of angle between face normals */ + return (float)M_PI - angle_normalized_v3v3(e->fprev->no, e->fnext->no); + } + else { + return 0.0f; + } +} + /* take care, this flag isn't cleared before use, it just so happens that its not set */ #define BM_BEVEL_EDGE_TAG_ENABLE(bme) BM_ELEM_API_FLAG_ENABLE( (bme), _FLAG_OVERLAP) #define BM_BEVEL_EDGE_TAG_DISABLE(bme) BM_ELEM_API_FLAG_DISABLE( (bme), _FLAG_OVERLAP) @@ -1936,8 +1996,8 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) BMEdge *bme2, *unflagged_bme, *first_bme; BMFace *f; BMIter iter, iter2; - EdgeHalf *e; - float weight; + EdgeHalf *e, *eother; + float weight, z; int i, found_shared_face, ccw_test_sum; int nsel = 0; int ntot = 0; @@ -2053,16 +2113,6 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) e->seg = 0; } e->is_rev = (bme->v2 == v); - if (e->is_bev) { - e->offset = bp->offset; - if (bp->use_weights) { - weight = BM_elem_float_data_get(&bm->edata, bme, CD_BWEIGHT); - e->offset *= weight; - } - } - else { - e->offset = 0.0f; - } } /* find wrap-around shared face */ BM_ITER_ELEM (f, &iter2, bme, BM_FACES_OF_EDGE) { @@ -2098,6 +2148,63 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) for (i = 0, e = bv->edges; i < ntot; i++, e++) { e->next = &bv->edges[(i + 1) % ntot]; e->prev = &bv->edges[(i + ntot - 1) % ntot]; + + /* set offsets */ + if (e->is_bev) { + /* Convert distance as specified by user into offsets along + * faces on left side and right side of this edgehalf. + * Except for percent method, offset will be same on each side. + * + * First check to see if other end has had construction made, + * because offset may have been forced to another number + * (but for percent method all 4 widths can be different). */ + + eother = find_other_end_edge_half(bp, e); + if (eother && bp->offset_type != BEVEL_AMT_PERCENT) { + e->offset_l = eother->offset_r; + e->offset_r = eother->offset_l; + } + else { + switch (bp->offset_type) { + case BEVEL_AMT_OFFSET: + e->offset_l = bp->offset; + break; + case BEVEL_AMT_WIDTH: + z = fabsf(2.0f * sinf(edge_face_angle(e) / 2.0f)); + if (z < BEVEL_EPSILON) + e->offset_l = 0.01f * bp->offset; /* undefined behavior, so tiny bevel */ + else + e->offset_l = bp->offset / z; + break; + case BEVEL_AMT_DEPTH: + z = fabsf(cosf(edge_face_angle(e) / 2.0f)); + if (z < BEVEL_EPSILON) + e->offset_l = 0.01f * bp->offset; /* undefined behavior, so tiny bevel */ + else + e->offset_l = bp->offset / z; + break; + case BEVEL_AMT_PERCENT: + e->offset_l = BM_edge_calc_length(e->prev->e) * bp->offset / 100.0f; + e->offset_r = BM_edge_calc_length(e->next->e) * bp->offset / 100.0f; + break; + default: + BLI_assert(!"bad bevel offset kind"); + e->offset_l = bp->offset; + break; + } + if (bp->offset_type != BEVEL_AMT_PERCENT) + e->offset_r = e->offset_l; + if (bp->use_weights) { + weight = BM_elem_float_data_get(&bm->edata, e->e, CD_BWEIGHT); + e->offset_l *= weight; + e->offset_r *= weight; + } + } + } + else { + e->offset_l = e->offset_r = 0.0f; + } + BM_BEVEL_EDGE_TAG_DISABLE(e->e); if (e->fprev && e->fnext) e->is_seam = !contig_ldata_across_edge(bm, e->e, e->fprev, e->fnext); @@ -2370,7 +2477,7 @@ static float bevel_limit_offset(BMesh *bm, BevelParams *bp) * * \warning all tagged edges _must_ be manifold. */ -void BM_mesh_bevel(BMesh *bm, const float offset, const float segments, +void BM_mesh_bevel(BMesh *bm, const float offset, const int offset_type, const float segments, const bool vertex_only, const bool use_weights, const bool limit_offset, const struct MDeformVert *dvert, const int vertex_group) { @@ -2380,9 +2487,11 @@ void BM_mesh_bevel(BMesh *bm, const float offset, const float segments, BevelParams bp = {NULL}; bp.offset = offset; + bp.offset_type = offset_type; bp.seg = segments; bp.vertex_only = vertex_only; bp.use_weights = use_weights; + bp.preserve_widths = false; bp.dvert = dvert; bp.vertex_group = vertex_group; diff --git a/source/blender/bmesh/tools/bmesh_bevel.h b/source/blender/bmesh/tools/bmesh_bevel.h index bee26357aca..9897b6b070c 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.h +++ b/source/blender/bmesh/tools/bmesh_bevel.h @@ -29,7 +29,7 @@ struct MDeformVert; -void BM_mesh_bevel(BMesh *bm, const float offset, const float segments, +void BM_mesh_bevel(BMesh *bm, const float offset, const int offset_type, const float segments, const bool vertex_only, const bool use_weights, const bool limit_offset, const struct MDeformVert *dvert, const int vertex_group); diff --git a/source/blender/bmesh/tools/bmesh_bisect_plane.c b/source/blender/bmesh/tools/bmesh_bisect_plane.c index 9cfe17d6413..6aeb26435ac 100644 --- a/source/blender/bmesh/tools/bmesh_bisect_plane.c +++ b/source/blender/bmesh/tools/bmesh_bisect_plane.c @@ -300,31 +300,26 @@ void BM_mesh_bisect_plane(BMesh *bm, float plane[4], BMIter iter; - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - vert_is_center_disable(v); - - BM_VERT_DIR(v) = plane_point_test_v3(plane, v->co, eps, &(BM_VERT_DIST(v))); - if (BM_VERT_DIR(v) == 0) { - if (oflag_center) { - BMO_elem_flag_enable(bm, v, oflag_center); - } - if (use_snap_center) { - closest_to_plane_v3(v->co, plane, v->co); - } - } - } - if (use_tag) { /* build tagged edge array */ BMEdge *e; einput_len = 0; + + /* flush edge tags to verts */ + BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false); + /* keep face tags as is */ BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) { if (edge_is_cut_test(e)) { edges_arr[einput_len++] = e; + + /* flush edge tags to verts */ + BM_elem_flag_enable(e->v1, BM_ELEM_TAG); + BM_elem_flag_enable(e->v2, BM_ELEM_TAG); } } + /* face tags are set by caller */ } else { BMEdge *e; @@ -339,6 +334,32 @@ void BM_mesh_bisect_plane(BMesh *bm, float plane[4], } } + + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + + if (use_tag && !BM_elem_flag_test(v, BM_ELEM_TAG)) { + vert_is_center_disable(v); + + /* these should never be accessed */ + BM_VERT_DIR(v) = 0; + BM_VERT_DIST(v) = 0.0f; + + continue; + } + + vert_is_center_disable(v); + BM_VERT_DIR(v) = plane_point_test_v3(plane, v->co, eps, &(BM_VERT_DIST(v))); + + if (BM_VERT_DIR(v) == 0) { + if (oflag_center) { + BMO_elem_flag_enable(bm, v, oflag_center); + } + if (use_snap_center) { + closest_to_plane_v3(v->co, plane, v->co); + } + } + } + /* store a stack of faces to be evaluated for splitting */ BLI_LINKSTACK_INIT(face_stack); @@ -372,7 +393,7 @@ void BM_mesh_bisect_plane(BMesh *bm, float plane[4], BM_VERT_DIR(v_new) = 0; BM_VERT_DIST(v_new) = 0.0f; } - else { + else if (side[0] == 0 || side[1] == 0) { /* check if either edge verts are aligned, * if so - tag and push all faces that use it into the stack */ unsigned int j; @@ -394,6 +415,13 @@ void BM_mesh_bisect_plane(BMesh *bm, float plane[4], } } } + + /* if both verts are on the center - tag it */ + if (oflag_center) { + if (side[0] == 0 && side[1] == 0) { + BMO_elem_flag_enable(bm, e, oflag_center); + } + } } } diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c index 4b6835a81fe..99d46559ca5 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c +++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c @@ -390,10 +390,10 @@ static void bm_decim_triangulate_end(BMesh *bm) { /* decimation finished, now re-join */ BMIter iter; - BMEdge *e; + BMEdge *e, *e_next; /* boundary edges */ - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + BM_ITER_MESH_MUTABLE (e, e_next, &iter, bm, BM_EDGES_OF_MESH) { BMLoop *l_a, *l_b; if (BM_edge_loop_pair(e, &l_a, &l_b)) { const int l_a_index = BM_elem_index_get(l_a); diff --git a/source/blender/bmesh/tools/bmesh_triangulate.c b/source/blender/bmesh/tools/bmesh_triangulate.c index 34ff493a026..59c2aa4331d 100644 --- a/source/blender/bmesh/tools/bmesh_triangulate.c +++ b/source/blender/bmesh/tools/bmesh_triangulate.c @@ -42,14 +42,16 @@ /** * a version of #BM_face_triangulate that maps to #BMOpSlot */ -static void bm_face_triangulate_mapping(BMesh *bm, BMFace *face, MemArena *sf_arena, const bool use_beauty, const bool use_tag, +static void bm_face_triangulate_mapping(BMesh *bm, BMFace *face, MemArena *sf_arena, + const int quad_method, const int ngon_method, + const bool use_tag, BMOperator *op, BMOpSlot *slot_facemap_out) { const int faces_array_tot = face->len - 3; BMFace **faces_array = BLI_array_alloca(faces_array, faces_array_tot); BLI_assert(face->len > 3); - BM_face_triangulate(bm, face, faces_array, sf_arena, use_beauty, use_tag); + BM_face_triangulate(bm, face, faces_array, sf_arena, quad_method, ngon_method, use_tag); if (faces_array) { int i; @@ -61,7 +63,7 @@ static void bm_face_triangulate_mapping(BMesh *bm, BMFace *face, MemArena *sf_ar } -void BM_mesh_triangulate(BMesh *bm, const bool use_beauty, const bool tag_only, +void BM_mesh_triangulate(BMesh *bm, const int quad_method, const int ngon_method, const bool tag_only, BMOperator *op, BMOpSlot *slot_facemap_out) { BMIter iter; @@ -75,7 +77,7 @@ void BM_mesh_triangulate(BMesh *bm, const bool use_beauty, const bool tag_only, BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) { if (face->len > 3) { if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) { - bm_face_triangulate_mapping(bm, face, sf_arena, use_beauty, tag_only, + bm_face_triangulate_mapping(bm, face, sf_arena, quad_method, ngon_method, tag_only, op, slot_facemap_out); } } @@ -85,7 +87,7 @@ void BM_mesh_triangulate(BMesh *bm, const bool use_beauty, const bool tag_only, BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) { if (face->len > 3) { if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) { - BM_face_triangulate(bm, face, NULL, sf_arena, use_beauty, tag_only); + BM_face_triangulate(bm, face, NULL, sf_arena, quad_method, ngon_method, tag_only); } } } diff --git a/source/blender/bmesh/tools/bmesh_triangulate.h b/source/blender/bmesh/tools/bmesh_triangulate.h index 141aa2f82b4..550109ffef9 100644 --- a/source/blender/bmesh/tools/bmesh_triangulate.h +++ b/source/blender/bmesh/tools/bmesh_triangulate.h @@ -30,7 +30,7 @@ #ifndef __BMESH_TRIANGULATE_H__ #define __BMESH_TRIANGULATE_H__ -void BM_mesh_triangulate(BMesh *bm, const bool use_beauty, const bool tag_only, +void BM_mesh_triangulate(BMesh *bm, const int quad_method, const int ngon_method, const bool tag_only, BMOperator *op, BMOpSlot *slot_facemap_out); #endif /* __BMESH_TRIANGULATE_H__ */ diff --git a/source/blender/collada/AnimationExporter.h b/source/blender/collada/AnimationExporter.h index ea5fd203bea..60224151308 100644 --- a/source/blender/collada/AnimationExporter.h +++ b/source/blender/collada/AnimationExporter.h @@ -53,10 +53,6 @@ extern "C" #include "BIK_api.h" #include "BKE_global.h" #include "ED_object.h" - -#ifdef NAN_BUILDINFO -extern char build_rev[]; -#endif } #include "MEM_guardedalloc.h" diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index 5d47ce155c8..74db2082a00 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -701,7 +701,7 @@ void ArmatureImporter::make_shape_keys() //insert other shape keys for (int i = 0 ; i < morphTargetIds.getCount() ; i++ ) { - //better to have a seperate map of morph objects, + //better to have a separate map of morph objects, //This'll do for now since only mesh morphing is imported Mesh *me = this->mesh_importer->get_mesh_by_geom_uid(morphTargetIds[i]); diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index c03316e1fe5..ee0326d5804 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -101,7 +101,9 @@ extern "C" #include "ED_keyframing.h" #ifdef WITH_BUILDINFO -extern char build_rev[]; +extern char build_commit_date[]; +extern char build_commit_time[]; +extern char build_hash[]; #endif #include "MEM_guardedalloc.h" @@ -226,9 +228,12 @@ void DocumentExporter::exportCurrentScene(Scene *sce) } char version_buf[128]; #ifdef WITH_BUILDINFO - sprintf(version_buf, "Blender %d.%02d.%d r%s", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION, build_rev); + BLI_snprintf(version_buf, sizeof(version_buf), "Blender %d.%02d.%d commit date:%s, hash:", + BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION, + build_commit_date, build_commit_time, build_hash); #else - sprintf(version_buf, "Blender %d.%02d.%d", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION); + BLI_snprintf(version_buf, sizeof(version_buf), "Blender %d.%02d.%d", + BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION); #endif asset.getContributor().mAuthoringTool = version_buf; asset.add(); diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index 146aff5ca5b..2e805ce18f1 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -354,12 +354,14 @@ void bc_match_scale(std::vector<Object *> *objects_done, void bc_triangulate_mesh(Mesh *me) { - bool use_beauty = false; - bool tag_only = false; + bool use_beauty = false; + bool tag_only = false; + int quad_method = MOD_TRIANGULATE_QUAD_SHORTEDGE; /* XXX: The triangulation method selection could be offered in the UI */ BMesh *bm = BM_mesh_create(&bm_mesh_allocsize_default); BM_mesh_bm_from_me(bm, me, true, false, 0); - BM_mesh_triangulate(bm, use_beauty, tag_only, NULL, NULL); + BM_mesh_triangulate(bm, quad_method, use_beauty, tag_only, NULL, NULL); + BM_mesh_bm_to_me(bm, me, FALSE); BM_mesh_free(bm); } diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index e6a3c33ea5d..11add975db5 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -30,7 +30,6 @@ set(INC operations ../blenkernel ../blenlib - ../blenlib ../imbuf ../makesdna ../makesrna @@ -230,8 +229,6 @@ set(SRC nodes/COM_SetAlphaNode.h nodes/COM_ConvertAlphaNode.cpp nodes/COM_ConvertAlphaNode.h - nodes/COM_AlphaOverNode.cpp - nodes/COM_AlphaOverNode.h nodes/COM_HueSaturationValueNode.cpp nodes/COM_HueSaturationValueNode.h nodes/COM_HueSaturationValueCorrectNode.cpp diff --git a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp index 9516deee7e3..7def96d426e 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp @@ -45,7 +45,10 @@ void ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_star vector<Node *>& nodes = system.getNodes(); vector<SocketConnection *>& links = system.getConnections(); - bool is_active_group = (parent_key.value == system.getContext().getbNodeTree()->active_viewer_key.value); + const bNodeTree *basetree = system.getContext().getbNodeTree(); + /* update viewers in the active edittree as well the base tree (for backdrop) */ + bool is_active_group = ((parent_key.value == basetree->active_viewer_key.value) || + (tree == basetree)); /* add all nodes of the tree to the node list */ bNode *node = (bNode *)tree->nodes.first; diff --git a/source/blender/compositor/intern/COM_SocketReader.h b/source/blender/compositor/intern/COM_SocketReader.h index b7aae8b92f0..2168611d0c0 100644 --- a/source/blender/compositor/intern/COM_SocketReader.h +++ b/source/blender/compositor/intern/COM_SocketReader.h @@ -63,7 +63,7 @@ protected: * @param y the y-coordinate of the pixel to calculate in image space * @param inputBuffers chunks that can be read by their ReadBufferOperation. */ - virtual void executePixel(float output[4], float x, float y, PixelSampler sampler) {} + virtual void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) {} /** * @brief calculate a single pixel @@ -75,7 +75,7 @@ protected: * @param chunkData chunk specific data a during execution time. */ virtual void executePixel(float output[4], int x, int y, void *chunkData) { - executePixel(output, x, y, COM_PS_NEAREST); + executePixelSampled(output, x, y, COM_PS_NEAREST); } /** @@ -88,25 +88,25 @@ protected: * @param dy * @param inputBuffers chunks that can be read by their ReadBufferOperation. */ - virtual void executePixel(float output[4], float x, float y, float dx, float dy, PixelSampler sampler) {} + virtual void executePixelFiltered(float output[4], float x, float y, float dx, float dy, PixelSampler sampler) {} public: - inline void read(float result[4], float x, float y, PixelSampler sampler) { - executePixel(result, x, y, sampler); + inline void readSampled(float result[4], float x, float y, PixelSampler sampler) { + executePixelSampled(result, x, y, sampler); } inline void read(float result[4], int x, int y, void *chunkData) { executePixel(result, x, y, chunkData); } - inline void read(float result[4], float x, float y, float dx, float dy, PixelSampler sampler) { - executePixel(result, x, y, dx, dy, sampler); + inline void readFiltered(float result[4], float x, float y, float dx, float dy, PixelSampler sampler) { + executePixelFiltered(result, x, y, dx, dy, sampler); } virtual void *initializeTileData(rcti *rect) { return 0; } - virtual void deinitializeTileData(rcti *rect, void *data) { - } - - virtual MemoryBuffer *getInputMemoryBuffer(MemoryBuffer **memoryBuffers) { return 0; } + virtual void deinitializeTileData(rcti *rect, void *data) {} + virtual ~SocketReader() {} + + virtual MemoryBuffer *getInputMemoryBuffer(MemoryBuffer **memoryBuffers) { return 0; } inline const unsigned int getWidth() const { return this->m_width; } inline const unsigned int getHeight() const { return this->m_height; } diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp index 330e61e7fea..57e996fe3b2 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.cpp +++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp @@ -77,9 +77,9 @@ static bool g_openclInitialized = false; #define MAX_HIGHLIGHT 8 static bool g_highlightInitialized = false; extern "C" { -int g_highlightIndex; -void **g_highlightedNodes; -void **g_highlightedNodesRead; +static int g_highlightIndex; +static void **g_highlightedNodes; +static void **g_highlightedNodesRead; #if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE #define HIGHLIGHT(wp) \ diff --git a/source/blender/compositor/nodes/COM_BlurNode.cpp b/source/blender/compositor/nodes/COM_BlurNode.cpp index b59a92710bc..a8de2aed526 100644 --- a/source/blender/compositor/nodes/COM_BlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BlurNode.cpp @@ -53,6 +53,7 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co if (data->filtertype == R_FILTER_FAST_GAUSS) { FastGaussianBlurOperation *operationfgb = new FastGaussianBlurOperation(); operationfgb->setData(data); + operationfgb->setChunksize(context->getChunksize()); operationfgb->setbNode(editorNode); this->getInputSocket(1)->relinkConnections(operationfgb->getInputSocket(1), 1, graph); graph->addOperation(operationfgb); diff --git a/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp b/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp index 5578fdae54e..2b396fb9861 100644 --- a/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp @@ -43,25 +43,23 @@ void ColorBalanceNode::convertToOperations(ExecutionSystem *graph, CompositorCon NodeOperation *operation; if (node->custom1 == 0) { ColorBalanceLGGOperation *operationLGG = new ColorBalanceLGGOperation(); - { - int c; - - for (c = 0; c < 3; c++) { - n->lift_lgg[c] = 2.0f - n->lift[c]; - n->gamma_inv[c] = (n->gamma[c] != 0.0f) ? 1.0f / n->gamma[c] : 1000000.0f; - } + + float lift_lgg[3], gamma_inv[3]; + for (int c = 0; c < 3; c++) { + lift_lgg[c] = 2.0f - n->lift[c]; + gamma_inv[c] = (n->gamma[c] != 0.0f) ? 1.0f / n->gamma[c] : 1000000.0f; } - + operationLGG->setGain(n->gain); - operationLGG->setLift(n->lift_lgg); - operationLGG->setGammaInv(n->gamma_inv); + operationLGG->setLift(lift_lgg); + operationLGG->setGammaInv(gamma_inv); operation = operationLGG; } else { ColorBalanceASCCDLOperation *operationCDL = new ColorBalanceASCCDLOperation(); - operationCDL->setGain(n->gain); - operationCDL->setLift(n->lift); - operationCDL->setGamma(n->gamma); + operationCDL->setOffset(n->offset); + operationCDL->setPower(n->power); + operationCDL->setSlope(n->slope); operation = operationCDL; } diff --git a/source/blender/compositor/nodes/COM_DefocusNode.cpp b/source/blender/compositor/nodes/COM_DefocusNode.cpp index c2bd8997525..b6dd0e526ae 100644 --- a/source/blender/compositor/nodes/COM_DefocusNode.cpp +++ b/source/blender/compositor/nodes/COM_DefocusNode.cpp @@ -85,7 +85,7 @@ void DefocusNode::convertToOperations(ExecutionSystem *graph, CompositorContext BokehImageOperation *bokeh = new BokehImageOperation(); NodeBokehImage *bokehdata = new NodeBokehImage(); - bokehdata->angle = data->rotation; + bokehdata->angle = RAD2DEGF(data->rotation); bokehdata->rounding = 0.0f; bokehdata->flaps = data->bktype; if (data->bktype < 3) { diff --git a/source/blender/compositor/nodes/COM_DespeckleNode.cpp b/source/blender/compositor/nodes/COM_DespeckleNode.cpp index a97714c870e..9894dc7b9ac 100644 --- a/source/blender/compositor/nodes/COM_DespeckleNode.cpp +++ b/source/blender/compositor/nodes/COM_DespeckleNode.cpp @@ -39,7 +39,7 @@ void DespeckleNode::convertToOperations(ExecutionSystem *graph, CompositorContex operation->setbNode(editorNode); operation->setThreshold(editorNode->custom3); - operation->setThresholdNeighbour(editorNode->custom4); + operation->setThresholdNeighbor(editorNode->custom4); inputImageSocket->relinkConnections(operation->getInputSocket(0), 1, graph); inputSocket->relinkConnections(operation->getInputSocket(1), 0, graph); diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp index 6e4bff460d1..d595afe6a78 100644 --- a/source/blender/compositor/nodes/COM_ImageNode.cpp +++ b/source/blender/compositor/nodes/COM_ImageNode.cpp @@ -142,7 +142,17 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c /* without this, multilayer that fail to load will crash blender [#32490] */ if (is_multilayer_ok == false) { - convertToOperations_invalid(graph, context); + int index; + vector<OutputSocket *> &outputsockets = this->getOutputSockets(); + for (index = 0; index < outputsockets.size(); index++) { + const float warning_color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + SetColorOperation *operation = new SetColorOperation(); + operation->setChannels(warning_color); + + /* link the operation */ + this->getOutputSocket(index)->relinkConnections(operation->getOutputSocket()); + graph->addOperation(operation); + } } } else { diff --git a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp index 6cc9aae4553..d4103a61685 100644 --- a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp +++ b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp @@ -27,15 +27,15 @@ AlphaOverKeyOperation::AlphaOverKeyOperation() : MixBaseOperation() /* pass */ } -void AlphaOverKeyOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void AlphaOverKeyOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputOverColor[4]; float value[4]; - this->m_inputValueOperation->read(value, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputOverColor, x, y, sampler); + this->m_inputValueOperation->readSampled(value, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputOverColor, x, y, sampler); if (inputOverColor[3] <= 0.0f) { copy_v4_v4(output, inputColor1); diff --git a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h index 31b0422918a..eceee43e600 100644 --- a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h +++ b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h @@ -39,6 +39,6 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; #endif diff --git a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp index 111dc899e1d..1dba542e142 100644 --- a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp +++ b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp @@ -27,15 +27,15 @@ AlphaOverMixedOperation::AlphaOverMixedOperation() : MixBaseOperation() this->m_x = 0.0f; } -void AlphaOverMixedOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void AlphaOverMixedOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputOverColor[4]; float value[4]; - this->m_inputValueOperation->read(value, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputOverColor, x, y, sampler); + this->m_inputValueOperation->readSampled(value, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputOverColor, x, y, sampler); if (inputOverColor[3] <= 0.0f) { copy_v4_v4(output, inputColor1); diff --git a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h index 14e7325ec1d..ff6d1a978b8 100644 --- a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h +++ b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h @@ -41,7 +41,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void setX(float x) { this->m_x = x; } }; diff --git a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp index ac7906f2f98..60a2fd6a442 100644 --- a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp +++ b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp @@ -27,15 +27,15 @@ AlphaOverPremultiplyOperation::AlphaOverPremultiplyOperation() : MixBaseOperatio /* pass */ } -void AlphaOverPremultiplyOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void AlphaOverPremultiplyOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputOverColor[4]; float value[4]; - this->m_inputValueOperation->read(value, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputOverColor, x, y, sampler); + this->m_inputValueOperation->readSampled(value, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputOverColor, x, y, sampler); /* Zero alpha values should still permit an add of RGB data */ if (inputOverColor[3] < 0.0f) { diff --git a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h index 16bd2aeaeed..db68583baa6 100644 --- a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h +++ b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h @@ -39,7 +39,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; #endif diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp index cc91210a385..dfff2bfeafb 100644 --- a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp @@ -152,7 +152,7 @@ void BlurBaseOperation::updateSize() { if (!this->m_sizeavailable) { float result[4]; - this->getInputSocketReader(1)->read(result, 0, 0, COM_PS_NEAREST); + this->getInputSocketReader(1)->readSampled(result, 0, 0, COM_PS_NEAREST); this->m_size = result[0]; this->m_sizeavailable = true; } diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp index 1c91af2a7a3..7f17db1d31b 100644 --- a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp @@ -80,7 +80,7 @@ void BokehBlurOperation::executePixel(float output[4], int x, int y, void *data) float tempBoundingBox[4]; float bokeh[4]; - this->m_inputBoundingBoxReader->read(tempBoundingBox, x, y, COM_PS_NEAREST); + this->m_inputBoundingBoxReader->readSampled(tempBoundingBox, x, y, COM_PS_NEAREST); if (tempBoundingBox[0] > 0.0f) { float multiplier_accum[4] = {0.0f, 0.0f, 0.0f, 0.0f}; MemoryBuffer *inputBuffer = (MemoryBuffer *)data; @@ -93,7 +93,7 @@ void BokehBlurOperation::executePixel(float output[4], int x, int y, void *data) zero_v4(color_accum); if (pixelSize < 2) { - this->m_inputProgram->read(color_accum, x, y, COM_PS_NEAREST); + this->m_inputProgram->readSampled(color_accum, x, y, COM_PS_NEAREST); multiplier_accum[0] = 1.0f; multiplier_accum[1] = 1.0f; multiplier_accum[2] = 1.0f; @@ -118,7 +118,7 @@ void BokehBlurOperation::executePixel(float output[4], int x, int y, void *data) for (int nx = minx; nx < maxx; nx += step) { float u = this->m_bokehMidX - (nx - x) * m; float v = this->m_bokehMidY - (ny - y) * m; - this->m_inputBokehProgram->read(bokeh, u, v, COM_PS_NEAREST); + this->m_inputBokehProgram->readSampled(bokeh, u, v, COM_PS_NEAREST); madd_v4_v4v4(color_accum, bokeh, &buffer[bufferindex]); add_v4_v4(multiplier_accum, bokeh); bufferindex += offsetadd; @@ -130,7 +130,7 @@ void BokehBlurOperation::executePixel(float output[4], int x, int y, void *data) output[3] = color_accum[3] * (1.0f / multiplier_accum[3]); } else { - this->m_inputProgram->read(output, x, y, COM_PS_NEAREST); + this->m_inputProgram->readSampled(output, x, y, COM_PS_NEAREST); } } @@ -220,7 +220,7 @@ void BokehBlurOperation::updateSize() { if (!this->m_sizeavailable) { float result[4]; - this->getInputSocketReader(3)->read(result, 0, 0, COM_PS_NEAREST); + this->getInputSocketReader(3)->readSampled(result, 0, 0, COM_PS_NEAREST); this->m_size = result[0]; CLAMP(this->m_size, 0.0f, 10.0f); this->m_sizeavailable = true; diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.cpp b/source/blender/compositor/operations/COM_BokehImageOperation.cpp index b87be33eca1..82de750de72 100644 --- a/source/blender/compositor/operations/COM_BokehImageOperation.cpp +++ b/source/blender/compositor/operations/COM_BokehImageOperation.cpp @@ -85,7 +85,7 @@ float BokehImageOperation::isInsideBokeh(float distance, float x, float y) } return insideBokeh; } -void BokehImageOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void BokehImageOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float shift = this->m_data->lensshift; float shift2 = shift / 2.0f; diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.h b/source/blender/compositor/operations/COM_BokehImageOperation.h index 44c4c0cfe27..f1f0f1ed11c 100644 --- a/source/blender/compositor/operations/COM_BokehImageOperation.h +++ b/source/blender/compositor/operations/COM_BokehImageOperation.h @@ -111,7 +111,7 @@ public: /** * @brief the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * @brief Initialize the execution diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.cpp b/source/blender/compositor/operations/COM_BoxMaskOperation.cpp index 52f84462761..4dd92aec4c8 100644 --- a/source/blender/compositor/operations/COM_BoxMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_BoxMaskOperation.cpp @@ -44,7 +44,7 @@ void BoxMaskOperation::initExecution() this->m_aspectRatio = ((float)this->getWidth()) / this->getHeight(); } -void BoxMaskOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void BoxMaskOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputMask[4]; float inputValue[4]; @@ -57,8 +57,8 @@ void BoxMaskOperation::executePixel(float output[4], float x, float y, PixelSamp rx = this->m_data->x + (this->m_cosine * dx + this->m_sine * dy); ry = this->m_data->y + (-this->m_sine * dx + this->m_cosine * dy); - this->m_inputMask->read(inputMask, x, y, sampler); - this->m_inputValue->read(inputValue, x, y, sampler); + this->m_inputMask->readSampled(inputMask, x, y, sampler); + this->m_inputValue->readSampled(inputValue, x, y, sampler); float halfHeight = this->m_data->height / 2.0f; float halfWidth = this->m_data->width / 2.0f; diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.h b/source/blender/compositor/operations/COM_BoxMaskOperation.h index f39d74829d4..04dc8a90fd7 100644 --- a/source/blender/compositor/operations/COM_BoxMaskOperation.h +++ b/source/blender/compositor/operations/COM_BoxMaskOperation.h @@ -45,7 +45,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_BrightnessOperation.cpp b/source/blender/compositor/operations/COM_BrightnessOperation.cpp index 0613540250c..33e35c3fe3b 100644 --- a/source/blender/compositor/operations/COM_BrightnessOperation.cpp +++ b/source/blender/compositor/operations/COM_BrightnessOperation.cpp @@ -37,15 +37,15 @@ void BrightnessOperation::initExecution() this->m_inputContrastProgram = this->getInputSocketReader(2); } -void BrightnessOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void BrightnessOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue[4]; float a, b; float inputBrightness[4]; float inputContrast[4]; - this->m_inputProgram->read(inputValue, x, y, sampler); - this->m_inputBrightnessProgram->read(inputBrightness, x, y, sampler); - this->m_inputContrastProgram->read(inputContrast, x, y, sampler); + this->m_inputProgram->readSampled(inputValue, x, y, sampler); + this->m_inputBrightnessProgram->readSampled(inputBrightness, x, y, sampler); + this->m_inputContrastProgram->readSampled(inputContrast, x, y, sampler); float brightness = inputBrightness[0]; float contrast = inputContrast[0]; brightness /= 100.0f; diff --git a/source/blender/compositor/operations/COM_BrightnessOperation.h b/source/blender/compositor/operations/COM_BrightnessOperation.h index 1c8eda63e94..22086ae11e8 100644 --- a/source/blender/compositor/operations/COM_BrightnessOperation.h +++ b/source/blender/compositor/operations/COM_BrightnessOperation.h @@ -40,7 +40,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp b/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp index e6e93774685..964f1d64667 100644 --- a/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp +++ b/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp @@ -39,11 +39,11 @@ void ChangeHSVOperation::deinitExecution() this->m_inputOperation = NULL; } -void ChangeHSVOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ChangeHSVOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; - this->m_inputOperation->read(inputColor1, x, y, sampler); + this->m_inputOperation->readSampled(inputColor1, x, y, sampler); output[0] = inputColor1[0] + (this->m_hue - 0.5f); if (output[0] > 1.0f) output[0] -= 1.0f; diff --git a/source/blender/compositor/operations/COM_ChangeHSVOperation.h b/source/blender/compositor/operations/COM_ChangeHSVOperation.h index 01852084e41..76025e86b7a 100644 --- a/source/blender/compositor/operations/COM_ChangeHSVOperation.h +++ b/source/blender/compositor/operations/COM_ChangeHSVOperation.h @@ -49,7 +49,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void setHue(float hue) { this->m_hue = hue; } void setSaturation(float saturation) { this->m_saturation = saturation; } diff --git a/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp b/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp index 84cc8aad950..14494841c49 100644 --- a/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp @@ -88,7 +88,7 @@ void ChannelMatteOperation::deinitExecution() this->m_inputImageProgram = NULL; } -void ChannelMatteOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ChannelMatteOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inColor[4]; float alpha; @@ -97,7 +97,7 @@ void ChannelMatteOperation::executePixel(float output[4], float x, float y, Pixe const float limit_min = this->m_limit_min; const float limit_range = this->m_limit_range; - this->m_inputImageProgram->read(inColor, x, y, sampler); + this->m_inputImageProgram->readSampled(inColor, x, y, sampler); /* matte operation */ alpha = inColor[this->m_ids[0]] - max(inColor[this->m_ids[1]], inColor[this->m_ids[2]]); diff --git a/source/blender/compositor/operations/COM_ChannelMatteOperation.h b/source/blender/compositor/operations/COM_ChannelMatteOperation.h index efb4f7427ca..58b467e7892 100644 --- a/source/blender/compositor/operations/COM_ChannelMatteOperation.h +++ b/source/blender/compositor/operations/COM_ChannelMatteOperation.h @@ -59,7 +59,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp b/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp index c2406abaa65..3329093882d 100644 --- a/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp @@ -44,7 +44,7 @@ void ChromaMatteOperation::deinitExecution() this->m_inputKeyProgram = NULL; } -void ChromaMatteOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ChromaMatteOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inKey[4]; float inImage[4]; @@ -57,8 +57,8 @@ void ChromaMatteOperation::executePixel(float output[4], float x, float y, Pixel float theta, beta; float kfg; - this->m_inputKeyProgram->read(inKey, x, y, sampler); - this->m_inputImageProgram->read(inImage, x, y, sampler); + this->m_inputKeyProgram->readSampled(inKey, x, y, sampler); + this->m_inputImageProgram->readSampled(inImage, x, y, sampler); /* store matte(alpha) value in [0] to go with * COM_SetAlphaOperation and the Value output diff --git a/source/blender/compositor/operations/COM_ChromaMatteOperation.h b/source/blender/compositor/operations/COM_ChromaMatteOperation.h index 9557faec855..a68790838c0 100644 --- a/source/blender/compositor/operations/COM_ChromaMatteOperation.h +++ b/source/blender/compositor/operations/COM_ChromaMatteOperation.h @@ -42,7 +42,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cpp b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cpp index aa4d0932c92..2846642570c 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cpp @@ -49,21 +49,21 @@ void ColorBalanceASCCDLOperation::initExecution() this->m_inputColorOperation = this->getInputSocketReader(1); } -void ColorBalanceASCCDLOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ColorBalanceASCCDLOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor[4]; float value[4]; - this->m_inputValueOperation->read(value, x, y, sampler); - this->m_inputColorOperation->read(inputColor, x, y, sampler); + this->m_inputValueOperation->readSampled(value, x, y, sampler); + this->m_inputColorOperation->readSampled(inputColor, x, y, sampler); float fac = value[0]; fac = min(1.0f, fac); const float mfac = 1.0f - fac; - output[0] = mfac * inputColor[0] + fac * colorbalance_cdl(inputColor[0], this->m_lift[0], this->m_gamma[0], this->m_gain[0]); - output[1] = mfac * inputColor[1] + fac * colorbalance_cdl(inputColor[1], this->m_lift[1], this->m_gamma[1], this->m_gain[1]); - output[2] = mfac * inputColor[2] + fac * colorbalance_cdl(inputColor[2], this->m_lift[2], this->m_gamma[2], this->m_gain[2]); + output[0] = mfac * inputColor[0] + fac * colorbalance_cdl(inputColor[0], this->m_offset[0], this->m_power[0], this->m_slope[0]); + output[1] = mfac * inputColor[1] + fac * colorbalance_cdl(inputColor[1], this->m_offset[1], this->m_power[1], this->m_slope[1]); + output[2] = mfac * inputColor[2] + fac * colorbalance_cdl(inputColor[2], this->m_offset[2], this->m_power[2], this->m_slope[2]); output[3] = inputColor[3]; } diff --git a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h index 17fb5f67be9..bf3495869b0 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h +++ b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h @@ -36,9 +36,9 @@ protected: SocketReader *m_inputValueOperation; SocketReader *m_inputColorOperation; - float m_gain[3]; - float m_lift[3]; - float m_gamma[3]; + float m_offset[3]; + float m_power[3]; + float m_slope[3]; public: /** @@ -49,7 +49,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution @@ -61,8 +61,8 @@ public: */ void deinitExecution(); - void setGain(float gain[3]) { copy_v3_v3(this->m_gain, gain); } - void setLift(float lift[3]) { copy_v3_v3(this->m_lift, lift); } - void setGamma(float gamma[3]) { copy_v3_v3(this->m_gamma, gamma); } + void setOffset(float offset[3]) { copy_v3_v3(this->m_offset, offset); } + void setPower(float power[3]) { copy_v3_v3(this->m_power, power); } + void setSlope(float slope[3]) { copy_v3_v3(this->m_slope, slope); } }; #endif diff --git a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cpp b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cpp index 7e9c10df0a9..9588687372e 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cpp @@ -54,13 +54,13 @@ void ColorBalanceLGGOperation::initExecution() this->m_inputColorOperation = this->getInputSocketReader(1); } -void ColorBalanceLGGOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ColorBalanceLGGOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor[4]; float value[4]; - this->m_inputValueOperation->read(value, x, y, sampler); - this->m_inputColorOperation->read(inputColor, x, y, sampler); + this->m_inputValueOperation->readSampled(value, x, y, sampler); + this->m_inputColorOperation->readSampled(inputColor, x, y, sampler); float fac = value[0]; fac = min(1.0f, fac); diff --git a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h index edc824475c2..da3a141e3c2 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h +++ b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h @@ -50,7 +50,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp index b7a3f43237a..19209951005 100644 --- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp @@ -40,12 +40,12 @@ void ColorCorrectionOperation::initExecution() this->m_inputMask = this->getInputSocketReader(1); } -void ColorCorrectionOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ColorCorrectionOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputImageColor[4]; float inputMask[4]; - this->m_inputImage->read(inputImageColor, x, y, sampler); - this->m_inputMask->read(inputMask, x, y, sampler); + this->m_inputImage->readSampled(inputImageColor, x, y, sampler); + this->m_inputMask->readSampled(inputMask, x, y, sampler); float level = (inputImageColor[0] + inputImageColor[1] + inputImageColor[2]) / 3.0f; float contrast = this->m_data->master.contrast; diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.h b/source/blender/compositor/operations/COM_ColorCorrectionOperation.h index 018e67b7ada..2b47d6a8034 100644 --- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.h +++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.h @@ -44,7 +44,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_ColorCurveOperation.cpp b/source/blender/compositor/operations/COM_ColorCurveOperation.cpp index 2f13a90c072..1115b2ab239 100644 --- a/source/blender/compositor/operations/COM_ColorCurveOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorCurveOperation.cpp @@ -58,7 +58,7 @@ void ColorCurveOperation::initExecution() } -void ColorCurveOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ColorCurveOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { CurveMapping *cumap = this->m_curveMapping; @@ -70,15 +70,15 @@ void ColorCurveOperation::executePixel(float output[4], float x, float y, PixelS float white[4]; float bwmul[3]; - this->m_inputBlackProgram->read(black, x, y, sampler); - this->m_inputWhiteProgram->read(white, x, y, sampler); + this->m_inputBlackProgram->readSampled(black, x, y, sampler); + this->m_inputWhiteProgram->readSampled(white, x, y, sampler); /* get our own local bwmul value, * since we can't be threadsafe and use cumap->bwmul & friends */ curvemapping_set_black_white_ex(black, white, bwmul); - this->m_inputFacProgram->read(fac, x, y, sampler); - this->m_inputImageProgram->read(image, x, y, sampler); + this->m_inputFacProgram->readSampled(fac, x, y, sampler); + this->m_inputImageProgram->readSampled(image, x, y, sampler); if (*fac >= 1.0f) { curvemapping_evaluate_premulRGBF_ex(cumap, output, image, @@ -130,13 +130,13 @@ void ConstantLevelColorCurveOperation::initExecution() curvemapping_set_black_white(this->m_curveMapping, this->m_black, this->m_white); } -void ConstantLevelColorCurveOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ConstantLevelColorCurveOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float fac[4]; float image[4]; - this->m_inputFacProgram->read(fac, x, y, sampler); - this->m_inputImageProgram->read(image, x, y, sampler); + this->m_inputFacProgram->readSampled(fac, x, y, sampler); + this->m_inputImageProgram->readSampled(image, x, y, sampler); if (*fac >= 1.0f) { curvemapping_evaluate_premulRGBF(this->m_curveMapping, output, image); diff --git a/source/blender/compositor/operations/COM_ColorCurveOperation.h b/source/blender/compositor/operations/COM_ColorCurveOperation.h index 7dc1913b85a..1eb77553953 100644 --- a/source/blender/compositor/operations/COM_ColorCurveOperation.h +++ b/source/blender/compositor/operations/COM_ColorCurveOperation.h @@ -41,7 +41,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution @@ -70,7 +70,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_ColorMatteOperation.cpp b/source/blender/compositor/operations/COM_ColorMatteOperation.cpp index d73196e42f5..b928141f41d 100644 --- a/source/blender/compositor/operations/COM_ColorMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorMatteOperation.cpp @@ -44,7 +44,7 @@ void ColorMatteOperation::deinitExecution() this->m_inputKeyProgram = NULL; } -void ColorMatteOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ColorMatteOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inColor[4]; float inKey[4]; @@ -55,8 +55,8 @@ void ColorMatteOperation::executePixel(float output[4], float x, float y, PixelS float h_wrap; - this->m_inputImageProgram->read(inColor, x, y, sampler); - this->m_inputKeyProgram->read(inKey, x, y, sampler); + this->m_inputImageProgram->readSampled(inColor, x, y, sampler); + this->m_inputKeyProgram->readSampled(inKey, x, y, sampler); /* store matte(alpha) value in [0] to go with diff --git a/source/blender/compositor/operations/COM_ColorMatteOperation.h b/source/blender/compositor/operations/COM_ColorMatteOperation.h index f065a5f7e89..53bbe8f6466 100644 --- a/source/blender/compositor/operations/COM_ColorMatteOperation.h +++ b/source/blender/compositor/operations/COM_ColorMatteOperation.h @@ -42,7 +42,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_ColorRampOperation.cpp b/source/blender/compositor/operations/COM_ColorRampOperation.cpp index 1618c83aece..fd3380d594e 100644 --- a/source/blender/compositor/operations/COM_ColorRampOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorRampOperation.cpp @@ -43,11 +43,11 @@ void ColorRampOperation::initExecution() this->m_inputProgram = this->getInputSocketReader(0); } -void ColorRampOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ColorRampOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float values[4]; - this->m_inputProgram->read(values, x, y, sampler); + this->m_inputProgram->readSampled(values, x, y, sampler); do_colorband(this->m_colorBand, values[0], output); } diff --git a/source/blender/compositor/operations/COM_ColorRampOperation.h b/source/blender/compositor/operations/COM_ColorRampOperation.h index 96d9a525e1e..333e6c36d97 100644 --- a/source/blender/compositor/operations/COM_ColorRampOperation.h +++ b/source/blender/compositor/operations/COM_ColorRampOperation.h @@ -38,7 +38,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_ColorSpillOperation.cpp b/source/blender/compositor/operations/COM_ColorSpillOperation.cpp index a8e8cb98564..873ec72d9e9 100644 --- a/source/blender/compositor/operations/COM_ColorSpillOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorSpillOperation.cpp @@ -84,12 +84,12 @@ void ColorSpillOperation::deinitExecution() this->m_inputFacReader = NULL; } -void ColorSpillOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ColorSpillOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float fac[4]; float input[4]; - this->m_inputFacReader->read(fac, x, y, sampler); - this->m_inputImageReader->read(input, x, y, sampler); + this->m_inputFacReader->readSampled(fac, x, y, sampler); + this->m_inputImageReader->readSampled(input, x, y, sampler); float rfac = min(1.0f, fac[0]); float map = calculateMapValue(rfac, input); if (map > 0.0f) { diff --git a/source/blender/compositor/operations/COM_ColorSpillOperation.h b/source/blender/compositor/operations/COM_ColorSpillOperation.h index 94ff78c37b2..f9dc9ef7e25 100644 --- a/source/blender/compositor/operations/COM_ColorSpillOperation.h +++ b/source/blender/compositor/operations/COM_ColorSpillOperation.h @@ -46,7 +46,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp index 383682b1474..3d4b771fecc 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.cpp +++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp @@ -188,20 +188,20 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber) for (x = x1; x < x2 && (!breaked); x++) { int input_x = x + dx, input_y = y + dy; - this->m_imageInput->read(color, input_x, input_y, COM_PS_NEAREST); + this->m_imageInput->readSampled(color, input_x, input_y, COM_PS_NEAREST); if (this->m_ignoreAlpha) { color[3] = 1.0f; } else { if (this->m_alphaInput != NULL) { - this->m_alphaInput->read(&(color[3]), input_x, input_y, COM_PS_NEAREST); + this->m_alphaInput->readSampled(&(color[3]), input_x, input_y, COM_PS_NEAREST); } } copy_v4_v4(buffer + offset4, color); if (this->m_depthInput != NULL) { - this->m_depthInput->read(color, input_x, input_y, COM_PS_NEAREST); + this->m_depthInput->readSampled(color, input_x, input_y, COM_PS_NEAREST); zbuffer[offset] = color[0]; } offset4 += COM_NUMBER_OF_CHANNELS; diff --git a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.cpp b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.cpp index 79ce149e790..cb269b16bf4 100644 --- a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.cpp @@ -38,10 +38,10 @@ void ConvertColorProfileOperation::initExecution() this->m_inputOperation = this->getInputSocketReader(0); } -void ConvertColorProfileOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ConvertColorProfileOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float color[4]; - this->m_inputOperation->read(color, x, y, sampler); + this->m_inputOperation->readSampled(color, x, y, sampler); IMB_buffer_float_from_float(output, color, 4, this->m_toProfile, this->m_fromProfile, this->m_predivided, 1, 1, 0, 0); } diff --git a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h index a8cbc613fb8..e68a9bdf7c1 100644 --- a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h +++ b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h @@ -59,7 +59,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp index f39a28b87a8..ea1443598a9 100644 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp @@ -72,12 +72,12 @@ void ConvertDepthToRadiusOperation::initExecution() } } -void ConvertDepthToRadiusOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ConvertDepthToRadiusOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue[4]; float z; float radius; - this->m_inputOperation->read(inputValue, x, y, sampler); + this->m_inputOperation->readSampled(inputValue, x, y, sampler); z = inputValue[0]; if (z != 0.f) { float iZ = (1.f / z); diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h index d5a1fd72cbf..b92eb65d01e 100644 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h @@ -54,7 +54,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_ConvertOperation.cpp b/source/blender/compositor/operations/COM_ConvertOperation.cpp index d72aabb078e..6b3e4067b18 100644 --- a/source/blender/compositor/operations/COM_ConvertOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertOperation.cpp @@ -47,10 +47,10 @@ ConvertValueToColorOperation::ConvertValueToColorOperation() : ConvertBaseOperat this->addOutputSocket(COM_DT_COLOR); } -void ConvertValueToColorOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ConvertValueToColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue[4]; - this->m_inputOperation->read(inputValue, x, y, sampler); + this->m_inputOperation->readSampled(inputValue, x, y, sampler); output[0] = output[1] = output[2] = inputValue[0]; output[3] = 1.0f; } @@ -64,10 +64,10 @@ ConvertColorToValueOperation::ConvertColorToValueOperation() : ConvertBaseOperat this->addOutputSocket(COM_DT_VALUE); } -void ConvertColorToValueOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ConvertColorToValueOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor[4]; - this->m_inputOperation->read(inputColor, x, y, sampler); + this->m_inputOperation->readSampled(inputColor, x, y, sampler); output[0] = (inputColor[0] + inputColor[1] + inputColor[2]) / 3.0f; } @@ -80,10 +80,10 @@ ConvertColorToBWOperation::ConvertColorToBWOperation() : ConvertBaseOperation() this->addOutputSocket(COM_DT_VALUE); } -void ConvertColorToBWOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ConvertColorToBWOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor[4]; - this->m_inputOperation->read(inputColor, x, y, sampler); + this->m_inputOperation->readSampled(inputColor, x, y, sampler); output[0] = rgb_to_bw(inputColor); } @@ -96,9 +96,9 @@ ConvertColorToVectorOperation::ConvertColorToVectorOperation() : ConvertBaseOper this->addOutputSocket(COM_DT_VECTOR); } -void ConvertColorToVectorOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ConvertColorToVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { - this->m_inputOperation->read(output, x, y, sampler); + this->m_inputOperation->readSampled(output, x, y, sampler); } @@ -110,10 +110,10 @@ ConvertValueToVectorOperation::ConvertValueToVectorOperation() : ConvertBaseOper this->addOutputSocket(COM_DT_VECTOR); } -void ConvertValueToVectorOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ConvertValueToVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float input[4]; - this->m_inputOperation->read(input, x, y, sampler); + this->m_inputOperation->readSampled(input, x, y, sampler); output[0] = input[0]; output[1] = input[0]; output[2] = input[0]; @@ -129,9 +129,9 @@ ConvertVectorToColorOperation::ConvertVectorToColorOperation() : ConvertBaseOper this->addOutputSocket(COM_DT_COLOR); } -void ConvertVectorToColorOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ConvertVectorToColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { - this->m_inputOperation->read(output, x, y, sampler); + this->m_inputOperation->readSampled(output, x, y, sampler); output[3] = 1.0f; } @@ -144,10 +144,10 @@ ConvertVectorToValueOperation::ConvertVectorToValueOperation() : ConvertBaseOper this->addOutputSocket(COM_DT_VALUE); } -void ConvertVectorToValueOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ConvertVectorToValueOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float input[4]; - this->m_inputOperation->read(input, x, y, sampler); + this->m_inputOperation->readSampled(input, x, y, sampler); output[0] = (input[0] + input[1] + input[2]) / 3.0f; } @@ -176,12 +176,12 @@ void ConvertRGBToYCCOperation::setMode(int mode) } } -void ConvertRGBToYCCOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ConvertRGBToYCCOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor[4]; float color[3]; - this->m_inputOperation->read(inputColor, x, y, sampler); + this->m_inputOperation->readSampled(inputColor, x, y, sampler); rgb_to_ycc(inputColor[0], inputColor[1], inputColor[2], &color[0], &color[1], &color[2], this->m_mode); /* divided by 255 to normalize for viewing in */ @@ -214,10 +214,10 @@ void ConvertYCCToRGBOperation::setMode(int mode) } } -void ConvertYCCToRGBOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ConvertYCCToRGBOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor[4]; - this->m_inputOperation->read(inputColor, x, y, sampler); + this->m_inputOperation->readSampled(inputColor, x, y, sampler); /* need to un-normalize the data */ /* R,G,B --> Y,Cb,Cr */ @@ -236,10 +236,10 @@ ConvertRGBToYUVOperation::ConvertRGBToYUVOperation() : ConvertBaseOperation() this->addOutputSocket(COM_DT_COLOR); } -void ConvertRGBToYUVOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ConvertRGBToYUVOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor[4]; - this->m_inputOperation->read(inputColor, x, y, sampler); + this->m_inputOperation->readSampled(inputColor, x, y, sampler); rgb_to_yuv(inputColor[0], inputColor[1], inputColor[2], &output[0], &output[1], &output[2]); output[3] = inputColor[3]; } @@ -253,10 +253,10 @@ ConvertYUVToRGBOperation::ConvertYUVToRGBOperation() : ConvertBaseOperation() this->addOutputSocket(COM_DT_COLOR); } -void ConvertYUVToRGBOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ConvertYUVToRGBOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor[4]; - this->m_inputOperation->read(inputColor, x, y, sampler); + this->m_inputOperation->readSampled(inputColor, x, y, sampler); yuv_to_rgb(inputColor[0], inputColor[1], inputColor[2], &output[0], &output[1], &output[2]); output[3] = inputColor[3]; } @@ -270,10 +270,10 @@ ConvertRGBToHSVOperation::ConvertRGBToHSVOperation() : ConvertBaseOperation() this->addOutputSocket(COM_DT_COLOR); } -void ConvertRGBToHSVOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ConvertRGBToHSVOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor[4]; - this->m_inputOperation->read(inputColor, x, y, sampler); + this->m_inputOperation->readSampled(inputColor, x, y, sampler); rgb_to_hsv_v(inputColor, output); output[3] = inputColor[3]; } @@ -287,10 +287,10 @@ ConvertHSVToRGBOperation::ConvertHSVToRGBOperation() : ConvertBaseOperation() this->addOutputSocket(COM_DT_COLOR); } -void ConvertHSVToRGBOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ConvertHSVToRGBOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor[4]; - this->m_inputOperation->read(inputColor, x, y, sampler); + this->m_inputOperation->readSampled(inputColor, x, y, sampler); hsv_to_rgb_v(inputColor, output); output[3] = inputColor[3]; } @@ -304,12 +304,12 @@ ConvertPremulToStraightOperation::ConvertPremulToStraightOperation() : ConvertBa this->addOutputSocket(COM_DT_COLOR); } -void ConvertPremulToStraightOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ConvertPremulToStraightOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue[4]; float alpha; - this->m_inputOperation->read(inputValue, x, y, sampler); + this->m_inputOperation->readSampled(inputValue, x, y, sampler); alpha = inputValue[3]; if (fabsf(alpha) < 1e-5f) { @@ -332,12 +332,12 @@ ConvertStraightToPremulOperation::ConvertStraightToPremulOperation() : ConvertBa this->addOutputSocket(COM_DT_COLOR); } -void ConvertStraightToPremulOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ConvertStraightToPremulOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue[4]; float alpha; - this->m_inputOperation->read(inputValue, x, y, sampler); + this->m_inputOperation->readSampled(inputValue, x, y, sampler); alpha = inputValue[3]; mul_v3_v3fl(output, inputValue, alpha); @@ -366,10 +366,10 @@ void SeparateChannelOperation::deinitExecution() } -void SeparateChannelOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void SeparateChannelOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float input[4]; - this->m_inputOperation->read(input, x, y, sampler); + this->m_inputOperation->readSampled(input, x, y, sampler); output[0] = input[this->m_channel]; } @@ -407,23 +407,23 @@ void CombineChannelsOperation::deinitExecution() } -void CombineChannelsOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void CombineChannelsOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float input[4]; if (this->m_inputChannel1Operation) { - this->m_inputChannel1Operation->read(input, x, y, sampler); + this->m_inputChannel1Operation->readSampled(input, x, y, sampler); output[0] = input[0]; } if (this->m_inputChannel2Operation) { - this->m_inputChannel2Operation->read(input, x, y, sampler); + this->m_inputChannel2Operation->readSampled(input, x, y, sampler); output[1] = input[0]; } if (this->m_inputChannel3Operation) { - this->m_inputChannel3Operation->read(input, x, y, sampler); + this->m_inputChannel3Operation->readSampled(input, x, y, sampler); output[2] = input[0]; } if (this->m_inputChannel4Operation) { - this->m_inputChannel4Operation->read(input, x, y, sampler); + this->m_inputChannel4Operation->readSampled(input, x, y, sampler); output[3] = input[0]; } } diff --git a/source/blender/compositor/operations/COM_ConvertOperation.h b/source/blender/compositor/operations/COM_ConvertOperation.h index 06aeb2e52d7..957df812a2e 100644 --- a/source/blender/compositor/operations/COM_ConvertOperation.h +++ b/source/blender/compositor/operations/COM_ConvertOperation.h @@ -42,7 +42,7 @@ class ConvertValueToColorOperation : public ConvertBaseOperation { public: ConvertValueToColorOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; @@ -50,7 +50,7 @@ class ConvertColorToValueOperation : public ConvertBaseOperation { public: ConvertColorToValueOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; @@ -58,7 +58,7 @@ class ConvertColorToBWOperation : public ConvertBaseOperation { public: ConvertColorToBWOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; @@ -66,7 +66,7 @@ class ConvertColorToVectorOperation : public ConvertBaseOperation { public: ConvertColorToVectorOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; @@ -74,7 +74,7 @@ class ConvertValueToVectorOperation : public ConvertBaseOperation { public: ConvertValueToVectorOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; @@ -82,7 +82,7 @@ class ConvertVectorToColorOperation : public ConvertBaseOperation { public: ConvertVectorToColorOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; @@ -90,7 +90,7 @@ class ConvertVectorToValueOperation : public ConvertBaseOperation { public: ConvertVectorToValueOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; @@ -101,7 +101,7 @@ private: public: ConvertRGBToYCCOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** Set the YCC mode */ void setMode(int mode); @@ -115,7 +115,7 @@ private: public: ConvertYCCToRGBOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** Set the YCC mode */ void setMode(int mode); @@ -126,7 +126,7 @@ class ConvertRGBToYUVOperation : public ConvertBaseOperation { public: ConvertRGBToYUVOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; @@ -134,7 +134,7 @@ class ConvertYUVToRGBOperation : public ConvertBaseOperation { public: ConvertYUVToRGBOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; @@ -142,7 +142,7 @@ class ConvertRGBToHSVOperation : public ConvertBaseOperation { public: ConvertRGBToHSVOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; @@ -150,7 +150,7 @@ class ConvertHSVToRGBOperation : public ConvertBaseOperation { public: ConvertHSVToRGBOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; @@ -158,7 +158,7 @@ class ConvertPremulToStraightOperation : public ConvertBaseOperation { public: ConvertPremulToStraightOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; @@ -166,7 +166,7 @@ class ConvertStraightToPremulOperation : public ConvertBaseOperation { public: ConvertStraightToPremulOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; @@ -176,7 +176,7 @@ private: int m_channel; public: SeparateChannelOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); @@ -193,7 +193,7 @@ private: SocketReader *m_inputChannel4Operation; public: CombineChannelsOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_CropOperation.cpp b/source/blender/compositor/operations/COM_CropOperation.cpp index 844d23db2ac..c514b576dcf 100644 --- a/source/blender/compositor/operations/COM_CropOperation.cpp +++ b/source/blender/compositor/operations/COM_CropOperation.cpp @@ -82,10 +82,10 @@ CropOperation::CropOperation() : CropBaseOperation() /* pass */ } -void CropOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void CropOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { if ((x < this->m_xmax && x >= this->m_xmin) && (y < this->m_ymax && y >= this->m_ymin)) { - this->m_inputOperation->read(output, x, y, sampler); + this->m_inputOperation->readSampled(output, x, y, sampler); } else { zero_v4(output); @@ -117,10 +117,10 @@ void CropImageOperation::determineResolution(unsigned int resolution[2], unsigne resolution[1] = this->m_ymax - this->m_ymin; } -void CropImageOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void CropImageOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) { - this->m_inputOperation->read(output, (x + this->m_xmin), (y + this->m_ymin), sampler); + this->m_inputOperation->readSampled(output, (x + this->m_xmin), (y + this->m_ymin), sampler); } else { zero_v4(output); diff --git a/source/blender/compositor/operations/COM_CropOperation.h b/source/blender/compositor/operations/COM_CropOperation.h index d2f2b15aa36..4890ede18a9 100644 --- a/source/blender/compositor/operations/COM_CropOperation.h +++ b/source/blender/compositor/operations/COM_CropOperation.h @@ -48,7 +48,7 @@ class CropOperation : public CropBaseOperation { private: public: CropOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class CropImageOperation : public CropBaseOperation { @@ -57,7 +57,7 @@ public: CropImageOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); void determineResolution(unsigned int resolution[2], unsigned int preferedResolution[2]); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; #endif diff --git a/source/blender/compositor/operations/COM_DespeckleOperation.cpp b/source/blender/compositor/operations/COM_DespeckleOperation.cpp index 599f54720f2..186c17845f3 100644 --- a/source/blender/compositor/operations/COM_DespeckleOperation.cpp +++ b/source/blender/compositor/operations/COM_DespeckleOperation.cpp @@ -114,7 +114,7 @@ void DespeckleOperation::executePixel(float output[4], int x, int y, void *data) //mul_v4_fl(color_mid, 1.0f / w); if ((w != 0.0f) && - ((w / WTOT) > (this->m_threshold_neighbour)) && + ((w / WTOT) > (this->m_threshold_neighbor)) && color_diff(color_mid, color_org, this->m_threshold)) { mul_v4_fl(color_mid_ok, 1.0f / w); diff --git a/source/blender/compositor/operations/COM_DespeckleOperation.h b/source/blender/compositor/operations/COM_DespeckleOperation.h index 99635e61544..00c5463c17a 100644 --- a/source/blender/compositor/operations/COM_DespeckleOperation.h +++ b/source/blender/compositor/operations/COM_DespeckleOperation.h @@ -25,7 +25,7 @@ class DespeckleOperation : public NodeOperation { private: float m_threshold; - float m_threshold_neighbour; + float m_threshold_neighbor; // int m_filterWidth; // int m_filterHeight; @@ -40,7 +40,7 @@ public: void executePixel(float output[4], int x, int y, void *data); void setThreshold(float threshold) { this->m_threshold = threshold; } - void setThresholdNeighbour(float threshold) { this->m_threshold_neighbour = threshold; } + void setThresholdNeighbor(float threshold) { this->m_threshold_neighbor = threshold; } void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp b/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp index e23eb26f527..325ef83a529 100644 --- a/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp @@ -44,7 +44,7 @@ void DifferenceMatteOperation::deinitExecution() this->m_inputImage2Program = NULL; } -void DifferenceMatteOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void DifferenceMatteOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inColor1[4]; float inColor2[4]; @@ -54,8 +54,8 @@ void DifferenceMatteOperation::executePixel(float output[4], float x, float y, P float difference; float alpha; - this->m_inputImage1Program->read(inColor1, x, y, sampler); - this->m_inputImage2Program->read(inColor2, x, y, sampler); + this->m_inputImage1Program->readSampled(inColor1, x, y, sampler); + this->m_inputImage2Program->readSampled(inColor2, x, y, sampler); difference = (fabsf(inColor2[0] - inColor1[0]) + fabsf(inColor2[1] - inColor1[1]) + diff --git a/source/blender/compositor/operations/COM_DifferenceMatteOperation.h b/source/blender/compositor/operations/COM_DifferenceMatteOperation.h index e0a38f703ed..a3647e1e5db 100644 --- a/source/blender/compositor/operations/COM_DifferenceMatteOperation.h +++ b/source/blender/compositor/operations/COM_DifferenceMatteOperation.h @@ -43,7 +43,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp index 23289429bfd..d6c25574d01 100644 --- a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp @@ -71,7 +71,7 @@ void DirectionalBlurOperation::executePixel(float output[4], int x, int y, void const int iterations = pow(2.0f, this->m_data->iter); float col[4] = {0, 0, 0, 0}; float col2[4] = {0, 0, 0, 0}; - this->m_inputProgram->read(col2, x, y, COM_PS_NEAREST); + this->m_inputProgram->readSampled(col2, x, y, COM_PS_NEAREST); float ltx = this->m_tx; float lty = this->m_ty; float lsc = this->m_sc; @@ -84,7 +84,7 @@ void DirectionalBlurOperation::executePixel(float output[4], int x, int y, void const float v = isc * (y - this->m_center_y_pix) + lty; const float u = isc * (x - this->m_center_x_pix) + ltx; - this->m_inputProgram->read(col, + this->m_inputProgram->readSampled(col, cs * u + ss * v + this->m_center_x_pix, cs * v - ss * u + this->m_center_y_pix, COM_PS_NEAREST); diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.cpp b/source/blender/compositor/operations/COM_DisplaceOperation.cpp index 1723da11f21..17692bd18ef 100644 --- a/source/blender/compositor/operations/COM_DisplaceOperation.cpp +++ b/source/blender/compositor/operations/COM_DisplaceOperation.cpp @@ -64,9 +64,9 @@ void DisplaceOperation::executePixel(float output[4], int x, int y, void *data) float dxt, dyt; float u, v; - this->m_inputScaleXProgram->read(inScale, x, y, COM_PS_NEAREST); + this->m_inputScaleXProgram->readSampled(inScale, x, y, COM_PS_NEAREST); float xs = inScale[0]; - this->m_inputScaleYProgram->read(inScale, x, y, COM_PS_NEAREST); + this->m_inputScaleYProgram->readSampled(inScale, x, y, COM_PS_NEAREST); float ys = inScale[0]; /* clamp x and y displacement to triple image resolution - @@ -74,7 +74,7 @@ void DisplaceOperation::executePixel(float output[4], int x, int y, void *data) CLAMP(xs, -this->m_width_x4, this->m_width_x4); CLAMP(ys, -this->m_height_x4, this->m_height_x4); - this->m_inputVectorProgram->read(inVector, x, y, COM_PS_NEAREST); + this->m_inputVectorProgram->readSampled(inVector, x, y, COM_PS_NEAREST); p_dx = inVector[0] * xs; p_dy = inVector[1] * ys; @@ -83,9 +83,9 @@ void DisplaceOperation::executePixel(float output[4], int x, int y, void *data) v = y - p_dy + 0.5f; /* calc derivatives */ - this->m_inputVectorProgram->read(inVector, x + 1, y, COM_PS_NEAREST); + this->m_inputVectorProgram->readSampled(inVector, x + 1, y, COM_PS_NEAREST); d_dx = inVector[0] * xs; - this->m_inputVectorProgram->read(inVector, x, y + 1, COM_PS_NEAREST); + this->m_inputVectorProgram->readSampled(inVector, x, y + 1, COM_PS_NEAREST); d_dy = inVector[1] * ys; /* clamp derivatives to minimum displacement distance in UV space */ @@ -96,7 +96,7 @@ void DisplaceOperation::executePixel(float output[4], int x, int y, void *data) dyt = signf(dyt) * max_ff(fabsf(dyt), DISPLACE_EPSILON) / this->getHeight(); /* EWA filtering (without nearest it gets blurry with NO distortion) */ - this->m_inputColorProgram->read(output, u, v, dxt, dyt, COM_PS_NEAREST); + this->m_inputColorProgram->readFiltered(output, u, v, dxt, dyt, COM_PS_NEAREST); } void DisplaceOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cpp b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cpp index c8ebb845bb6..48160d5db2c 100644 --- a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cpp +++ b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cpp @@ -53,7 +53,7 @@ void DisplaceSimpleOperation::initExecution() * in order to take effect */ // #define DISPLACE_EPSILON 0.01f -void DisplaceSimpleOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void DisplaceSimpleOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inVector[4]; float inScale[4]; @@ -61,9 +61,9 @@ void DisplaceSimpleOperation::executePixel(float output[4], float x, float y, Pi float p_dx, p_dy; /* main displacement in pixel space */ float u, v; - this->m_inputScaleXProgram->read(inScale, x, y, sampler); + this->m_inputScaleXProgram->readSampled(inScale, x, y, sampler); float xs = inScale[0]; - this->m_inputScaleYProgram->read(inScale, x, y, sampler); + this->m_inputScaleYProgram->readSampled(inScale, x, y, sampler); float ys = inScale[0]; /* clamp x and y displacement to triple image resolution - @@ -71,7 +71,7 @@ void DisplaceSimpleOperation::executePixel(float output[4], float x, float y, Pi CLAMP(xs, -this->m_width_x4, this->m_width_x4); CLAMP(ys, -this->m_height_x4, this->m_height_x4); - this->m_inputVectorProgram->read(inVector, x, y, sampler); + this->m_inputVectorProgram->readSampled(inVector, x, y, sampler); p_dx = inVector[0] * xs; p_dy = inVector[1] * ys; @@ -82,7 +82,7 @@ void DisplaceSimpleOperation::executePixel(float output[4], float x, float y, Pi CLAMP(u, 0.f, this->getWidth() - 1.f); CLAMP(v, 0.f, this->getHeight() - 1.f); - this->m_inputColorProgram->read(output, u, v, sampler); + this->m_inputColorProgram->readSampled(output, u, v, sampler); } void DisplaceSimpleOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h index 989cf8a1f67..6e52dfe86e9 100644 --- a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h +++ b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h @@ -48,7 +48,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.cpp b/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.cpp index d3309e0c978..072ca1022e7 100644 --- a/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.cpp @@ -49,7 +49,7 @@ float DistanceRGBMatteOperation::calculateDistance(float key[4], float image[4]) return len_v3v3(key, image); } -void DistanceRGBMatteOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void DistanceRGBMatteOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inKey[4]; float inImage[4]; @@ -60,8 +60,8 @@ void DistanceRGBMatteOperation::executePixel(float output[4], float x, float y, float distance; float alpha; - this->m_inputKeyProgram->read(inKey, x, y, sampler); - this->m_inputImageProgram->read(inImage, x, y, sampler); + this->m_inputKeyProgram->readSampled(inKey, x, y, sampler); + this->m_inputImageProgram->readSampled(inImage, x, y, sampler); distance = this->calculateDistance(inKey, inImage); diff --git a/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h b/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h index 43299486f60..a815caa5ef5 100644 --- a/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h +++ b/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h @@ -45,7 +45,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_DotproductOperation.cpp b/source/blender/compositor/operations/COM_DotproductOperation.cpp index 1439dfa404a..368db185adc 100644 --- a/source/blender/compositor/operations/COM_DotproductOperation.cpp +++ b/source/blender/compositor/operations/COM_DotproductOperation.cpp @@ -45,11 +45,11 @@ void DotproductOperation::deinitExecution() /** @todo: current implementation is the inverse of a dotproduct. not 'logically' correct */ -void DotproductOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void DotproductOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float input1[4]; float input2[4]; - this->m_input1Operation->read(input1, x, y, sampler); - this->m_input2Operation->read(input2, x, y, sampler); + this->m_input1Operation->readSampled(input1, x, y, sampler); + this->m_input2Operation->readSampled(input2, x, y, sampler); output[0] = -(input1[0] * input2[0] + input1[1] * input2[1] + input1[2] * input2[2]); } diff --git a/source/blender/compositor/operations/COM_DotproductOperation.h b/source/blender/compositor/operations/COM_DotproductOperation.h index 31588207504..4378e280d17 100644 --- a/source/blender/compositor/operations/COM_DotproductOperation.h +++ b/source/blender/compositor/operations/COM_DotproductOperation.h @@ -31,7 +31,7 @@ private: SocketReader *m_input2Operation; public: DotproductOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp b/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp index 9ab21e2d5bd..d7cc2ec9272 100644 --- a/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp @@ -44,7 +44,7 @@ void EllipseMaskOperation::initExecution() this->m_aspectRatio = ((float)this->getWidth()) / this->getHeight(); } -void EllipseMaskOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void EllipseMaskOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputMask[4]; float inputValue[4]; @@ -57,8 +57,8 @@ void EllipseMaskOperation::executePixel(float output[4], float x, float y, Pixel rx = this->m_data->x + (this->m_cosine * dx + this->m_sine * dy); ry = this->m_data->y + (-this->m_sine * dx + this->m_cosine * dy); - this->m_inputMask->read(inputMask, x, y, sampler); - this->m_inputValue->read(inputValue, x, y, sampler); + this->m_inputMask->readSampled(inputMask, x, y, sampler); + this->m_inputValue->readSampled(inputValue, x, y, sampler); const float halfHeight = (this->m_data->height) / 2.0f; const float halfWidth = this->m_data->width / 2.0f; diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.h b/source/blender/compositor/operations/COM_EllipseMaskOperation.h index ed74e6b43db..753615df370 100644 --- a/source/blender/compositor/operations/COM_EllipseMaskOperation.h +++ b/source/blender/compositor/operations/COM_EllipseMaskOperation.h @@ -45,7 +45,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp index 9231261986d..a6be9254f6f 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp @@ -29,6 +29,7 @@ FastGaussianBlurOperation::FastGaussianBlurOperation() : BlurBaseOperation(COM_DT_COLOR) { this->m_iirgaus = NULL; + this->m_chunksize = 256; } void FastGaussianBlurOperation::executePixel(float output[4], int x, int y, void *data) @@ -37,22 +38,56 @@ void FastGaussianBlurOperation::executePixel(float output[4], int x, int y, void newData->read(output, x, y); } +// Calculate the depending area of interest. This depends on the +// size of the blur operation; if the blur is large it is faster +// to just calculate the whole image at once. +// Returns true if the area is just a tile and false if it is +// the whole image. +bool FastGaussianBlurOperation::getDAI(rcti *rect, rcti *output) +{ + // m_data->sizex * m_size should be enough? For some reason there + // seem to be errors in the boundary between tiles. + int sx = this->m_data->sizex * this->m_size * 2; + if (sx < 1) + sx = 1; + int sy = this->m_data->sizey * this->m_size * 2; + if (sy < 1) + sy = 1; + + if (sx >= this->m_chunksize || sy >= this->m_chunksize) { + output->xmin = 0; + output->xmax = this->getWidth(); + output->ymin = 0; + output->ymax = this->getHeight(); + return false; + } + else { + output->xmin = rect->xmin - sx - 1; + output->xmax = rect->xmax + sx + 1; + output->ymin = rect->ymin - sy - 1; + output->ymax = rect->ymax + sy + 1; + return true; + } +} + bool FastGaussianBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { rcti newInput; - rcti sizeInput; - sizeInput.xmin = 0; - sizeInput.ymin = 0; - sizeInput.xmax = 5; - sizeInput.ymax = 5; - NodeOperation *operation = this->getInputOperation(1); - if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) { - return true; + if (!this->m_sizeavailable) { + rcti sizeInput; + sizeInput.xmin = 0; + sizeInput.ymin = 0; + sizeInput.xmax = 5; + sizeInput.ymax = 5; + NodeOperation *operation = this->getInputOperation(1); + if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) { + return true; + } } - else { - if (this->m_iirgaus) { - return false; + { + if (this->m_sizeavailable) { + getDAI(input, &newInput); } else { newInput.xmin = 0; @@ -81,6 +116,7 @@ void FastGaussianBlurOperation::deinitExecution() void *FastGaussianBlurOperation::initializeTileData(rcti *rect) { +#if 0 lockMutex(); if (!this->m_iirgaus) { MemoryBuffer *newBuf = (MemoryBuffer *)this->m_inputProgram->initializeTileData(rect); @@ -109,8 +145,68 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect) } unlockMutex(); return this->m_iirgaus; +#else + + lockMutex(); + if (this->m_iirgaus) { + // if this->m_iirgaus is set, we don't do tile rendering, so + // we can return the already calculated cache + unlockMutex(); + return this->m_iirgaus; + } + updateSize(); + rcti dai; + bool use_tiles = getDAI(rect, &dai); + if (use_tiles) { + unlockMutex(); + } + + MemoryBuffer *buffer = (MemoryBuffer *)this->m_inputProgram->initializeTileData(NULL); + rcti *buf_rect = buffer->getRect(); + + dai.xmin = max(dai.xmin, buf_rect->xmin); + dai.xmax = min(dai.xmax, buf_rect->xmax); + dai.ymin = max(dai.ymin, buf_rect->ymin); + dai.ymax = min(dai.ymax, buf_rect->ymax); + + MemoryBuffer *tile = new MemoryBuffer(NULL, &dai); + tile->copyContentFrom(buffer); + + int c; + float sx = this->m_data->sizex * this->m_size / 2.0f; + float sy = this->m_data->sizey * this->m_size / 2.0f; + + if ((sx == sy) && (sx > 0.f)) { + for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) + IIR_gauss(tile, sx, c, 3); + } + else { + if (sx > 0.0f) { + for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) + IIR_gauss(tile, sx, c, 1); + } + if (sy > 0.0f) { + for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) + IIR_gauss(tile, sy, c, 2); + } + } + if (!use_tiles) { + this->m_iirgaus = tile; + unlockMutex(); + } + return tile; +#endif } +void FastGaussianBlurOperation::deinitializeTileData(rcti *rect, void *data) +{ + if (!this->m_iirgaus && data) { + MemoryBuffer *tile = (MemoryBuffer *)data; + delete tile; + } +} + + void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsigned int chan, unsigned int xy) { double q, q2, sc, cf[4], tsM[9], tsu[3], tsv[3]; @@ -195,22 +291,38 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsign Y = (double *)MEM_callocN(sz * sizeof(double), "IIR_gauss Y buf"); W = (double *)MEM_callocN(sz * sizeof(double), "IIR_gauss W buf"); if (xy & 1) { // H + int offset; for (y = 0; y < src_height; ++y) { const int yx = y * src_width; - for (x = 0; x < src_width; ++x) - X[x] = buffer[(x + yx) * COM_NUMBER_OF_CHANNELS + chan]; + offset = yx * COM_NUMBER_OF_CHANNELS + chan; + for (x = 0; x < src_width; ++x) { + X[x] = buffer[offset]; + offset += COM_NUMBER_OF_CHANNELS; + } YVV(src_width); - for (x = 0; x < src_width; ++x) - buffer[(x + yx) * COM_NUMBER_OF_CHANNELS + chan] = Y[x]; + offset = yx * COM_NUMBER_OF_CHANNELS + chan; + for (x = 0; x < src_width; ++x) { + buffer[offset] = Y[x]; + offset += COM_NUMBER_OF_CHANNELS; + } } } if (xy & 2) { // V + int offset; + const int add = src_width * COM_NUMBER_OF_CHANNELS; + for (x = 0; x < src_width; ++x) { - for (y = 0; y < src_height; ++y) - X[y] = buffer[(x + y * src_width) * COM_NUMBER_OF_CHANNELS + chan]; + offset = x * COM_NUMBER_OF_CHANNELS + chan; + for (y = 0; y < src_height; ++y) { + X[y] = buffer[offset]; + offset += add; + } YVV(src_height); - for (y = 0; y < src_height; ++y) - buffer[(x + y * src_width) * COM_NUMBER_OF_CHANNELS + chan] = Y[y]; + offset = x * COM_NUMBER_OF_CHANNELS + chan; + for (y = 0; y < src_height; ++y) { + buffer[offset] = Y[y]; + offset += add; + } } } diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h index 58bf1d4f596..e12d437b43e 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h @@ -28,16 +28,19 @@ class FastGaussianBlurOperation : public BlurBaseOperation { private: - float m_sx; - float m_sy; MemoryBuffer *m_iirgaus; + int m_chunksize; + public: FastGaussianBlurOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); void executePixel(float output[4], int x, int y, void *data); + void setChunksize(int size) { this->m_chunksize = size; } static void IIR_gauss(MemoryBuffer *src, float sigma, unsigned int channel, unsigned int xy); + bool getDAI(rcti *rect, rcti *output); void *initializeTileData(rcti *rect); + void deinitializeTileData(rcti *rect, void *data); void deinitExecution(); void initExecution(); }; diff --git a/source/blender/compositor/operations/COM_FlipOperation.cpp b/source/blender/compositor/operations/COM_FlipOperation.cpp index 526eba34d86..3de2ae9dabc 100644 --- a/source/blender/compositor/operations/COM_FlipOperation.cpp +++ b/source/blender/compositor/operations/COM_FlipOperation.cpp @@ -42,12 +42,12 @@ void FlipOperation::deinitExecution() } -void FlipOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void FlipOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float nx = this->m_flipX ? this->getWidth() - 1 - x : x; float ny = this->m_flipY ? this->getHeight() - 1 - y : y; - this->m_inputOperation->read(output, nx, ny, sampler); + this->m_inputOperation->readSampled(output, nx, ny, sampler); } bool FlipOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) diff --git a/source/blender/compositor/operations/COM_FlipOperation.h b/source/blender/compositor/operations/COM_FlipOperation.h index 018617cea8a..a1fcde19876 100644 --- a/source/blender/compositor/operations/COM_FlipOperation.h +++ b/source/blender/compositor/operations/COM_FlipOperation.h @@ -33,7 +33,7 @@ private: public: FlipOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp b/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp index 8f92dc02a57..357677d6832 100644 --- a/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp +++ b/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp @@ -34,10 +34,10 @@ void GammaCorrectOperation::initExecution() this->m_inputProgram = this->getInputSocketReader(0); } -void GammaCorrectOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void GammaCorrectOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor[4]; - this->m_inputProgram->read(inputColor, x, y, sampler); + this->m_inputProgram->readSampled(inputColor, x, y, sampler); if (inputColor[3] > 0.0f) { inputColor[0] /= inputColor[3]; inputColor[1] /= inputColor[3]; @@ -73,10 +73,10 @@ void GammaUncorrectOperation::initExecution() this->m_inputProgram = this->getInputSocketReader(0); } -void GammaUncorrectOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void GammaUncorrectOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor[4]; - this->m_inputProgram->read(inputColor, x, y, sampler); + this->m_inputProgram->readSampled(inputColor, x, y, sampler); if (inputColor[3] > 0.0f) { inputColor[0] /= inputColor[3]; diff --git a/source/blender/compositor/operations/COM_GammaCorrectOperation.h b/source/blender/compositor/operations/COM_GammaCorrectOperation.h index 514855b4f56..68eaab83c99 100644 --- a/source/blender/compositor/operations/COM_GammaCorrectOperation.h +++ b/source/blender/compositor/operations/COM_GammaCorrectOperation.h @@ -38,7 +38,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution @@ -64,7 +64,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_GammaOperation.cpp b/source/blender/compositor/operations/COM_GammaOperation.cpp index 326031c5984..d98f2c4663f 100644 --- a/source/blender/compositor/operations/COM_GammaOperation.cpp +++ b/source/blender/compositor/operations/COM_GammaOperation.cpp @@ -37,13 +37,13 @@ void GammaOperation::initExecution() this->m_inputGammaProgram = this->getInputSocketReader(1); } -void GammaOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void GammaOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue[4]; float inputGamma[4]; - this->m_inputProgram->read(inputValue, x, y, sampler); - this->m_inputGammaProgram->read(inputGamma, x, y, sampler); + this->m_inputProgram->readSampled(inputValue, x, y, sampler); + this->m_inputGammaProgram->readSampled(inputGamma, x, y, sampler); const float gamma = inputGamma[0]; /* check for negative to avoid nan's */ output[0] = inputValue[0] > 0.0f ? powf(inputValue[0], gamma) : inputValue[0]; diff --git a/source/blender/compositor/operations/COM_GammaOperation.h b/source/blender/compositor/operations/COM_GammaOperation.h index 4482f7be34a..d8e08457812 100644 --- a/source/blender/compositor/operations/COM_GammaOperation.h +++ b/source/blender/compositor/operations/COM_GammaOperation.h @@ -39,7 +39,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp b/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp index 1c7d2659c39..78e1e80cafc 100644 --- a/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp @@ -42,11 +42,11 @@ void GlareThresholdOperation::initExecution() this->m_inputProgram = this->getInputSocketReader(0); } -void GlareThresholdOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void GlareThresholdOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { const float threshold = this->m_settings->threshold; - this->m_inputProgram->read(output, x, y, sampler); + this->m_inputProgram->readSampled(output, x, y, sampler); if (rgb_to_luma_y(output) >= threshold) { output[0] -= threshold, output[1] -= threshold, output[2] -= threshold; output[0] = max(output[0], 0.0f); diff --git a/source/blender/compositor/operations/COM_GlareThresholdOperation.h b/source/blender/compositor/operations/COM_GlareThresholdOperation.h index 44f9db6a483..7760a19251b 100644 --- a/source/blender/compositor/operations/COM_GlareThresholdOperation.h +++ b/source/blender/compositor/operations/COM_GlareThresholdOperation.h @@ -42,7 +42,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp index 8f58942fbe2..6bbaac8e303 100644 --- a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp +++ b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp @@ -45,11 +45,11 @@ void HueSaturationValueCorrectOperation::initExecution() this->m_inputProgram = this->getInputSocketReader(0); } -void HueSaturationValueCorrectOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void HueSaturationValueCorrectOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float hsv[4], f; - this->m_inputProgram->read(hsv, x, y, sampler); + this->m_inputProgram->readSampled(hsv, x, y, sampler); /* adjust hue, scaling returned default 0.5 up to 1 */ f = curvemapping_evaluateF(this->m_curveMapping, 0, hsv[0]); diff --git a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h index 5e57d09a51e..0a0e82bf168 100644 --- a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h +++ b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h @@ -37,7 +37,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_IDMaskOperation.cpp b/source/blender/compositor/operations/COM_IDMaskOperation.cpp index 4b9bcb118e7..a021f07d2a7 100644 --- a/source/blender/compositor/operations/COM_IDMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_IDMaskOperation.cpp @@ -33,11 +33,11 @@ void IDMaskOperation::initExecution() this->m_inputProgram = this->getInputSocketReader(0); } -void IDMaskOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void IDMaskOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue[4]; - this->m_inputProgram->read(inputValue, x, y, sampler); + this->m_inputProgram->readSampled(inputValue, x, y, sampler); const float a = (inputValue[0] == this->m_objectIndex) ? 1.0f : 0.0f; output[0] = a; } diff --git a/source/blender/compositor/operations/COM_IDMaskOperation.h b/source/blender/compositor/operations/COM_IDMaskOperation.h index 68c5cf4c1dc..dfddc489ca4 100644 --- a/source/blender/compositor/operations/COM_IDMaskOperation.h +++ b/source/blender/compositor/operations/COM_IDMaskOperation.h @@ -39,7 +39,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_ImageOperation.cpp b/source/blender/compositor/operations/COM_ImageOperation.cpp index cface29fdca..adc325de377 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.cpp +++ b/source/blender/compositor/operations/COM_ImageOperation.cpp @@ -146,7 +146,7 @@ static void sampleImageAtLocation(ImBuf *ibuf, float x, float y, PixelSampler sa } } -void ImageOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ImageOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { if ((this->m_imageFloatBuffer == NULL && this->m_imageByteBuffer == NULL) || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) { zero_v4(output); @@ -156,7 +156,7 @@ void ImageOperation::executePixel(float output[4], float x, float y, PixelSample } } -void ImageAlphaOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ImageAlphaOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float tempcolor[4]; @@ -170,7 +170,7 @@ void ImageAlphaOperation::executePixel(float output[4], float x, float y, PixelS } } -void ImageDepthOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ImageDepthOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { if (this->m_depthBuffer == NULL || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) { output[0] = 0.0f; diff --git a/source/blender/compositor/operations/COM_ImageOperation.h b/source/blender/compositor/operations/COM_ImageOperation.h index b51f11edd04..a9e2ed9ff64 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.h +++ b/source/blender/compositor/operations/COM_ImageOperation.h @@ -73,7 +73,7 @@ public: * Constructor */ ImageOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class ImageAlphaOperation : public BaseImageOperation { public: @@ -81,7 +81,7 @@ public: * Constructor */ ImageAlphaOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class ImageDepthOperation : public BaseImageOperation { public: @@ -89,6 +89,6 @@ public: * Constructor */ ImageDepthOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; #endif diff --git a/source/blender/compositor/operations/COM_InpaintOperation.cpp b/source/blender/compositor/operations/COM_InpaintOperation.cpp index edcd1563e03..b64c98be0c7 100644 --- a/source/blender/compositor/operations/COM_InpaintOperation.cpp +++ b/source/blender/compositor/operations/COM_InpaintOperation.cpp @@ -48,7 +48,6 @@ void InpaintSimpleOperation::initExecution() { this->m_inputImageProgram = this->getInputSocketReader(0); - this->m_cached_buffer = NULL; this->m_pixelorder = NULL; this->m_manhatten_distance = NULL; this->m_cached_buffer = NULL; diff --git a/source/blender/compositor/operations/COM_InvertOperation.cpp b/source/blender/compositor/operations/COM_InvertOperation.cpp index 9c2dd825709..dc5a2653129 100644 --- a/source/blender/compositor/operations/COM_InvertOperation.cpp +++ b/source/blender/compositor/operations/COM_InvertOperation.cpp @@ -39,12 +39,12 @@ void InvertOperation::initExecution() this->m_inputColorProgram = this->getInputSocketReader(1); } -void InvertOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void InvertOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue[4]; float inputColor[4]; - this->m_inputValueProgram->read(inputValue, x, y, sampler); - this->m_inputColorProgram->read(inputColor, x, y, sampler); + this->m_inputValueProgram->readSampled(inputValue, x, y, sampler); + this->m_inputColorProgram->readSampled(inputColor, x, y, sampler); const float value = inputValue[0]; const float invertedValue = 1.0f - value; diff --git a/source/blender/compositor/operations/COM_InvertOperation.h b/source/blender/compositor/operations/COM_InvertOperation.h index 7fded7bb1e4..be1e933f1e9 100644 --- a/source/blender/compositor/operations/COM_InvertOperation.h +++ b/source/blender/compositor/operations/COM_InvertOperation.h @@ -42,7 +42,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_KeyingDespillOperation.cpp b/source/blender/compositor/operations/COM_KeyingDespillOperation.cpp index 01f5c032730..c4b821f998f 100644 --- a/source/blender/compositor/operations/COM_KeyingDespillOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingDespillOperation.cpp @@ -53,13 +53,13 @@ void KeyingDespillOperation::deinitExecution() this->m_screenReader = NULL; } -void KeyingDespillOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void KeyingDespillOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float pixelColor[4]; float screenColor[4]; - this->m_pixelReader->read(pixelColor, x, y, sampler); - this->m_screenReader->read(screenColor, x, y, sampler); + this->m_pixelReader->readSampled(pixelColor, x, y, sampler); + this->m_screenReader->readSampled(screenColor, x, y, sampler); const int screen_primary_channel = max_axis_v3(screenColor); const int other_1 = (screen_primary_channel + 1) % 3; diff --git a/source/blender/compositor/operations/COM_KeyingDespillOperation.h b/source/blender/compositor/operations/COM_KeyingDespillOperation.h index 18e771b14f1..da9924d5b4b 100644 --- a/source/blender/compositor/operations/COM_KeyingDespillOperation.h +++ b/source/blender/compositor/operations/COM_KeyingDespillOperation.h @@ -45,7 +45,7 @@ public: void setDespillFactor(float value) {this->m_despillFactor = value;} void setColorBalance(float value) {this->m_colorBalance = value;} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; #endif diff --git a/source/blender/compositor/operations/COM_KeyingOperation.cpp b/source/blender/compositor/operations/COM_KeyingOperation.cpp index baeacb56744..e2566d2f4f0 100644 --- a/source/blender/compositor/operations/COM_KeyingOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingOperation.cpp @@ -65,13 +65,13 @@ void KeyingOperation::deinitExecution() this->m_screenReader = NULL; } -void KeyingOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void KeyingOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float pixelColor[4]; float screenColor[4]; - this->m_pixelReader->read(pixelColor, x, y, sampler); - this->m_screenReader->read(screenColor, x, y, sampler); + this->m_pixelReader->readSampled(pixelColor, x, y, sampler); + this->m_screenReader->readSampled(screenColor, x, y, sampler); const int primary_channel = max_axis_v3(screenColor); diff --git a/source/blender/compositor/operations/COM_KeyingOperation.h b/source/blender/compositor/operations/COM_KeyingOperation.h index fcff9243dfc..e4542e2c6dd 100644 --- a/source/blender/compositor/operations/COM_KeyingOperation.h +++ b/source/blender/compositor/operations/COM_KeyingOperation.h @@ -49,7 +49,7 @@ public: void setScreenBalance(float value) {this->m_screenBalance = value;} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; #endif diff --git a/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp b/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp index 4c65113ee70..0e48d5963c6 100644 --- a/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp @@ -40,7 +40,7 @@ void LuminanceMatteOperation::deinitExecution() this->m_inputImageProgram = NULL; } -void LuminanceMatteOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void LuminanceMatteOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inColor[4]; @@ -49,7 +49,7 @@ void LuminanceMatteOperation::executePixel(float output[4], float x, float y, Pi float alpha; - this->m_inputImageProgram->read(inColor, x, y, sampler); + this->m_inputImageProgram->readSampled(inColor, x, y, sampler); /* one line thread-friend algorithm: * output[0] = max(inputValue[3], min(high, max(low, ((inColor[0]-low)/(high-low)))) diff --git a/source/blender/compositor/operations/COM_LuminanceMatteOperation.h b/source/blender/compositor/operations/COM_LuminanceMatteOperation.h index cb8cc01efea..93051f52228 100644 --- a/source/blender/compositor/operations/COM_LuminanceMatteOperation.h +++ b/source/blender/compositor/operations/COM_LuminanceMatteOperation.h @@ -41,7 +41,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_MapRangeOperation.cpp b/source/blender/compositor/operations/COM_MapRangeOperation.cpp index 1fe74ade0fc..2e80d4f1ba3 100644 --- a/source/blender/compositor/operations/COM_MapRangeOperation.cpp +++ b/source/blender/compositor/operations/COM_MapRangeOperation.cpp @@ -46,18 +46,18 @@ void MapRangeOperation::initExecution() /* The code below assumes all data is inside range +- this, and that input buffer is single channel */ #define BLENDER_ZMAX 10000.0f -void MapRangeOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MapRangeOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputs[8]; /* includes the 5 inputs + 3 pads */ float value; float source_min, source_max; float dest_min, dest_max; - this->m_inputOperation->read(inputs, x, y, sampler); - this->m_sourceMinOperation->read(inputs + 1, x, y, sampler); - this->m_sourceMaxOperation->read(inputs + 2, x, y, sampler); - this->m_destMinOperation->read(inputs + 3, x, y, sampler); - this->m_destMaxOperation->read(inputs + 4, x, y, sampler); + this->m_inputOperation->readSampled(inputs, x, y, sampler); + this->m_sourceMinOperation->readSampled(inputs + 1, x, y, sampler); + this->m_sourceMaxOperation->readSampled(inputs + 2, x, y, sampler); + this->m_destMinOperation->readSampled(inputs + 3, x, y, sampler); + this->m_destMaxOperation->readSampled(inputs + 4, x, y, sampler); value = inputs[0]; source_min = inputs[1]; diff --git a/source/blender/compositor/operations/COM_MapRangeOperation.h b/source/blender/compositor/operations/COM_MapRangeOperation.h index 00dfc68168c..a232f89ea9d 100644 --- a/source/blender/compositor/operations/COM_MapRangeOperation.h +++ b/source/blender/compositor/operations/COM_MapRangeOperation.h @@ -50,7 +50,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_MapUVOperation.cpp b/source/blender/compositor/operations/COM_MapUVOperation.cpp index a9b6ad3edc1..289b447dec7 100644 --- a/source/blender/compositor/operations/COM_MapUVOperation.cpp +++ b/source/blender/compositor/operations/COM_MapUVOperation.cpp @@ -40,7 +40,7 @@ void MapUVOperation::initExecution() this->m_inputUVProgram = this->getInputSocketReader(1); } -void MapUVOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MapUVOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputUV[4]; float uv_a[4], uv_b[4]; @@ -50,22 +50,22 @@ void MapUVOperation::executePixel(float output[4], float x, float y, PixelSample float uv_l, uv_r; float uv_u, uv_d; - this->m_inputUVProgram->read(inputUV, x, y, sampler); + this->m_inputUVProgram->readSampled(inputUV, x, y, sampler); if (inputUV[2] == 0.f) { zero_v4(output); return; } /* adaptive sampling, red (U) channel */ - this->m_inputUVProgram->read(uv_a, x - 1, y, COM_PS_NEAREST); - this->m_inputUVProgram->read(uv_b, x + 1, y, COM_PS_NEAREST); + this->m_inputUVProgram->readSampled(uv_a, x - 1, y, COM_PS_NEAREST); + this->m_inputUVProgram->readSampled(uv_b, x + 1, y, COM_PS_NEAREST); 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->m_inputUVProgram->read(uv_a, x, y - 1, COM_PS_NEAREST); - this->m_inputUVProgram->read(uv_b, x, y + 1, COM_PS_NEAREST); + this->m_inputUVProgram->readSampled(uv_a, x, y - 1, COM_PS_NEAREST); + this->m_inputUVProgram->readSampled(uv_b, x, y + 1, COM_PS_NEAREST); 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; @@ -81,7 +81,7 @@ void MapUVOperation::executePixel(float output[4], float x, float y, PixelSample u = inputUV[0] * this->m_inputColorProgram->getWidth(); v = inputUV[1] * this->m_inputColorProgram->getHeight(); - this->m_inputColorProgram->read(output, u, v, dx, dy, COM_PS_NEAREST); + this->m_inputColorProgram->readFiltered(output, u, v, dx, dy, COM_PS_NEAREST); /* "premul" */ if (alpha < 1.0f) { diff --git a/source/blender/compositor/operations/COM_MapUVOperation.h b/source/blender/compositor/operations/COM_MapUVOperation.h index c8356c1a7ad..fe8bfd2a9ac 100644 --- a/source/blender/compositor/operations/COM_MapUVOperation.h +++ b/source/blender/compositor/operations/COM_MapUVOperation.h @@ -45,7 +45,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_MapValueOperation.cpp b/source/blender/compositor/operations/COM_MapValueOperation.cpp index 7acc431f7b5..d6aaf560fce 100644 --- a/source/blender/compositor/operations/COM_MapValueOperation.cpp +++ b/source/blender/compositor/operations/COM_MapValueOperation.cpp @@ -34,10 +34,10 @@ void MapValueOperation::initExecution() this->m_inputOperation = this->getInputSocketReader(0); } -void MapValueOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MapValueOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float src[4]; - this->m_inputOperation->read(src, x, y, sampler); + this->m_inputOperation->readSampled(src, x, y, sampler); TexMapping *texmap = this->m_settings; float value = (src[0] + texmap->loc[0]) * texmap->size[0]; if (texmap->flag & TEXMAP_CLIP_MIN) diff --git a/source/blender/compositor/operations/COM_MapValueOperation.h b/source/blender/compositor/operations/COM_MapValueOperation.h index 418d6d9bf4d..a9a59d6633a 100644 --- a/source/blender/compositor/operations/COM_MapValueOperation.h +++ b/source/blender/compositor/operations/COM_MapValueOperation.h @@ -45,7 +45,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp index ba1059c4eb5..a5b1987d4b3 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.cpp +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -75,7 +75,7 @@ void MaskOperation::initExecution() masklay; masklay = masklay->next) { - masklay_shape = BKE_mask_layer_shape_varify_frame(masklay, this->m_frame_number); + masklay_shape = BKE_mask_layer_shape_verify_frame(masklay, this->m_frame_number); BKE_mask_layer_shape_from_mask(masklay, masklay_shape); } } @@ -84,7 +84,7 @@ void MaskOperation::initExecution() this->m_rasterMaskHandles[i] = BKE_maskrasterize_handle_new(); /* re-eval frame info */ - BKE_mask_evaluate(mask_temp, frame_iter, TRUE); + BKE_mask_evaluate(mask_temp, frame_iter, true); BKE_maskrasterize_handle_init(this->m_rasterMaskHandles[i], mask_temp, this->m_maskWidth, this->m_maskHeight, @@ -127,7 +127,7 @@ void MaskOperation::determineResolution(unsigned int resolution[2], unsigned int } } -void MaskOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MaskOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { const float xy[2] = {x * this->m_maskWidthInv, y * this->m_maskHeightInv}; diff --git a/source/blender/compositor/operations/COM_MaskOperation.h b/source/blender/compositor/operations/COM_MaskOperation.h index 2de71afcfa7..18d7e594104 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.h +++ b/source/blender/compositor/operations/COM_MaskOperation.h @@ -83,7 +83,7 @@ public: void setMotionBlurSamples(int samples) { this->m_rasterMaskHandleTot = min(max(1, samples), CMP_NODE_MASK_MBLUR_SAMPLES_MAX); } void setMotionBlurShutter(float shutter) { this->m_frame_shutter = shutter; } - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; #endif diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.cpp b/source/blender/compositor/operations/COM_MathBaseOperation.cpp index fa0c480eb70..cc7511bb9fc 100644 --- a/source/blender/compositor/operations/COM_MathBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_MathBaseOperation.cpp @@ -72,52 +72,52 @@ void MathBaseOperation::clampIfNeeded(float *color) } } -void MathAddOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MathAddOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(inputValue1, x, y, sampler); - this->m_inputValue2Operation->read(inputValue2, x, y, sampler); + this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler); + this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler); output[0] = inputValue1[0] + inputValue2[0]; clampIfNeeded(output); } -void MathSubtractOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MathSubtractOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(inputValue1, x, y, sampler); - this->m_inputValue2Operation->read(inputValue2, x, y, sampler); + this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler); + this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler); output[0] = inputValue1[0] - inputValue2[0]; clampIfNeeded(output); } -void MathMultiplyOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MathMultiplyOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(inputValue1, x, y, sampler); - this->m_inputValue2Operation->read(inputValue2, x, y, sampler); + this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler); + this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler); output[0] = inputValue1[0] * inputValue2[0]; clampIfNeeded(output); } -void MathDivideOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MathDivideOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(inputValue1, x, y, sampler); - this->m_inputValue2Operation->read(inputValue2, x, y, sampler); + this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler); + this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler); if (inputValue2[0] == 0) /* We don't want to divide by zero. */ output[0] = 0.0; @@ -127,52 +127,52 @@ void MathDivideOperation::executePixel(float output[4], float x, float y, PixelS clampIfNeeded(output); } -void MathSineOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MathSineOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(inputValue1, x, y, sampler); - this->m_inputValue2Operation->read(inputValue2, x, y, sampler); + this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler); + this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler); output[0] = sin(inputValue1[0]); clampIfNeeded(output); } -void MathCosineOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MathCosineOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(inputValue1, x, y, sampler); - this->m_inputValue2Operation->read(inputValue2, x, y, sampler); + this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler); + this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler); output[0] = cos(inputValue1[0]); clampIfNeeded(output); } -void MathTangentOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MathTangentOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(inputValue1, x, y, sampler); - this->m_inputValue2Operation->read(inputValue2, x, y, sampler); + this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler); + this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler); output[0] = tan(inputValue1[0]); clampIfNeeded(output); } -void MathArcSineOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MathArcSineOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(inputValue1, x, y, sampler); - this->m_inputValue2Operation->read(inputValue2, x, y, sampler); + this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler); + this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler); if (inputValue1[0] <= 1 && inputValue1[0] >= -1) output[0] = asin(inputValue1[0]); @@ -182,13 +182,13 @@ void MathArcSineOperation::executePixel(float output[4], float x, float y, Pixel clampIfNeeded(output); } -void MathArcCosineOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MathArcCosineOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(inputValue1, x, y, sampler); - this->m_inputValue2Operation->read(inputValue2, x, y, sampler); + this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler); + this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler); if (inputValue1[0] <= 1 && inputValue1[0] >= -1) output[0] = acos(inputValue1[0]); @@ -198,26 +198,26 @@ void MathArcCosineOperation::executePixel(float output[4], float x, float y, Pix clampIfNeeded(output); } -void MathArcTangentOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MathArcTangentOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(inputValue1, x, y, sampler); - this->m_inputValue2Operation->read(inputValue2, x, y, sampler); + this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler); + this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler); output[0] = atan(inputValue1[0]); clampIfNeeded(output); } -void MathPowerOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MathPowerOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(inputValue1, x, y, sampler); - this->m_inputValue2Operation->read(inputValue2, x, y, sampler); + this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler); + this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler); if (inputValue1[0] >= 0) { output[0] = pow(inputValue1[0], inputValue2[0]); @@ -236,13 +236,13 @@ void MathPowerOperation::executePixel(float output[4], float x, float y, PixelSa clampIfNeeded(output); } -void MathLogarithmOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MathLogarithmOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(inputValue1, x, y, sampler); - this->m_inputValue2Operation->read(inputValue2, x, y, sampler); + this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler); + this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler); if (inputValue1[0] > 0 && inputValue2[0] > 0) output[0] = log(inputValue1[0]) / log(inputValue2[0]); @@ -252,78 +252,78 @@ void MathLogarithmOperation::executePixel(float output[4], float x, float y, Pix clampIfNeeded(output); } -void MathMinimumOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MathMinimumOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(inputValue1, x, y, sampler); - this->m_inputValue2Operation->read(inputValue2, x, y, sampler); + this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler); + this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler); output[0] = min(inputValue1[0], inputValue2[0]); clampIfNeeded(output); } -void MathMaximumOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MathMaximumOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(inputValue1, x, y, sampler); - this->m_inputValue2Operation->read(inputValue2, x, y, sampler); + this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler); + this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler); output[0] = max(inputValue1[0], inputValue2[0]); clampIfNeeded(output); } -void MathRoundOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MathRoundOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(inputValue1, x, y, sampler); - this->m_inputValue2Operation->read(inputValue2, x, y, sampler); + this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler); + this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler); output[0] = round(inputValue1[0]); clampIfNeeded(output); } -void MathLessThanOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MathLessThanOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(inputValue1, x, y, sampler); - this->m_inputValue2Operation->read(inputValue2, x, y, sampler); + this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler); + this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler); output[0] = inputValue1[0] < inputValue2[0] ? 1.0f : 0.0f; clampIfNeeded(output); } -void MathGreaterThanOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MathGreaterThanOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(inputValue1, x, y, sampler); - this->m_inputValue2Operation->read(inputValue2, x, y, sampler); + this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler); + this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler); output[0] = inputValue1[0] > inputValue2[0] ? 1.0f : 0.0f; clampIfNeeded(output); } -void MathModuloOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MathModuloOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(inputValue1, x, y, sampler); - this->m_inputValue2Operation->read(inputValue2, x, y, sampler); + this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler); + this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler); if (inputValue2[0] == 0) output[0] = 0.0; diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.h b/source/blender/compositor/operations/COM_MathBaseOperation.h index 649a9688037..4ea7c43a67d 100644 --- a/source/blender/compositor/operations/COM_MathBaseOperation.h +++ b/source/blender/compositor/operations/COM_MathBaseOperation.h @@ -50,7 +50,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler) = 0; + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) = 0; /** * Initialize the execution @@ -73,94 +73,94 @@ public: class MathAddOperation : public MathBaseOperation { public: MathAddOperation() : MathBaseOperation() {} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MathSubtractOperation : public MathBaseOperation { public: MathSubtractOperation() : MathBaseOperation() {} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MathMultiplyOperation : public MathBaseOperation { public: MathMultiplyOperation() : MathBaseOperation() {} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MathDivideOperation : public MathBaseOperation { public: MathDivideOperation() : MathBaseOperation() {} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MathSineOperation : public MathBaseOperation { public: MathSineOperation() : MathBaseOperation() {} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MathCosineOperation : public MathBaseOperation { public: MathCosineOperation() : MathBaseOperation() {} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MathTangentOperation : public MathBaseOperation { public: MathTangentOperation() : MathBaseOperation() {} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MathArcSineOperation : public MathBaseOperation { public: MathArcSineOperation() : MathBaseOperation() {} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MathArcCosineOperation : public MathBaseOperation { public: MathArcCosineOperation() : MathBaseOperation() {} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MathArcTangentOperation : public MathBaseOperation { public: MathArcTangentOperation() : MathBaseOperation() {} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MathPowerOperation : public MathBaseOperation { public: MathPowerOperation() : MathBaseOperation() {} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MathLogarithmOperation : public MathBaseOperation { public: MathLogarithmOperation() : MathBaseOperation() {} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MathMinimumOperation : public MathBaseOperation { public: MathMinimumOperation() : MathBaseOperation() {} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MathMaximumOperation : public MathBaseOperation { public: MathMaximumOperation() : MathBaseOperation() {} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MathRoundOperation : public MathBaseOperation { public: MathRoundOperation() : MathBaseOperation() {} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MathLessThanOperation : public MathBaseOperation { public: MathLessThanOperation() : MathBaseOperation() {} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MathGreaterThanOperation : public MathBaseOperation { public: MathGreaterThanOperation() : MathBaseOperation() {} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MathModuloOperation : public MathBaseOperation { public: MathModuloOperation() : MathBaseOperation() {} - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; #endif diff --git a/source/blender/compositor/operations/COM_MixOperation.cpp b/source/blender/compositor/operations/COM_MixOperation.cpp index f094e93f147..9781cb4e162 100644 --- a/source/blender/compositor/operations/COM_MixOperation.cpp +++ b/source/blender/compositor/operations/COM_MixOperation.cpp @@ -48,15 +48,15 @@ void MixBaseOperation::initExecution() this->m_inputColor2Operation = this->getInputSocketReader(2); } -void MixBaseOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixBaseOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); float value = inputValue[0]; if (this->useValueAlphaMultiply()) { @@ -107,15 +107,15 @@ MixAddOperation::MixAddOperation() : MixBaseOperation() /* pass */ } -void MixAddOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixAddOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); float value = inputValue[0]; if (this->useValueAlphaMultiply()) { @@ -136,16 +136,16 @@ MixBlendOperation::MixBlendOperation() : MixBaseOperation() /* pass */ } -void MixBlendOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixBlendOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; float value; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); value = inputValue[0]; if (this->useValueAlphaMultiply()) { @@ -167,16 +167,16 @@ MixBurnOperation::MixBurnOperation() : MixBaseOperation() /* pass */ } -void MixBurnOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixBurnOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; float tmp; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); float value = inputValue[0]; if (this->useValueAlphaMultiply()) { @@ -235,15 +235,15 @@ MixColorOperation::MixColorOperation() : MixBaseOperation() /* pass */ } -void MixColorOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); float value = inputValue[0]; if (this->useValueAlphaMultiply()) { @@ -277,15 +277,15 @@ MixDarkenOperation::MixDarkenOperation() : MixBaseOperation() /* pass */ } -void MixDarkenOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixDarkenOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); float value = inputValue[0]; if (this->useValueAlphaMultiply()) { @@ -315,15 +315,15 @@ MixDifferenceOperation::MixDifferenceOperation() : MixBaseOperation() /* pass */ } -void MixDifferenceOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixDifferenceOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); float value = inputValue[0]; if (this->useValueAlphaMultiply()) { @@ -345,15 +345,15 @@ MixDivideOperation::MixDivideOperation() : MixBaseOperation() /* pass */ } -void MixDivideOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixDivideOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); float value = inputValue[0]; if (this->useValueAlphaMultiply()) { @@ -386,16 +386,16 @@ MixDodgeOperation::MixDodgeOperation() : MixBaseOperation() /* pass */ } -void MixDodgeOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixDodgeOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; float tmp; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); float value = inputValue[0]; if (this->useValueAlphaMultiply()) { @@ -459,16 +459,16 @@ MixGlareOperation::MixGlareOperation() : MixBaseOperation() /* pass */ } -void MixGlareOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixGlareOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; float value; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); value = inputValue[0]; float mf = 2.f - 2.f * fabsf(value - 0.5f); @@ -491,15 +491,15 @@ MixHueOperation::MixHueOperation() : MixBaseOperation() /* pass */ } -void MixHueOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixHueOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); float value = inputValue[0]; if (this->useValueAlphaMultiply()) { @@ -533,15 +533,15 @@ MixLightenOperation::MixLightenOperation() : MixBaseOperation() /* pass */ } -void MixLightenOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixLightenOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); float value = inputValue[0]; if (this->useValueAlphaMultiply()) { @@ -569,15 +569,15 @@ MixLinearLightOperation::MixLinearLightOperation() : MixBaseOperation() /* pass */ } -void MixLinearLightOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixLinearLightOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); float value = inputValue[0]; if (this->useValueAlphaMultiply()) { @@ -608,15 +608,15 @@ MixMultiplyOperation::MixMultiplyOperation() : MixBaseOperation() /* pass */ } -void MixMultiplyOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixMultiplyOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); float value = inputValue[0]; if (this->useValueAlphaMultiply()) { @@ -638,15 +638,15 @@ MixOverlayOperation::MixOverlayOperation() : MixBaseOperation() /* pass */ } -void MixOverlayOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixOverlayOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); float value = inputValue[0]; if (this->useValueAlphaMultiply()) { @@ -685,15 +685,15 @@ MixSaturationOperation::MixSaturationOperation() : MixBaseOperation() /* pass */ } -void MixSaturationOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixSaturationOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); float value = inputValue[0]; if (this->useValueAlphaMultiply()) { @@ -724,15 +724,15 @@ MixScreenOperation::MixScreenOperation() : MixBaseOperation() /* pass */ } -void MixScreenOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixScreenOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); float value = inputValue[0]; if (this->useValueAlphaMultiply()) { @@ -755,15 +755,15 @@ MixSoftLightOperation::MixSoftLightOperation() : MixBaseOperation() /* pass */ } -void MixSoftLightOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) \ +void MixSoftLightOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) \ { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); float value = inputValue[0]; if (this->useValueAlphaMultiply()) { @@ -792,15 +792,15 @@ MixSubtractOperation::MixSubtractOperation() : MixBaseOperation() /* pass */ } -void MixSubtractOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixSubtractOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); float value = inputValue[0]; if (this->useValueAlphaMultiply()) { @@ -821,15 +821,15 @@ MixValueOperation::MixValueOperation() : MixBaseOperation() /* pass */ } -void MixValueOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MixValueOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float inputColor1[4]; float inputColor2[4]; float inputValue[4]; - this->m_inputValueOperation->read(inputValue, x, y, sampler); - this->m_inputColor1Operation->read(inputColor1, x, y, sampler); - this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + this->m_inputValueOperation->readSampled(inputValue, x, y, sampler); + this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler); + this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler); float value = inputValue[0]; if (this->useValueAlphaMultiply()) { diff --git a/source/blender/compositor/operations/COM_MixOperation.h b/source/blender/compositor/operations/COM_MixOperation.h index 93dbe6f36a6..479ce161eea 100644 --- a/source/blender/compositor/operations/COM_MixOperation.h +++ b/source/blender/compositor/operations/COM_MixOperation.h @@ -60,7 +60,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution @@ -83,115 +83,115 @@ public: class MixAddOperation : public MixBaseOperation { public: MixAddOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MixBlendOperation : public MixBaseOperation { public: MixBlendOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MixBurnOperation : public MixBaseOperation { public: MixBurnOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MixColorOperation : public MixBaseOperation { public: MixColorOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MixDarkenOperation : public MixBaseOperation { public: MixDarkenOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MixDifferenceOperation : public MixBaseOperation { public: MixDifferenceOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MixDivideOperation : public MixBaseOperation { public: MixDivideOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MixDodgeOperation : public MixBaseOperation { public: MixDodgeOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MixGlareOperation : public MixBaseOperation { public: MixGlareOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MixHueOperation : public MixBaseOperation { public: MixHueOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MixLightenOperation : public MixBaseOperation { public: MixLightenOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MixLinearLightOperation : public MixBaseOperation { public: MixLinearLightOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MixMultiplyOperation : public MixBaseOperation { public: MixMultiplyOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MixOverlayOperation : public MixBaseOperation { public: MixOverlayOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MixSaturationOperation : public MixBaseOperation { public: MixSaturationOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MixScreenOperation : public MixBaseOperation { public: MixScreenOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MixSoftLightOperation : public MixBaseOperation { public: MixSoftLightOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MixSubtractOperation : public MixBaseOperation { public: MixSubtractOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MixValueOperation : public MixBaseOperation { public: MixValueOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; #endif diff --git a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp index 0d2de47bc4f..fbbfa8fd65e 100644 --- a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp @@ -33,7 +33,7 @@ MovieClipAttributeOperation::MovieClipAttributeOperation() : NodeOperation() this->m_attribute = MCA_X; } -void MovieClipAttributeOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MovieClipAttributeOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { if (!this->m_valueSet) { float loc[2], scale, angle; diff --git a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h index f894626d534..49c86c7fafc 100644 --- a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h +++ b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h @@ -51,7 +51,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); void setMovieClip(MovieClip *clip) { this->m_clip = clip; } diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cpp b/source/blender/compositor/operations/COM_MovieClipOperation.cpp index 76dc093035c..5b75113e7f3 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieClipOperation.cpp @@ -86,7 +86,7 @@ void MovieClipBaseOperation::determineResolution(unsigned int resolution[2], uns } } -void MovieClipBaseOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MovieClipBaseOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { ImBuf *ibuf = this->m_movieClipBuffer; @@ -122,9 +122,9 @@ MovieClipAlphaOperation::MovieClipAlphaOperation() : MovieClipBaseOperation() this->addOutputSocket(COM_DT_VALUE); } -void MovieClipAlphaOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MovieClipAlphaOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { - MovieClipBaseOperation::executePixel(output, x, y, sampler); + MovieClipBaseOperation::executePixelSampled(output, x, y, sampler); output[0] = output[3]; output[1] = 0.0f; output[2] = 0.0f; diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.h b/source/blender/compositor/operations/COM_MovieClipOperation.h index a368dca423c..c16262cbd02 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.h +++ b/source/blender/compositor/operations/COM_MovieClipOperation.h @@ -57,7 +57,7 @@ public: void setCacheFrame(bool value) { this->m_cacheFrame = value; } void setFramenumber(int framenumber) { this->m_framenumber = framenumber; } - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MovieClipOperation : public MovieClipBaseOperation { @@ -68,7 +68,7 @@ public: class MovieClipAlphaOperation : public MovieClipBaseOperation { public: MovieClipAlphaOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; #endif diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp index 863a404ba67..bc792244dcb 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp @@ -29,7 +29,7 @@ extern "C" { } -vector<DistortionCache *> s_cache; +static vector<DistortionCache *> s_cache; void deintializeDistortionCache(void) { @@ -122,16 +122,16 @@ void MovieDistortionOperation::deinitExecution() } -void MovieDistortionOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MovieDistortionOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { if (this->m_cache != NULL) { float u, v; this->m_cache->getUV(&this->m_movieClip->tracking, x, y, &u, &v); - this->m_inputOperation->read(output, u, v, COM_PS_BILINEAR); + this->m_inputOperation->readSampled(output, u, v, COM_PS_BILINEAR); } else { - this->m_inputOperation->read(output, x, y, COM_PS_BILINEAR); + this->m_inputOperation->readSampled(output, x, y, COM_PS_BILINEAR); } } diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.h b/source/blender/compositor/operations/COM_MovieDistortionOperation.h index c9629451992..42c4a84f9b2 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.h +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.h @@ -156,7 +156,7 @@ protected: public: MovieDistortionOperation(bool distortion); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp index e2a95b2e33b..84c1fdfb6f5 100644 --- a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp +++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp @@ -42,7 +42,7 @@ ImBuf *MultilayerBaseOperation::getImBuf() return NULL; } -void MultilayerColorOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MultilayerColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { int yi = y; int xi = x; @@ -70,7 +70,7 @@ void MultilayerColorOperation::executePixel(float output[4], float x, float y, P } } -void MultilayerValueOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MultilayerValueOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { int yi = y; int xi = x; @@ -83,7 +83,7 @@ void MultilayerValueOperation::executePixel(float output[4], float x, float y, P } } -void MultilayerVectorOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MultilayerVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { int yi = y; int xi = x; diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.h b/source/blender/compositor/operations/COM_MultilayerImageOperation.h index 065bcc7da1e..37bee1b6a8c 100644 --- a/source/blender/compositor/operations/COM_MultilayerImageOperation.h +++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.h @@ -46,7 +46,7 @@ public: MultilayerColorOperation(int passindex) : MultilayerBaseOperation(passindex) { this->addOutputSocket(COM_DT_COLOR); } - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MultilayerValueOperation : public MultilayerBaseOperation { @@ -54,7 +54,7 @@ public: MultilayerValueOperation(int passindex) : MultilayerBaseOperation(passindex) { this->addOutputSocket(COM_DT_VALUE); } - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class MultilayerVectorOperation : public MultilayerBaseOperation { @@ -62,7 +62,7 @@ public: MultilayerVectorOperation(int passindex) : MultilayerBaseOperation(passindex) { this->addOutputSocket(COM_DT_VECTOR); } - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; #endif diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp index a5be993f241..c94387337c3 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp +++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp @@ -79,7 +79,7 @@ static void write_buffer_rect(rcti *rect, const bNodeTree *tree, for (y = y1; y < y2 && (!breaked); y++) { for (x = x1; x < x2 && (!breaked); x++) { - reader->read(color, x, y, COM_PS_NEAREST); + reader->readSampled(color, x, y, COM_PS_NEAREST); for (i = 0; i < size; ++i) buffer[offset + i] = color[i]; diff --git a/source/blender/compositor/operations/COM_PixelateOperation.cpp b/source/blender/compositor/operations/COM_PixelateOperation.cpp index 89e7f0093a1..eed6d1d01b9 100644 --- a/source/blender/compositor/operations/COM_PixelateOperation.cpp +++ b/source/blender/compositor/operations/COM_PixelateOperation.cpp @@ -40,10 +40,10 @@ void PixelateOperation::deinitExecution() this->m_inputOperation = NULL; } -void PixelateOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void PixelateOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float nx = round(x); float ny = round(y); - this->m_inputOperation->read(output, nx, ny, sampler); + this->m_inputOperation->readSampled(output, nx, ny, sampler); } diff --git a/source/blender/compositor/operations/COM_PixelateOperation.h b/source/blender/compositor/operations/COM_PixelateOperation.h index 83603a59331..8e60baf7f05 100644 --- a/source/blender/compositor/operations/COM_PixelateOperation.h +++ b/source/blender/compositor/operations/COM_PixelateOperation.h @@ -62,7 +62,7 @@ public: * @param y y-coordinate * @param sampler sampler */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; #endif diff --git a/source/blender/compositor/operations/COM_PlaneTrackMaskOperation.cpp b/source/blender/compositor/operations/COM_PlaneTrackMaskOperation.cpp index 8aa1324d8e2..58fa4bd08dc 100644 --- a/source/blender/compositor/operations/COM_PlaneTrackMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_PlaneTrackMaskOperation.cpp @@ -50,7 +50,7 @@ void PlaneTrackMaskOperation::initExecution() BLI_jitter_init(this->m_jitter[0], this->m_osa); } -void PlaneTrackMaskOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void PlaneTrackMaskOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float point[2]; diff --git a/source/blender/compositor/operations/COM_PlaneTrackMaskOperation.h b/source/blender/compositor/operations/COM_PlaneTrackMaskOperation.h index db32f9830e0..7f763954079 100644 --- a/source/blender/compositor/operations/COM_PlaneTrackMaskOperation.h +++ b/source/blender/compositor/operations/COM_PlaneTrackMaskOperation.h @@ -43,7 +43,7 @@ public: void initExecution(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; #endif diff --git a/source/blender/compositor/operations/COM_PlaneTrackWarpImageOperation.cpp b/source/blender/compositor/operations/COM_PlaneTrackWarpImageOperation.cpp index df487a766f3..dba3a6f3505 100644 --- a/source/blender/compositor/operations/COM_PlaneTrackWarpImageOperation.cpp +++ b/source/blender/compositor/operations/COM_PlaneTrackWarpImageOperation.cpp @@ -47,23 +47,17 @@ BLI_INLINE bool isPointInsideQuad(const float x, const float y, const float corn isect_point_tri_v2(point, corners[0], corners[2], corners[3]); } -BLI_INLINE bool resolveUV(const float x, const float y, const float corners[4][2], float uv[2]) +BLI_INLINE void warpCoord(float x, float y, float matrix[3][3], float uv[2]) { - float point[2]; - bool inside; - - inside = isPointInsideQuad(x, y, corners); - - point[0] = x; - point[1] = y; - - /* Use reverse bilinear to get UV coordinates within original frame */ - resolve_quad_uv(uv, point, corners[0], corners[1], corners[2], corners[3]); + float vec[3] = {x, y, 1.0f}; + mul_m3_v3(matrix, vec); + vec[0] /= vec[2]; + vec[1] /= vec[2]; - return inside; + copy_v2_v2(uv, vec); } -BLI_INLINE void resolveUVAndDxDy(const float x, const float y, const float corners[4][2], +BLI_INLINE void resolveUVAndDxDy(const float x, const float y, float matrix[3][3], float *u_r, float *v_r, float *dx_r, float *dy_r) { float inputUV[2]; @@ -73,23 +67,21 @@ BLI_INLINE void resolveUVAndDxDy(const float x, const float y, const float corne float uv_l, uv_r; float uv_u, uv_d; - bool ok1, ok2; - - resolveUV(x, y, corners, inputUV); + warpCoord(x, y, matrix, inputUV); /* adaptive sampling, red (U) channel */ - ok1 = resolveUV(x - 1, y, corners, uv_a); - ok2 = resolveUV(x + 1, y, corners, uv_b); - uv_l = ok1 ? fabsf(inputUV[0] - uv_a[0]) : 0.0f; - uv_r = ok2 ? fabsf(inputUV[0] - uv_b[0]) : 0.0f; + warpCoord(x - 1, y, matrix, uv_a); + warpCoord(x + 1, y, matrix, uv_b); + uv_l = fabsf(inputUV[0] - uv_a[0]); + uv_r = fabsf(inputUV[0] - uv_b[0]); dx = 0.5f * (uv_l + uv_r); /* adaptive sampling, green (V) channel */ - ok1 = resolveUV(x, y - 1, corners, uv_a); - ok2 = resolveUV(x, y + 1, corners, uv_b); - uv_u = ok1 ? fabsf(inputUV[1] - uv_a[1]) : 0.f; - uv_d = ok2 ? fabsf(inputUV[1] - uv_b[1]) : 0.f; + warpCoord(x, y - 1, matrix, uv_a); + warpCoord(x, y + 1, matrix, uv_b); + uv_u = fabsf(inputUV[1] - uv_a[1]); + uv_d = fabsf(inputUV[1] - uv_b[1]); dy = 0.5f * (uv_u + uv_d); @@ -118,6 +110,16 @@ void PlaneTrackWarpImageOperation::initExecution() this->m_pixelReader = this->getInputSocketReader(0); BLI_jitter_init(this->m_jitter[0], this->m_osa); + + const int width = this->m_pixelReader->getWidth(); + const int height = this->m_pixelReader->getHeight(); + float frame_corners[4][2] = {{0.0f, 0.0f}, + {(float) width, 0.0f}, + {(float) width, (float) height}, + {0.0f, (float) height}}; + BKE_tracking_homography_between_two_quads(this->m_frameSpaceCorners, + frame_corners, + this->m_perspectiveMatrix); } void PlaneTrackWarpImageOperation::deinitExecution() @@ -125,24 +127,25 @@ void PlaneTrackWarpImageOperation::deinitExecution() this->m_pixelReader = NULL; } -void PlaneTrackWarpImageOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void PlaneTrackWarpImageOperation::executePixelSampled(float output[4], float x_, float y_, PixelSampler sampler) { float color_accum[4]; zero_v4(color_accum); for (int sample = 0; sample < this->m_osa; sample++) { - float current_x = x + this->m_jitter[sample][0], - current_y = y + this->m_jitter[sample][1]; + float current_x = x_ + this->m_jitter[sample][0], + current_y = y_ + this->m_jitter[sample][1]; if (isPointInsideQuad(current_x, current_y, this->m_frameSpaceCorners)) { float current_color[4]; float u, v, dx, dy; - resolveUVAndDxDy(current_x, current_y, this->m_frameSpaceCorners, &u, &v, &dx, &dy); + resolveUVAndDxDy(current_x, current_y, m_perspectiveMatrix, &u, &v, &dx, &dy); - u *= this->m_pixelReader->getWidth(); - v *= this->m_pixelReader->getHeight(); + /* derivatives are to be in normalized space.. */ + dx /= this->m_pixelReader->getWidth(); + dy /= this->m_pixelReader->getHeight(); - this->m_pixelReader->read(current_color, u, v, dx, dy, COM_PS_NEAREST); + this->m_pixelReader->readFiltered(current_color, u, v, dx, dy, COM_PS_NEAREST); add_v4_v4(color_accum, current_color); } } @@ -152,20 +155,13 @@ void PlaneTrackWarpImageOperation::executePixel(float output[4], float x, float bool PlaneTrackWarpImageOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { - float frame_space_corners[4][2]; - - for (int i = 0; i < 4; i++) { - frame_space_corners[i][0] = this->m_corners[i][0] * this->getWidth(); - frame_space_corners[i][1] = this->m_corners[i][1] * this->getHeight(); - } - float UVs[4][2]; /* TODO(sergey): figure out proper way to do this. */ - resolveUV(input->xmin - 2, input->ymin - 2, frame_space_corners, UVs[0]); - resolveUV(input->xmax + 2, input->ymin - 2, frame_space_corners, UVs[1]); - resolveUV(input->xmax + 2, input->ymax + 2, frame_space_corners, UVs[2]); - resolveUV(input->xmin - 2, input->ymax + 2, frame_space_corners, UVs[3]); + warpCoord(input->xmin - 2, input->ymin - 2, this->m_perspectiveMatrix, UVs[0]); + warpCoord(input->xmax + 2, input->ymin - 2, this->m_perspectiveMatrix, UVs[1]); + warpCoord(input->xmax + 2, input->ymax + 2, this->m_perspectiveMatrix, UVs[2]); + warpCoord(input->xmin - 2, input->ymax + 2, this->m_perspectiveMatrix, UVs[3]); float min[2], max[2]; INIT_MINMAX2(min, max); @@ -175,10 +171,10 @@ bool PlaneTrackWarpImageOperation::determineDependingAreaOfInterest(rcti *input, rcti newInput; - newInput.xmin = min[0] * readOperation->getWidth() - 1; - newInput.ymin = min[1] * readOperation->getHeight() - 1; - newInput.xmax = max[0] * readOperation->getWidth() + 1; - newInput.ymax = max[1] * readOperation->getHeight() + 1; + newInput.xmin = min[0] - 1; + newInput.ymin = min[1] - 1; + newInput.xmax = max[0] + 1; + newInput.ymax = max[1] + 1; return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } diff --git a/source/blender/compositor/operations/COM_PlaneTrackWarpImageOperation.h b/source/blender/compositor/operations/COM_PlaneTrackWarpImageOperation.h index a92ff3f9ddf..ed9cc2fe5aa 100644 --- a/source/blender/compositor/operations/COM_PlaneTrackWarpImageOperation.h +++ b/source/blender/compositor/operations/COM_PlaneTrackWarpImageOperation.h @@ -38,6 +38,7 @@ protected: SocketReader *m_pixelReader; int m_osa; float m_jitter[32][2]; + float m_perspectiveMatrix[3][3]; public: PlaneTrackWarpImageOperation(); @@ -45,7 +46,7 @@ public: void initExecution(); void deinitExecution(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); }; diff --git a/source/blender/compositor/operations/COM_PreviewOperation.cpp b/source/blender/compositor/operations/COM_PreviewOperation.cpp index ba158fb2509..add9e8b959e 100644 --- a/source/blender/compositor/operations/COM_PreviewOperation.cpp +++ b/source/blender/compositor/operations/COM_PreviewOperation.cpp @@ -104,7 +104,7 @@ void PreviewOperation::executeRegion(rcti *rect, unsigned int tileNumber) color[1] = 0.0f; color[2] = 0.0f; color[3] = 1.0f; - this->m_input->read(color, rx, ry, COM_PS_NEAREST); + this->m_input->readSampled(color, rx, ry, COM_PS_NEAREST); IMB_colormanagement_processor_apply_v4(cm_processor, color); F4TOCHAR4(color, this->m_outputBuffer + offset); offset += 4; diff --git a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp index e8b900b9a85..7f6079c55aa 100644 --- a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp @@ -102,7 +102,7 @@ void ProjectorLensDistortionOperation::updateDispersion() this->lockMutex(); if (!this->m_dispersionAvailable) { float result[4]; - this->getInputSocketReader(1)->read(result, 1, 1, COM_PS_NEAREST); + this->getInputSocketReader(1)->readSampled(result, 1, 1, COM_PS_NEAREST); this->m_dispersion = result[0]; this->m_kr = 0.25f * max_ff(min_ff(this->m_dispersion, 1.0f), 0.0f); this->m_kr2 = this->m_kr * 20; diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.cpp b/source/blender/compositor/operations/COM_ReadBufferOperation.cpp index 3aeef6bf409..b93e338ad6c 100644 --- a/source/blender/compositor/operations/COM_ReadBufferOperation.cpp +++ b/source/blender/compositor/operations/COM_ReadBufferOperation.cpp @@ -52,7 +52,7 @@ void ReadBufferOperation::determineResolution(unsigned int resolution[2], unsign m_single_value = operation->isSingleValue(); } } -void ReadBufferOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ReadBufferOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { if (m_single_value) { /* write buffer has a single value stored at (0,0) */ @@ -81,7 +81,7 @@ void ReadBufferOperation::executePixelExtend(float output[4], float x, float y, } } -void ReadBufferOperation::executePixel(float output[4], float x, float y, float dx, float dy, PixelSampler sampler) +void ReadBufferOperation::executePixelFiltered(float output[4], float x, float y, float dx, float dy, PixelSampler sampler) { if (m_single_value) { /* write buffer has a single value stored at (0,0) */ diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.h b/source/blender/compositor/operations/COM_ReadBufferOperation.h index 7a67056eda6..cdc6e50f6d4 100644 --- a/source/blender/compositor/operations/COM_ReadBufferOperation.h +++ b/source/blender/compositor/operations/COM_ReadBufferOperation.h @@ -40,10 +40,10 @@ public: void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); void *initializeTileData(rcti *rect); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void executePixelExtend(float output[4], float x, float y, PixelSampler sampler, MemoryBufferExtend extend_x, MemoryBufferExtend extend_y); - void executePixel(float output[4], float x, float y, float dx, float dy, PixelSampler sampler); + void executePixelFiltered(float output[4], float x, float y, float dx, float dy, PixelSampler sampler); const bool isReadBufferOperation() const { return true; } void setOffset(unsigned int offset) { this->m_offset = offset; } unsigned int getOffset() const { return this->m_offset; } diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.cpp b/source/blender/compositor/operations/COM_RenderLayersProg.cpp index ea6ad86d92c..2c2a4c6f180 100644 --- a/source/blender/compositor/operations/COM_RenderLayersProg.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersProg.cpp @@ -60,7 +60,7 @@ void RenderLayersBaseProg::initExecution() if (rl && rl->rectf) { this->m_inputBuffer = RE_RenderLayerGetPass(rl, this->m_renderpass); - if (this->m_inputBuffer == NULL || this->m_renderpass == SCE_PASS_COMBINED) { + if (this->m_inputBuffer == NULL && this->m_renderpass == SCE_PASS_COMBINED) { this->m_inputBuffer = rl->rectf; } } @@ -112,7 +112,7 @@ void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, Pi } } -void RenderLayersBaseProg::executePixel(float output[4], float x, float y, PixelSampler sampler) +void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { #if 0 const RenderData *rd = this->m_rd; @@ -192,7 +192,7 @@ RenderLayersAlphaProg::RenderLayersAlphaProg() : RenderLayersBaseProg(SCE_PASS_C this->addOutputSocket(COM_DT_VALUE); } -void RenderLayersAlphaProg::executePixel(float output[4], float x, float y, PixelSampler sampler) +void RenderLayersAlphaProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { int ix = x; int iy = y; @@ -234,7 +234,7 @@ RenderLayersDepthProg::RenderLayersDepthProg() : RenderLayersBaseProg(SCE_PASS_Z this->addOutputSocket(COM_DT_VALUE); } -void RenderLayersDepthProg::executePixel(float output[4], float x, float y, PixelSampler sampler) +void RenderLayersDepthProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { int ix = x; int iy = y; diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.h b/source/blender/compositor/operations/COM_RenderLayersProg.h index 04861174387..b76a8621b19 100644 --- a/source/blender/compositor/operations/COM_RenderLayersProg.h +++ b/source/blender/compositor/operations/COM_RenderLayersProg.h @@ -99,7 +99,7 @@ public: short getLayerId() { return this->m_layerId; } void initExecution(); void deinitExecution(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class RenderLayersAOOperation : public RenderLayersBaseProg { @@ -110,7 +110,7 @@ public: class RenderLayersAlphaProg : public RenderLayersBaseProg { public: RenderLayersAlphaProg(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class RenderLayersColorOperation : public RenderLayersBaseProg { @@ -126,7 +126,7 @@ public: class RenderLayersDepthProg : public RenderLayersBaseProg { public: RenderLayersDepthProg(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class RenderLayersDiffuseOperation : public RenderLayersBaseProg { diff --git a/source/blender/compositor/operations/COM_RotateOperation.cpp b/source/blender/compositor/operations/COM_RotateOperation.cpp index 422c5b93484..c6ad87bbf97 100644 --- a/source/blender/compositor/operations/COM_RotateOperation.cpp +++ b/source/blender/compositor/operations/COM_RotateOperation.cpp @@ -52,7 +52,7 @@ inline void RotateOperation::ensureDegree() { if (!this->m_isDegreeSet) { float degree[4]; - this->m_degreeSocket->read(degree, 0, 0, COM_PS_NEAREST); + this->m_degreeSocket->readSampled(degree, 0, 0, COM_PS_NEAREST); double rad; if (this->m_doDegree2RadConversion) { rad = DEG2RAD((double)degree[0]); @@ -68,14 +68,14 @@ inline void RotateOperation::ensureDegree() } -void RotateOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void RotateOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { ensureDegree(); const float dy = y - this->m_centerY; const float dx = x - this->m_centerX; const float nx = this->m_centerX + (this->m_cosine * dx + this->m_sine * dy); const float ny = this->m_centerY + (-this->m_sine * dx + this->m_cosine * dy); - this->m_imageSocket->read(output, nx, ny, sampler); + this->m_imageSocket->readSampled(output, nx, ny, sampler); } bool RotateOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) diff --git a/source/blender/compositor/operations/COM_RotateOperation.h b/source/blender/compositor/operations/COM_RotateOperation.h index 292f0743a44..40acad1abe6 100644 --- a/source/blender/compositor/operations/COM_RotateOperation.h +++ b/source/blender/compositor/operations/COM_RotateOperation.h @@ -38,7 +38,7 @@ private: public: RotateOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); void setDoDegree2RadConversion(bool abool) { this->m_doDegree2RadConversion = abool; } diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cpp b/source/blender/compositor/operations/COM_ScaleOperation.cpp index 9e8f5af0ef0..452765a5ab7 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.cpp +++ b/source/blender/compositor/operations/COM_ScaleOperation.cpp @@ -66,22 +66,22 @@ void ScaleOperation::deinitExecution() } -void ScaleOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ScaleOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { PixelSampler effective_sampler = getEffectiveSampler(sampler); float scaleX[4]; float scaleY[4]; - this->m_inputXOperation->read(scaleX, x, y, effective_sampler); - this->m_inputYOperation->read(scaleY, x, y, effective_sampler); + this->m_inputXOperation->readSampled(scaleX, x, y, effective_sampler); + this->m_inputYOperation->readSampled(scaleY, x, y, effective_sampler); const float scx = scaleX[0]; const float scy = scaleY[0]; float nx = this->m_centerX + (x - this->m_centerX) / scx; float ny = this->m_centerY + (y - this->m_centerY) / scy; - this->m_inputOperation->read(output, nx, ny, effective_sampler); + this->m_inputOperation->readSampled(output, nx, ny, effective_sampler); } bool ScaleOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) @@ -90,8 +90,8 @@ bool ScaleOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOpe float scaleX[4]; float scaleY[4]; - this->m_inputXOperation->read(scaleX, 0, 0, COM_PS_NEAREST); - this->m_inputYOperation->read(scaleY, 0, 0, COM_PS_NEAREST); + this->m_inputXOperation->readSampled(scaleX, 0, 0, COM_PS_NEAREST); + this->m_inputYOperation->readSampled(scaleY, 0, 0, COM_PS_NEAREST); const float scx = scaleX[0]; const float scy = scaleY[0]; @@ -134,15 +134,15 @@ void ScaleAbsoluteOperation::deinitExecution() } -void ScaleAbsoluteOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ScaleAbsoluteOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { PixelSampler effective_sampler = getEffectiveSampler(sampler); float scaleX[4]; float scaleY[4]; - this->m_inputXOperation->read(scaleX, x, y, effective_sampler); - this->m_inputYOperation->read(scaleY, x, y, effective_sampler); + this->m_inputXOperation->readSampled(scaleX, x, y, effective_sampler); + this->m_inputYOperation->readSampled(scaleY, x, y, effective_sampler); const float scx = scaleX[0]; // target absolute scale const float scy = scaleY[0]; // target absolute scale @@ -156,7 +156,7 @@ void ScaleAbsoluteOperation::executePixel(float output[4], float x, float y, Pix float nx = this->m_centerX + (x - this->m_centerX) / relativeXScale; float ny = this->m_centerY + (y - this->m_centerY) / relativeYScale; - this->m_inputOperation->read(output, nx, ny, effective_sampler); + this->m_inputOperation->readSampled(output, nx, ny, effective_sampler); } bool ScaleAbsoluteOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) @@ -165,8 +165,8 @@ bool ScaleAbsoluteOperation::determineDependingAreaOfInterest(rcti *input, ReadB float scaleX[4]; float scaleY[4]; - this->m_inputXOperation->read(scaleX, 0, 0, COM_PS_NEAREST); - this->m_inputYOperation->read(scaleY, 0, 0, COM_PS_NEAREST); + this->m_inputXOperation->readSampled(scaleX, 0, 0, COM_PS_NEAREST); + this->m_inputYOperation->readSampled(scaleY, 0, 0, COM_PS_NEAREST); const float scx = scaleX[0]; const float scy = scaleY[0]; @@ -253,17 +253,17 @@ void ScaleFixedSizeOperation::deinitExecution() } -void ScaleFixedSizeOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ScaleFixedSizeOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { PixelSampler effective_sampler = getEffectiveSampler(sampler); if (this->m_is_offset) { float nx = ((x - this->m_offsetX) * this->m_relX); float ny = ((y - this->m_offsetY) * this->m_relY); - this->m_inputOperation->read(output, nx, ny, effective_sampler); + this->m_inputOperation->readSampled(output, nx, ny, effective_sampler); } else { - this->m_inputOperation->read(output, x * this->m_relX, y * this->m_relY, effective_sampler); + this->m_inputOperation->readSampled(output, x * this->m_relX, y * this->m_relY, effective_sampler); } } diff --git a/source/blender/compositor/operations/COM_ScaleOperation.h b/source/blender/compositor/operations/COM_ScaleOperation.h index f42cdbd78ed..706a5898027 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.h +++ b/source/blender/compositor/operations/COM_ScaleOperation.h @@ -47,7 +47,7 @@ private: public: ScaleOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); @@ -63,7 +63,7 @@ class ScaleAbsoluteOperation : public BaseScaleOperation { public: ScaleAbsoluteOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); @@ -88,7 +88,7 @@ public: ScaleFixedSizeOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp index d1060224444..5d2977d361b 100644 --- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp @@ -291,9 +291,9 @@ void ScreenLensDistortionOperation::updateDispersionAndDistortion() this->lockMutex(); if (!this->m_valuesAvailable) { float result[4]; - this->getInputSocketReader(1)->read(result, 0, 0, COM_PS_NEAREST); + this->getInputSocketReader(1)->readSampled(result, 0, 0, COM_PS_NEAREST); this->m_distortion = result[0]; - this->getInputSocketReader(2)->read(result, 0, 0, COM_PS_NEAREST); + this->getInputSocketReader(2)->readSampled(result, 0, 0, COM_PS_NEAREST); this->m_dispersion = result[0]; updateVariables(this->m_distortion, this->m_dispersion); this->m_valuesAvailable = true; diff --git a/source/blender/compositor/operations/COM_SetAlphaOperation.cpp b/source/blender/compositor/operations/COM_SetAlphaOperation.cpp index fc6cfa455f3..efdc844704a 100644 --- a/source/blender/compositor/operations/COM_SetAlphaOperation.cpp +++ b/source/blender/compositor/operations/COM_SetAlphaOperation.cpp @@ -38,12 +38,12 @@ void SetAlphaOperation::initExecution() this->m_inputAlpha = getInputSocketReader(1); } -void SetAlphaOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void SetAlphaOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float alphaInput[4]; - this->m_inputColor->read(output, x, y, sampler); - this->m_inputAlpha->read(alphaInput, x, y, sampler); + this->m_inputColor->readSampled(output, x, y, sampler); + this->m_inputAlpha->readSampled(alphaInput, x, y, sampler); output[3] = alphaInput[0]; } diff --git a/source/blender/compositor/operations/COM_SetAlphaOperation.h b/source/blender/compositor/operations/COM_SetAlphaOperation.h index 1ec4a7aeacf..a0869ec90b2 100644 --- a/source/blender/compositor/operations/COM_SetAlphaOperation.h +++ b/source/blender/compositor/operations/COM_SetAlphaOperation.h @@ -43,7 +43,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_SetColorOperation.cpp b/source/blender/compositor/operations/COM_SetColorOperation.cpp index 44c29b3befd..94a863e628b 100644 --- a/source/blender/compositor/operations/COM_SetColorOperation.cpp +++ b/source/blender/compositor/operations/COM_SetColorOperation.cpp @@ -27,7 +27,7 @@ SetColorOperation::SetColorOperation() : NodeOperation() this->addOutputSocket(COM_DT_COLOR); } -void SetColorOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void SetColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { copy_v4_v4(output, this->m_color); } diff --git a/source/blender/compositor/operations/COM_SetColorOperation.h b/source/blender/compositor/operations/COM_SetColorOperation.h index 8377decdd7b..7dfed6b570b 100644 --- a/source/blender/compositor/operations/COM_SetColorOperation.h +++ b/source/blender/compositor/operations/COM_SetColorOperation.h @@ -55,7 +55,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); bool isSetOperation() const { return true; } diff --git a/source/blender/compositor/operations/COM_SetSamplerOperation.cpp b/source/blender/compositor/operations/COM_SetSamplerOperation.cpp index 343b5973f7e..be72ffd0336 100644 --- a/source/blender/compositor/operations/COM_SetSamplerOperation.cpp +++ b/source/blender/compositor/operations/COM_SetSamplerOperation.cpp @@ -37,7 +37,7 @@ void SetSamplerOperation::deinitExecution() this->m_reader = NULL; } -void SetSamplerOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void SetSamplerOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { - this->m_reader->read(output, x, y, this->m_sampler); + this->m_reader->readSampled(output, x, y, this->m_sampler); } diff --git a/source/blender/compositor/operations/COM_SetSamplerOperation.h b/source/blender/compositor/operations/COM_SetSamplerOperation.h index c94e174fc81..145d82bd407 100644 --- a/source/blender/compositor/operations/COM_SetSamplerOperation.h +++ b/source/blender/compositor/operations/COM_SetSamplerOperation.h @@ -44,7 +44,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); }; diff --git a/source/blender/compositor/operations/COM_SetValueOperation.cpp b/source/blender/compositor/operations/COM_SetValueOperation.cpp index c5ce3e4c09c..51e09a63051 100644 --- a/source/blender/compositor/operations/COM_SetValueOperation.cpp +++ b/source/blender/compositor/operations/COM_SetValueOperation.cpp @@ -27,7 +27,7 @@ SetValueOperation::SetValueOperation() : NodeOperation() this->addOutputSocket(COM_DT_VALUE); } -void SetValueOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void SetValueOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { output[0] = this->m_value; } diff --git a/source/blender/compositor/operations/COM_SetValueOperation.h b/source/blender/compositor/operations/COM_SetValueOperation.h index b88b85d66f2..7cb914ffa48 100644 --- a/source/blender/compositor/operations/COM_SetValueOperation.h +++ b/source/blender/compositor/operations/COM_SetValueOperation.h @@ -46,7 +46,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); bool isSetOperation() const { return true; } diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.cpp b/source/blender/compositor/operations/COM_SetVectorOperation.cpp index d5c665e81f5..17212d78e15 100644 --- a/source/blender/compositor/operations/COM_SetVectorOperation.cpp +++ b/source/blender/compositor/operations/COM_SetVectorOperation.cpp @@ -28,7 +28,7 @@ SetVectorOperation::SetVectorOperation() : NodeOperation() this->addOutputSocket(COM_DT_VECTOR); } -void SetVectorOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void SetVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { output[0] = this->m_x; output[1] = this->m_y; diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.h b/source/blender/compositor/operations/COM_SetVectorOperation.h index d15da58e58e..6fd1b9768fc 100644 --- a/source/blender/compositor/operations/COM_SetVectorOperation.h +++ b/source/blender/compositor/operations/COM_SetVectorOperation.h @@ -54,7 +54,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); bool isSetOperation() const { return true; } diff --git a/source/blender/compositor/operations/COM_SocketProxyOperation.cpp b/source/blender/compositor/operations/COM_SocketProxyOperation.cpp index ac2cee8eb44..d047198ac93 100644 --- a/source/blender/compositor/operations/COM_SocketProxyOperation.cpp +++ b/source/blender/compositor/operations/COM_SocketProxyOperation.cpp @@ -39,9 +39,9 @@ void SocketProxyOperation::deinitExecution() this->m_inputOperation = NULL; } -void SocketProxyOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void SocketProxyOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { if (this->m_inputOperation) { - this->m_inputOperation->read(output, x, y, sampler); + this->m_inputOperation->readSampled(output, x, y, sampler); } } diff --git a/source/blender/compositor/operations/COM_SocketProxyOperation.h b/source/blender/compositor/operations/COM_SocketProxyOperation.h index a37384455ca..6a6a0b351b0 100644 --- a/source/blender/compositor/operations/COM_SocketProxyOperation.h +++ b/source/blender/compositor/operations/COM_SocketProxyOperation.h @@ -30,7 +30,7 @@ private: SocketReader *m_inputOperation; public: SocketProxyOperation(DataType type); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_SplitOperation.cpp b/source/blender/compositor/operations/COM_SplitOperation.cpp index a7dbccfc2f7..210095f3bf1 100644 --- a/source/blender/compositor/operations/COM_SplitOperation.cpp +++ b/source/blender/compositor/operations/COM_SplitOperation.cpp @@ -57,15 +57,15 @@ void SplitOperation::deinitExecution() this->m_image2Input = NULL; } -void SplitOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void SplitOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { int perc = this->m_xSplit ? this->m_splitPercentage * this->getWidth() / 100.0f : this->m_splitPercentage * this->getHeight() / 100.0f; bool image1 = this->m_xSplit ? x > perc : y > perc; if (image1) { - this->m_image1Input->read(output, x, y, COM_PS_NEAREST); + this->m_image1Input->readSampled(output, x, y, COM_PS_NEAREST); } else { - this->m_image2Input->read(output, x, y, COM_PS_NEAREST); + this->m_image2Input->readSampled(output, x, y, COM_PS_NEAREST); } } diff --git a/source/blender/compositor/operations/COM_SplitOperation.h b/source/blender/compositor/operations/COM_SplitOperation.h index 5a042b789d8..2853c845d03 100644 --- a/source/blender/compositor/operations/COM_SplitOperation.h +++ b/source/blender/compositor/operations/COM_SplitOperation.h @@ -35,7 +35,7 @@ public: SplitOperation(); void initExecution(); void deinitExecution(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); void setSplitPercentage(float splitPercentage) { this->m_splitPercentage = splitPercentage; } void setXSplit(bool xsplit) { this->m_xSplit = xsplit; } diff --git a/source/blender/compositor/operations/COM_TextureOperation.cpp b/source/blender/compositor/operations/COM_TextureOperation.cpp index bbb7c8b5289..96aea56050f 100644 --- a/source/blender/compositor/operations/COM_TextureOperation.cpp +++ b/source/blender/compositor/operations/COM_TextureOperation.cpp @@ -75,16 +75,16 @@ void TextureBaseOperation::determineResolution(unsigned int resolution[2], unsig } } -void TextureAlphaOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void TextureAlphaOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { - TextureBaseOperation::executePixel(output, x, y, sampler); + TextureBaseOperation::executePixelSampled(output, x, y, sampler); output[0] = output[3]; output[1] = 0.0f; output[2] = 0.0f; output[3] = 0.0f; } -void TextureBaseOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void TextureBaseOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { TexResult texres = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; float textureSize[4]; @@ -96,8 +96,8 @@ void TextureBaseOperation::executePixel(float output[4], float x, float y, Pixel const float u = (x - cx) / this->getWidth() * 2; const float v = (y - cy) / this->getHeight() * 2; - this->m_inputSize->read(textureSize, x, y, sampler); - this->m_inputOffset->read(textureOffset, x, y, sampler); + this->m_inputSize->readSampled(textureSize, x, y, sampler); + this->m_inputOffset->readSampled(textureOffset, x, y, sampler); vec[0] = textureSize[0] * (u + textureOffset[0]); vec[1] = textureSize[1] * (v + textureOffset[1]); @@ -136,7 +136,7 @@ MemoryBuffer *TextureBaseOperation::createMemoryBuffer(rcti *rect2) for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++, data += 4) { - this->executePixel(data, x, y, COM_PS_NEAREST); + this->executePixelSampled(data, x, y, COM_PS_NEAREST); } } diff --git a/source/blender/compositor/operations/COM_TextureOperation.h b/source/blender/compositor/operations/COM_TextureOperation.h index b776f6f2493..064e63c025a 100644 --- a/source/blender/compositor/operations/COM_TextureOperation.h +++ b/source/blender/compositor/operations/COM_TextureOperation.h @@ -62,7 +62,7 @@ protected: MemoryBuffer *createMemoryBuffer(rcti *rect2); public: - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void setTexture(Tex *texture) { this->m_texture = texture; } void initExecution(); @@ -79,7 +79,7 @@ public: class TextureAlphaOperation : public TextureBaseOperation { public: TextureAlphaOperation(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.cpp b/source/blender/compositor/operations/COM_TrackPositionOperation.cpp index 4f00358633a..721b17bcff0 100644 --- a/source/blender/compositor/operations/COM_TrackPositionOperation.cpp +++ b/source/blender/compositor/operations/COM_TrackPositionOperation.cpp @@ -102,7 +102,7 @@ void TrackPositionOperation::initExecution() } } -void TrackPositionOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void TrackPositionOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { output[0] = this->m_markerPos[this->m_axis] - this->m_relativePos[this->m_axis]; diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.h b/source/blender/compositor/operations/COM_TrackPositionOperation.h index 7a4ce9f9213..10dbaf96646 100644 --- a/source/blender/compositor/operations/COM_TrackPositionOperation.h +++ b/source/blender/compositor/operations/COM_TrackPositionOperation.h @@ -70,7 +70,7 @@ public: void initExecution(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); bool isSetOperation() const { return true; } }; diff --git a/source/blender/compositor/operations/COM_TranslateOperation.cpp b/source/blender/compositor/operations/COM_TranslateOperation.cpp index e2582c3b67b..64da954a2e1 100644 --- a/source/blender/compositor/operations/COM_TranslateOperation.cpp +++ b/source/blender/compositor/operations/COM_TranslateOperation.cpp @@ -52,14 +52,14 @@ void TranslateOperation::deinitExecution() } -void TranslateOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void TranslateOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { ensureDelta(); float originalXPos = x - this->getDeltaX(); float originalYPos = y - this->getDeltaY(); - this->m_inputOperation->read(output, originalXPos, originalYPos, sampler); + this->m_inputOperation->readSampled(output, originalXPos, originalYPos, sampler); } bool TranslateOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) diff --git a/source/blender/compositor/operations/COM_TranslateOperation.h b/source/blender/compositor/operations/COM_TranslateOperation.h index a638ae7ce69..f2ae976e2ef 100644 --- a/source/blender/compositor/operations/COM_TranslateOperation.h +++ b/source/blender/compositor/operations/COM_TranslateOperation.h @@ -38,7 +38,7 @@ private: public: TranslateOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void initExecution(); void deinitExecution(); @@ -49,9 +49,9 @@ public: inline void ensureDelta() { if (!this->m_isDeltaSet) { float tempDelta[4]; - this->m_inputXOperation->read(tempDelta, 0, 0, COM_PS_NEAREST); + this->m_inputXOperation->readSampled(tempDelta, 0, 0, COM_PS_NEAREST); this->m_deltaX = tempDelta[0]; - this->m_inputYOperation->read(tempDelta, 0, 0, COM_PS_NEAREST); + this->m_inputYOperation->readSampled(tempDelta, 0, 0, COM_PS_NEAREST); this->m_deltaY = tempDelta[0]; this->m_isDeltaSet = true; } diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp index 03031e0f764..8bdaa0f486e 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp @@ -338,7 +338,7 @@ voi *InverseSearchRadiusOperation::initializeTileData(rcti *rect) return data; } -void InverseSearchRadiusOperation::executePixel(float output[4], int x, int y, void *data) +void InverseSearchRadiusOperation::executePixelChunk(float output[4], int x, int y, void *data) { MemoryBuffer *buffer = (MemoryBuffer *)data; buffer->readNoCheck(color, x, y); diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h index 7ba8df16795..cab38698296 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h @@ -85,7 +85,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], int x, int y, MemoryBuffer *inputBuffers[], void *data); + void executePixelChunk(float output[4], int x, int y, void *data); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_VectorCurveOperation.cpp b/source/blender/compositor/operations/COM_VectorCurveOperation.cpp index 6450b0716a3..204b0f2011b 100644 --- a/source/blender/compositor/operations/COM_VectorCurveOperation.cpp +++ b/source/blender/compositor/operations/COM_VectorCurveOperation.cpp @@ -43,12 +43,12 @@ void VectorCurveOperation::initExecution() this->m_inputProgram = this->getInputSocketReader(0); } -void VectorCurveOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void VectorCurveOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float input[4]; - this->m_inputProgram->read(input, x, y, sampler); + this->m_inputProgram->readSampled(input, x, y, sampler); curvemapping_evaluate_premulRGBF(this->m_curveMapping, output, input); output[3] = input[3]; diff --git a/source/blender/compositor/operations/COM_VectorCurveOperation.h b/source/blender/compositor/operations/COM_VectorCurveOperation.h index 6a1f916c60b..677af77b05e 100644 --- a/source/blender/compositor/operations/COM_VectorCurveOperation.h +++ b/source/blender/compositor/operations/COM_VectorCurveOperation.h @@ -37,7 +37,7 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); /** * Initialize the execution diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cpp b/source/blender/compositor/operations/COM_ViewerOperation.cpp index 468aec64a56..13b50910b50 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.cpp +++ b/source/blender/compositor/operations/COM_ViewerOperation.cpp @@ -101,18 +101,18 @@ void ViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber) for (y = y1; y < y2 && (!breaked); y++) { for (x = x1; x < x2; x++) { - this->m_imageInput->read(&(buffer[offset4]), x, y, COM_PS_NEAREST); + this->m_imageInput->readSampled(&(buffer[offset4]), x, y, COM_PS_NEAREST); if (this->m_ignoreAlpha) { buffer[offset4 + 3] = 1.0f; } else { if (this->m_alphaInput != NULL) { - this->m_alphaInput->read(alpha, x, y, COM_PS_NEAREST); + this->m_alphaInput->readSampled(alpha, x, y, COM_PS_NEAREST); buffer[offset4 + 3] = alpha[0]; } } if (m_depthInput) { - this->m_depthInput->read(depth, x, y, COM_PS_NEAREST); + this->m_depthInput->readSampled(depth, x, y, COM_PS_NEAREST); depthbuffer[offset] = depth[0]; } @@ -147,8 +147,6 @@ void ViewerOperation::initImage() ima->ok = IMA_OK_LOADED; ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; - - BLI_unlock_thread(LOCK_DRAW_IMAGE); } if (m_doDepthBuffer) { diff --git a/source/blender/compositor/operations/COM_WrapOperation.cpp b/source/blender/compositor/operations/COM_WrapOperation.cpp index ea19952f60c..e6cde05eae2 100644 --- a/source/blender/compositor/operations/COM_WrapOperation.cpp +++ b/source/blender/compositor/operations/COM_WrapOperation.cpp @@ -42,7 +42,7 @@ inline float WrapOperation::getWrappedOriginalYPos(float y) return fmodf(y, this->getHeight()); } -void WrapOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void WrapOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float nx, ny; nx = x; diff --git a/source/blender/compositor/operations/COM_WrapOperation.h b/source/blender/compositor/operations/COM_WrapOperation.h index ddd5fa8032d..33ea1280564 100644 --- a/source/blender/compositor/operations/COM_WrapOperation.h +++ b/source/blender/compositor/operations/COM_WrapOperation.h @@ -31,7 +31,7 @@ private: public: WrapOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void setWrapping(int wrapping_type); float getWrappedOriginalXPos(float x); diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp index cf462607936..832864b399d 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp @@ -40,9 +40,9 @@ WriteBufferOperation::~WriteBufferOperation() } } -void WriteBufferOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void WriteBufferOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { - this->m_input->read(output, x, y, sampler); + this->m_input->readSampled(output, x, y, sampler); } void WriteBufferOperation::initExecution() @@ -98,7 +98,7 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber) for (y = y1; y < y2 && (!breaked); y++) { int offset4 = (y * memoryBuffer->getWidth() + x1) * COM_NUMBER_OF_CHANNELS; for (x = x1; x < x2; x++) { - this->m_input->read(&(buffer[offset4]), x, y, COM_PS_NEAREST); + this->m_input->readSampled(&(buffer[offset4]), x, y, COM_PS_NEAREST); offset4 += COM_NUMBER_OF_CHANNELS; } if (isBreaked()) { @@ -157,14 +157,14 @@ void WriteBufferOperation::executeOpenCLRegion(OpenCLDevice *device, rcti *rect, this->getMemoryProxy()->getBuffer()->copyContentFrom(outputBuffer); // STEP 4 - while (clMemToCleanUp->size() > 0) { + while (!clMemToCleanUp->empty()) { cl_mem mem = clMemToCleanUp->front(); error = clReleaseMemObject(mem); if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } clMemToCleanUp->pop_front(); } - while (clKernelsToCleanUp->size() > 0) { + while (!clKernelsToCleanUp->empty()) { cl_kernel kernel = clKernelsToCleanUp->front(); error = clReleaseKernel(kernel); if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.h b/source/blender/compositor/operations/COM_WriteBufferOperation.h index 157543fcb72..1f1f58b18f1 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.h +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.h @@ -39,7 +39,7 @@ public: ~WriteBufferOperation(); int isBufferOperation() { return true; } MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; } - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); const bool isWriteBufferOperation() const { return true; } bool isSingleValue() const { return m_single_value; } diff --git a/source/blender/compositor/operations/COM_ZCombineOperation.cpp b/source/blender/compositor/operations/COM_ZCombineOperation.cpp index 7db91a40fb7..6cb88919b1b 100644 --- a/source/blender/compositor/operations/COM_ZCombineOperation.cpp +++ b/source/blender/compositor/operations/COM_ZCombineOperation.cpp @@ -46,36 +46,36 @@ void ZCombineOperation::initExecution() this->m_depth2Reader = this->getInputSocketReader(3); } -void ZCombineOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ZCombineOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float depth1[4]; float depth2[4]; - this->m_depth1Reader->read(depth1, x, y, sampler); - this->m_depth2Reader->read(depth2, x, y, sampler); + this->m_depth1Reader->readSampled(depth1, x, y, sampler); + this->m_depth2Reader->readSampled(depth2, x, y, sampler); if (depth1[0] < depth2[0]) { - this->m_image1Reader->read(output, x, y, sampler); + this->m_image1Reader->readSampled(output, x, y, sampler); } else { - this->m_image2Reader->read(output, x, y, sampler); + this->m_image2Reader->readSampled(output, x, y, sampler); } } -void ZCombineAlphaOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ZCombineAlphaOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float depth1[4]; float depth2[4]; float color1[4]; float color2[4]; - this->m_depth1Reader->read(depth1, x, y, sampler); - this->m_depth2Reader->read(depth2, x, y, sampler); + this->m_depth1Reader->readSampled(depth1, x, y, sampler); + this->m_depth2Reader->readSampled(depth2, x, y, sampler); if (depth1[0] <= depth2[0]) { - this->m_image1Reader->read(color1, x, y, sampler); - this->m_image2Reader->read(color2, x, y, sampler); + this->m_image1Reader->readSampled(color1, x, y, sampler); + this->m_image2Reader->readSampled(color2, x, y, sampler); } else { - this->m_image1Reader->read(color2, x, y, sampler); - this->m_image2Reader->read(color1, x, y, sampler); + this->m_image1Reader->readSampled(color2, x, y, sampler); + this->m_image2Reader->readSampled(color1, x, y, sampler); } float fac = color1[3]; float ifac = 1.0f - fac; @@ -113,28 +113,28 @@ void ZCombineMaskOperation::initExecution() this->m_image2Reader = this->getInputSocketReader(2); } -void ZCombineMaskOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ZCombineMaskOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float mask[4]; float color1[4]; float color2[4]; - this->m_maskReader->read(mask, x, y, sampler); - this->m_image1Reader->read(color1, x, y, sampler); - this->m_image2Reader->read(color2, x, y, sampler); + this->m_maskReader->readSampled(mask, x, y, sampler); + this->m_image1Reader->readSampled(color1, x, y, sampler); + this->m_image2Reader->readSampled(color2, x, y, sampler); interp_v4_v4v4(output, color1, color2, 1.0f - mask[0]); } -void ZCombineMaskAlphaOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void ZCombineMaskAlphaOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float mask[4]; float color1[4]; float color2[4]; - this->m_maskReader->read(mask, x, y, sampler); - this->m_image1Reader->read(color1, x, y, sampler); - this->m_image2Reader->read(color2, x, y, sampler); + this->m_maskReader->readSampled(mask, x, y, sampler); + this->m_image1Reader->readSampled(color1, x, y, sampler); + this->m_image2Reader->readSampled(color2, x, y, sampler); float fac = (1.0f - mask[0]) * (1.0f - color1[3]) + mask[0] * color2[3]; float mfac = 1.0f - fac; diff --git a/source/blender/compositor/operations/COM_ZCombineOperation.h b/source/blender/compositor/operations/COM_ZCombineOperation.h index eeeb29d330f..199120fa3be 100644 --- a/source/blender/compositor/operations/COM_ZCombineOperation.h +++ b/source/blender/compositor/operations/COM_ZCombineOperation.h @@ -47,11 +47,11 @@ public: /** * the inner loop of this program */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class ZCombineAlphaOperation : public ZCombineOperation { - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class ZCombineMaskOperation : public NodeOperation { @@ -64,10 +64,10 @@ public: void initExecution(); void deinitExecution(); - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; class ZCombineMaskAlphaOperation : public ZCombineMaskOperation { - void executePixel(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); }; #endif diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 142342997be..75363f4f567 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -63,6 +63,7 @@ #include "BKE_curve.h" #include "BKE_key.h" +#include "BKE_nla.h" #include "BKE_context.h" #include "UI_interface.h" @@ -341,7 +342,7 @@ static void acf_generic_idblock_name(bAnimListElem *ale, char *name) } /* name property for ID block entries */ -static short acf_generic_idblock_nameprop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) +static bool acf_generic_idblock_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) { RNA_id_pointer_create(ale->id, ptr); *prop = RNA_struct_name_property(ptr->type); @@ -351,7 +352,7 @@ static short acf_generic_idblock_nameprop(bAnimListElem *ale, PointerRNA *ptr, P /* name property for ID block entries which are just subheading "fillers" */ -static short acf_generic_idfill_nameprop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) +static bool acf_generic_idfill_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) { /* actual ID we're representing is stored in ale->data not ale->id, as id gives the owner */ RNA_id_pointer_create(ale->data, ptr); @@ -364,19 +365,19 @@ static short acf_generic_idfill_nameprop(bAnimListElem *ale, PointerRNA *ptr, Pr #if 0 /* channel type has no settings */ -static short acf_generic_none_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) +static bool acf_generic_none_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) { - return 0; + return false; } #endif /* check if some setting exists for this object-based data-expander (datablock only) */ -static short acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting) +static bool acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting) { switch (setting) { /* expand is always supported */ case ACHANNEL_SETTING_EXPAND: - return 1; + return true; /* mute is only supported for NLA */ case ACHANNEL_SETTING_MUTE: @@ -384,11 +385,11 @@ static short acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListEle /* select is ok for most "ds*" channels (e.g. dsmat) */ case ACHANNEL_SETTING_SELECT: - return 1; + return true; /* other flags are never supported */ default: - return 0; + return false; } } @@ -437,23 +438,23 @@ static int acf_summary_icon(bAnimListElem *UNUSED(ale)) } /* check if some setting exists for this channel */ -static short acf_summary_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) +static bool acf_summary_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) { /* only expanded is supported, as it is used for hiding all stuff which the summary covers */ return (setting == ACHANNEL_SETTING_EXPAND); } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_summary_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_summary_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { if (setting == ACHANNEL_SETTING_EXPAND) { /* expanded */ - *neg = 1; + *neg = true; return ADS_FLAG_SUMMARY_COLLAPSED; } else { /* unsupported */ - *neg = 0; + *neg = false; return 0; } } @@ -508,7 +509,7 @@ static int acf_scene_icon(bAnimListElem *UNUSED(ale)) } /* check if some setting exists for this channel */ -static short acf_scene_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting) +static bool acf_scene_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting) { switch (setting) { /* muted only in NLA */ @@ -522,32 +523,32 @@ static short acf_scene_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale /* only select and expand supported otherwise */ case ACHANNEL_SETTING_SELECT: case ACHANNEL_SETTING_EXPAND: - return 1; + return true; default: - return 0; + return false; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_scene_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_scene_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ return SCE_DS_SELECTED; case ACHANNEL_SETTING_EXPAND: /* expanded */ - *neg = 1; + *neg = true; return SCE_DS_COLLAPSED; case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; default: /* unsupported */ @@ -592,7 +593,7 @@ static bAnimChannelType ACF_SCENE = NULL, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_scene_icon, /* icon */ acf_scene_setting_valid, /* has setting */ @@ -648,7 +649,7 @@ static void acf_object_name(bAnimListElem *ale, char *name) } /* check if some setting exists for this channel */ -static short acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) +static bool acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) { Base *base = (Base *)ale->data; Object *ob = base->object; @@ -665,18 +666,18 @@ static short acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, int /* only select and expand supported otherwise */ case ACHANNEL_SETTING_SELECT: case ACHANNEL_SETTING_EXPAND: - return 1; + return true; default: - return 0; + return false; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_object_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_object_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ @@ -690,7 +691,7 @@ static int acf_object_setting_flag(bAnimContext *UNUSED(ac), int setting, short return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; default: /* unsupported */ @@ -736,7 +737,7 @@ static bAnimChannelType ACF_OBJECT = NULL, /* offset */ acf_object_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_object_icon, /* icon */ acf_object_setting_valid, /* has setting */ @@ -802,7 +803,7 @@ static void acf_group_name(bAnimListElem *ale, char *name) } /* name property for group entries */ -static short acf_group_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) +static bool acf_group_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) { RNA_pointer_create(ale->id, &RNA_ActionGroup, ale->data, ptr); *prop = RNA_struct_name_property(ptr->type); @@ -811,23 +812,28 @@ static short acf_group_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRN } /* check if some setting exists for this channel */ -static short acf_group_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting) +static bool acf_group_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting) { /* for now, all settings are supported, though some are only conditionally */ switch (setting) { + /* unsupported */ + case ACHANNEL_SETTING_SOLO: /* Only available in NLA Editor for tracks */ + return false; + + /* conditionally supported */ case ACHANNEL_SETTING_VISIBLE: /* Only available in Graph Editor */ return (ac->spacetype == SPACE_IPO); default: /* always supported */ - return 1; + return true; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_group_setting_flag(bAnimContext *ac, int setting, short *neg) +static int acf_group_setting_flag(bAnimContext *ac, int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ @@ -848,7 +854,6 @@ static int acf_group_setting_flag(bAnimContext *ac, int setting, short *neg) return AGRP_MUTED; case ACHANNEL_SETTING_PROTECT: /* protected */ - // *neg = 1; - if we change this to edtiability return AGRP_PROTECTED; case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */ @@ -897,7 +902,7 @@ static void acf_fcurve_name(bAnimListElem *ale, char *name) } /* "name" property for fcurve entries */ -static short acf_fcurve_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) +static bool acf_fcurve_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) { FCurve *fcu = (FCurve *)ale->data; @@ -918,36 +923,37 @@ static short acf_fcurve_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyR } /* check if some setting exists for this channel */ -static short acf_fcurve_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) +static bool acf_fcurve_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) { FCurve *fcu = (FCurve *)ale->data; switch (setting) { /* unsupported */ + case ACHANNEL_SETTING_SOLO: /* Solo Flag is only for NLA */ case ACHANNEL_SETTING_EXPAND: /* F-Curves are not containers */ - return 0; + return false; /* conditionally available */ case ACHANNEL_SETTING_PROTECT: /* Protection is only valid when there's keyframes */ if (fcu->bezt) - return 1; + return true; else - return 0; // NOTE: in this special case, we need to draw ICON_ZOOMOUT + return false; // NOTE: in this special case, we need to draw ICON_ZOOMOUT case ACHANNEL_SETTING_VISIBLE: /* Only available in Graph Editor */ return (ac->spacetype == SPACE_IPO); /* always available */ default: - return 1; + return true; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ @@ -957,7 +963,6 @@ static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac), int setting, short return FCURVE_MUTED; case ACHANNEL_SETTING_PROTECT: /* protected */ - // *neg = 1; - if we change this to edtiability return FCURVE_PROTECTED; case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */ @@ -1005,31 +1010,31 @@ static int acf_fillactd_icon(bAnimListElem *UNUSED(ale)) } /* check if some setting exists for this channel */ -static short acf_fillactd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) +static bool acf_fillactd_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; + return true; default: - return 0; + return false; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_fillactd_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_fillactd_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ return ADT_UI_SELECTED; case ACHANNEL_SETTING_EXPAND: /* expanded */ - *neg = 1; + *neg = true; return ACT_COLLAPSED; default: /* unsupported */ @@ -1072,7 +1077,7 @@ static bAnimChannelType ACF_FILLACTD = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idfill_nameprop, /* name prop */ + acf_generic_idfill_name_prop, /* name prop */ acf_fillactd_icon, /* icon */ acf_fillactd_setting_valid, /* has setting */ @@ -1095,27 +1100,27 @@ static void acf_filldrivers_name(bAnimListElem *UNUSED(ale), char *name) /* check if some setting exists for this channel */ // TODO: this could be made more generic -static short acf_filldrivers_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) +static bool acf_filldrivers_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) { switch (setting) { /* only expand supported */ case ACHANNEL_SETTING_EXPAND: - return 1; + return true; default: - return 0; + return false; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_filldrivers_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_filldrivers_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ - *neg = 1; + *neg = true; return ADT_DRIVERS_COLLAPSED; default: /* unsupported */ @@ -1169,10 +1174,10 @@ static int acf_dsmat_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dsmat_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dsmat_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1182,7 +1187,7 @@ static int acf_dsmat_setting_flag(bAnimContext *UNUSED(ac), int setting, short * return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1228,7 +1233,7 @@ static bAnimChannelType ACF_DSMAT = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dsmat_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1245,10 +1250,10 @@ static int acf_dslam_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dslam_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dslam_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1258,7 +1263,7 @@ static int acf_dslam_setting_flag(bAnimContext *UNUSED(ac), int setting, short * return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1304,7 +1309,7 @@ static bAnimChannelType ACF_DSLAM = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dslam_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1328,10 +1333,10 @@ static short acf_dstex_offset(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(al } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dstex_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dstex_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1341,7 +1346,7 @@ static int acf_dstex_setting_flag(bAnimContext *UNUSED(ac), int setting, short * return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1387,7 +1392,7 @@ static bAnimChannelType ACF_DSTEX = acf_dstex_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idfill_nameprop, /* name prop */ + acf_generic_idfill_name_prop, /* name prop */ acf_dstex_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1404,10 +1409,10 @@ static int acf_dscam_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dscam_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dscam_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1417,7 +1422,7 @@ static int acf_dscam_setting_flag(bAnimContext *UNUSED(ac), int setting, short * return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1463,7 +1468,7 @@ static bAnimChannelType ACF_DSCAM = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idfill_nameprop, /* name prop */ + acf_generic_idfill_name_prop, /* name prop */ acf_dscam_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1490,10 +1495,10 @@ static int acf_dscur_icon(bAnimListElem *ale) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dscur_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dscur_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1503,7 +1508,7 @@ static int acf_dscur_setting_flag(bAnimContext *UNUSED(ac), int setting, short * return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1549,7 +1554,7 @@ static bAnimChannelType ACF_DSCUR = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dscur_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1566,10 +1571,10 @@ static int acf_dsskey_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dsskey_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dsskey_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1579,7 +1584,7 @@ static int acf_dsskey_setting_flag(bAnimContext *UNUSED(ac), int setting, short return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1625,7 +1630,7 @@ static bAnimChannelType ACF_DSSKEY = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dsskey_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1642,10 +1647,10 @@ static int acf_dswor_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dswor_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dswor_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1655,7 +1660,7 @@ static int acf_dswor_setting_flag(bAnimContext *UNUSED(ac), int setting, short * return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1701,7 +1706,7 @@ static bAnimChannelType ACF_DSWOR = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idfill_nameprop, /* name prop */ + acf_generic_idfill_name_prop, /* name prop */ acf_dswor_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1718,10 +1723,10 @@ static int acf_dspart_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dspart_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dspart_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1731,7 +1736,7 @@ static int acf_dspart_setting_flag(bAnimContext *UNUSED(ac), int setting, short return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1777,7 +1782,7 @@ static bAnimChannelType ACF_DSPART = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dspart_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1794,10 +1799,10 @@ static int acf_dsmball_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dsmball_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dsmball_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1807,7 +1812,7 @@ static int acf_dsmball_setting_flag(bAnimContext *UNUSED(ac), int setting, short return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1853,7 +1858,7 @@ static bAnimChannelType ACF_DSMBALL = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dsmball_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1870,10 +1875,10 @@ static int acf_dsarm_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dsarm_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dsarm_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1883,7 +1888,7 @@ static int acf_dsarm_setting_flag(bAnimContext *UNUSED(ac), int setting, short * return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1929,7 +1934,7 @@ static bAnimChannelType ACF_DSARM = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dsarm_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1957,10 +1962,10 @@ static short acf_dsntree_offset(bAnimContext *ac, bAnimListElem *ale) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dsntree_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dsntree_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1970,7 +1975,7 @@ static int acf_dsntree_setting_flag(bAnimContext *UNUSED(ac), int setting, short return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -2016,7 +2021,7 @@ static bAnimChannelType ACF_DSNTREE = acf_dsntree_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dsntree_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -2033,10 +2038,10 @@ static int acf_dslinestyle_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dslinestyle_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dslinestyle_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -2046,7 +2051,7 @@ static int acf_dslinestyle_setting_flag(bAnimContext *UNUSED(ac), int setting, s return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -2092,7 +2097,7 @@ static bAnimChannelType ACF_DSLINESTYLE = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dslinestyle_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -2109,10 +2114,10 @@ static int acf_dsmesh_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dsmesh_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dsmesh_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -2122,7 +2127,7 @@ static int acf_dsmesh_setting_flag(bAnimContext *UNUSED(ac), int setting, short return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -2168,7 +2173,7 @@ static bAnimChannelType ACF_DSMESH = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dsmesh_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -2185,10 +2190,10 @@ static int acf_dslat_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dslat_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dslat_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -2198,7 +2203,7 @@ static int acf_dslat_setting_flag(bAnimContext *UNUSED(ac), int setting, short * return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -2244,7 +2249,7 @@ static bAnimChannelType ACF_DSLAT = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dslat_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -2261,10 +2266,10 @@ static int acf_dsspk_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dsspk_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dsspk_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -2274,7 +2279,7 @@ static int acf_dsspk_setting_flag(bAnimContext *UNUSED(ac), int setting, short * return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -2320,7 +2325,7 @@ static bAnimChannelType ACF_DSSPK = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dsspk_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -2346,7 +2351,7 @@ static void acf_shapekey_name(bAnimListElem *ale, char *name) } /* name property for ShapeKey entries */ -static short acf_shapekey_nameprop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) +static bool acf_shapekey_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) { KeyBlock *kb = (KeyBlock *)ale->data; @@ -2358,29 +2363,29 @@ static short acf_shapekey_nameprop(bAnimListElem *ale, PointerRNA *ptr, Property return (*prop != NULL); } - return 0; + return false; } /* check if some setting exists for this channel */ -static short acf_shapekey_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) +static bool acf_shapekey_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) { switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted */ case ACHANNEL_SETTING_PROTECT: /* protected */ - return 1; + return true; /* nothing else is supported */ default: - return 0; + return false; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_shapekey_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_shapekey_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_MUTE: /* mute */ @@ -2427,7 +2432,7 @@ static bAnimChannelType ACF_SHAPEKEY = acf_generic_basic_offset, /* offset */ acf_shapekey_name, /* name */ - acf_shapekey_nameprop, /* name prop */ + acf_shapekey_name_prop, /* name prop */ NULL, /* icon */ acf_shapekey_setting_valid, /* has setting */ @@ -2451,24 +2456,24 @@ static int acf_gpd_icon(bAnimListElem *UNUSED(ale)) } /* check if some setting exists for this channel */ -static short acf_gpd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) +static bool acf_gpd_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; + return true; default: - return 0; + return false; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_gpd_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_gpd_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ @@ -2502,7 +2507,7 @@ static bAnimChannelType ACF_GPD = acf_generic_group_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idfill_nameprop, /* name prop */ + acf_generic_idfill_name_prop, /* name prop */ acf_gpd_icon, /* icon */ acf_gpd_setting_valid, /* has setting */ @@ -2522,7 +2527,7 @@ static void acf_gpl_name(bAnimListElem *ale, char *name) } /* name property for grease pencil layer entries */ -static short acf_gpl_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) +static bool acf_gpl_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) { if (ale->data) { RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, ptr); @@ -2531,29 +2536,30 @@ static short acf_gpl_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA return (*prop != NULL); } - return 0; + return false; } /* check if some setting exists for this channel */ -static short acf_gpl_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) +static bool acf_gpl_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) { switch (setting) { /* unsupported */ case ACHANNEL_SETTING_EXPAND: /* gpencil layers are more like F-Curves than groups */ case ACHANNEL_SETTING_VISIBLE: /* graph editor only */ - return 0; + case ACHANNEL_SETTING_SOLO: /* nla editor only */ + return false; /* always available */ default: - return 1; + return true; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_gpl_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_gpl_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ @@ -2563,7 +2569,6 @@ static int acf_gpl_setting_flag(bAnimContext *UNUSED(ac), int setting, short *ne return GP_LAYER_HIDE; case ACHANNEL_SETTING_PROTECT: /* protected */ - // *neg = 1; - if we change this to editability return GP_LAYER_LOCKED; default: /* unsupported */ @@ -2616,24 +2621,24 @@ static int acf_mask_icon(bAnimListElem *UNUSED(ale)) } /* check if some setting exists for this channel */ -static short acf_mask_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) +static bool 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; + return true; default: - return 0; + return false; } } /* 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) +static int acf_mask_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ @@ -2667,7 +2672,7 @@ static bAnimChannelType ACF_MASKDATA = acf_generic_group_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idfill_nameprop, /* name prop */ + acf_generic_idfill_name_prop, /* name prop */ acf_mask_icon, /* icon */ acf_mask_setting_valid, /* has setting */ @@ -2687,7 +2692,7 @@ static void acf_masklay_name(bAnimListElem *ale, char *name) } /* name property for grease pencil layer entries */ -static short acf_masklay_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) +static bool acf_masklay_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) { if (ale->data) { RNA_pointer_create(ale->id, &RNA_MaskLayer, ale->data, ptr); @@ -2696,39 +2701,36 @@ static short acf_masklay_name_prop(bAnimListElem *ale, PointerRNA *ptr, Property return (*prop != NULL); } - return 0; + return false; } /* check if some setting exists for this channel */ -static short acf_masklay_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) +static bool 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; + case ACHANNEL_SETTING_SOLO: /* nla editor only */ + return false; /* always available */ default: - return 1; + return true; } } /* 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) +static int acf_masklay_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; 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 editability return MASK_LAYERFLAG_LOCKED; default: /* unsupported */ @@ -2764,6 +2766,146 @@ static bAnimChannelType ACF_MASKLAYER = acf_masklay_setting_ptr /* pointer for setting */ }; +/* NLA Track ----------------------------------------------- */ + +/* get backdrop color for nla track channels */ +static void acf_nlatrack_color(bAnimContext *UNUSED(ac), bAnimListElem *ale, float r_color[3]) +{ + NlaTrack *nlt = (NlaTrack *)ale->data; + AnimData *adt = ale->adt; + bool nonSolo = false; + + /* is track enabled for solo drawing? */ + if ((adt) && (adt->flag & ADT_NLA_SOLO_TRACK)) { + if ((nlt->flag & NLATRACK_SOLO) == 0) { + /* tag for special non-solo handling */ + nonSolo = true; + } + } + + /* set color for nla track */ + UI_GetThemeColorShade3fv(TH_HEADER, ((nonSolo == false) ? 20 : -20), r_color); +} + +/* name for nla track entries */ +static void acf_nlatrack_name(bAnimListElem *ale, char *name) +{ + NlaTrack *nlt = (NlaTrack *)ale->data; + + if (nlt && name) + BLI_strncpy(name, nlt->name, ANIM_CHAN_NAME_SIZE); +} + +/* name property for nla track entries */ +static bool acf_nlatrack_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) +{ + if (ale->data) { + RNA_pointer_create(ale->id, &RNA_NlaTrack, ale->data, ptr); + *prop = RNA_struct_name_property(ptr->type); + + return (*prop != NULL); + } + + return false; +} + +/* check if some setting exists for this channel */ +static bool acf_nlatrack_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *ale, int setting) +{ + NlaTrack *nlt = (NlaTrack *)ale->data; + AnimData *adt = ale->adt; + + /* visibility of settings depends on various states... */ + switch (setting) { + /* always supported */ + case ACHANNEL_SETTING_SELECT: + case ACHANNEL_SETTING_SOLO: + return true; + + /* conditionally supported... */ + case ACHANNEL_SETTING_PROTECT: + case ACHANNEL_SETTING_MUTE: + /* if this track is active and we're tweaking it, don't draw these toggles */ + if (((nlt->flag & NLATRACK_ACTIVE) && (nlt->flag & NLATRACK_DISABLED)) == 0) { + /* is track enabled for solo drawing? */ + if ((adt) && (adt->flag & ADT_NLA_SOLO_TRACK)) { + if (nlt->flag & NLATRACK_SOLO) { + /* ok - we've got a solo track, and this is it */ + return true; + } + else { + /* not ok - we've got a solo track, but this isn't it, so make it more obvious */ + return false; + } + } + + + /* ok - no tracks are solo'd, and this isn't being tweaked */ + return true; + } + else { + /* unsupported - this track is being tweaked */ + return false; + } + + /* unsupported */ + default: + return false; + } +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_nlatrack_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) +{ + /* clear extra return data first */ + *neg = false; + + switch (setting) { + case ACHANNEL_SETTING_SELECT: /* selected */ + return NLATRACK_SELECTED; + + case ACHANNEL_SETTING_MUTE: /* muted */ + return NLATRACK_MUTED; + + case ACHANNEL_SETTING_PROTECT: /* protected */ + return NLATRACK_PROTECTED; + + case ACHANNEL_SETTING_SOLO: /* solo */ + return NLATRACK_SOLO; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_nlatrack_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type) +{ + NlaTrack *nlt = (NlaTrack *)ale->data; + return GET_ACF_FLAG_PTR(nlt->flag, type); +} + +/* nla track type define */ +static bAnimChannelType ACF_NLATRACK = +{ + "NLA Track", /* type name */ + + acf_nlatrack_color, /* backdrop color */ + acf_generic_channel_backdrop, /* backdrop */ + acf_generic_indention_flexible, /* indent level */ + acf_generic_group_offset, /* offset */ // XXX? + + acf_nlatrack_name, /* name */ + acf_nlatrack_name_prop, /* name prop */ + NULL, /* icon */ + + acf_nlatrack_setting_valid, /* has setting */ + acf_nlatrack_setting_flag, /* flag for setting */ + acf_nlatrack_setting_ptr /* pointer for setting */ +}; + + + /* *********************************************** */ /* Type Registration and General Access */ @@ -2822,9 +2964,9 @@ static void ANIM_init_channel_typeinfo_data(void) 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 */ + animchannelTypeInfo[type++] = &ACF_NLATRACK; /* NLA Track */ + + // TODO: this channel type still hasn't been ported over yet, since it requires special attention animchannelTypeInfo[type++] = NULL; /* NLA Action */ } } @@ -2888,7 +3030,8 @@ short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, int setting /* 1) check that the setting exists for the current context */ if ((acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting))) { /* 2) get pointer to check for flag in, and the flag to check for */ - short negflag, ptrsize; + short ptrsize; + bool negflag; int flag; void *ptr; @@ -2963,7 +3106,8 @@ void ANIM_channel_setting_set(bAnimContext *ac, bAnimListElem *ale, int setting, /* 1) check that the setting exists for the current context */ if ((acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting))) { /* 2) get pointer to check for flag in, and the flag to check for */ - short negflag, ptrsize; + short ptrsize; + bool negflag; int flag; void *ptr; @@ -3225,6 +3369,26 @@ static void achannel_setting_flush_widget_cb(bContext *C, void *ale_npoin, void BLI_freelistN(&anim_data); } +/* callback for wrapping NLA Track "solo" toggle logic */ +static void achannel_nlatrack_solo_widget_cb(bContext *C, void *adt_poin, void *nlt_poin) +{ + AnimData *adt = adt_poin; + NlaTrack *nlt = nlt_poin; + + /* Toggle 'solo' mode. There are several complications here which need explaining: + * - The method call is needed to perform a few additional validation operations + * to ensure that the mode is applied properly + * - BUT, since the button already toggles the value, we need to un-toggle it + * before the API call gets to it, otherwise it will end up clearing the result + * again! + */ + nlt->flag ^= NLATRACK_SOLO; + BKE_nlatrack_solo_toggle(adt, nlt); + + /* send notifiers */ + WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_RENAME, NULL); +} + /* callback for rename widgets - clear rename-in-progress */ static void achannel_setting_rename_done_cb(bContext *C, void *ads_poin, void *UNUSED(arg2)) { @@ -3325,7 +3489,8 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChannelType *acf, uiBlock *block, int xpos, int ypos, int setting) { - short negflag, ptrsize /* , enabled */ /* UNUSED */, butType; + short ptrsize, butType; + bool negflag; int flag, icon; void *ptr; const char *tooltip; @@ -3343,7 +3508,7 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann icon = ICON_VISIBLE_IPO_OFF; if (ale->type == ANIMTYPE_FCURVE) - tooltip = TIP_("Channel is visible in Graph Editor for editing"); + tooltip = TIP_("F-Curve is visible in Graph Editor for editing"); else tooltip = TIP_("Channels are visible in Graph Editor for editing"); break; @@ -3355,9 +3520,9 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann break; case ACHANNEL_SETTING_SOLO: /* NLA Tracks only */ - //icon = ((enabled) ? ICON_LAYER_ACTIVE : ICON_LAYER_USED); - icon = ICON_LAYER_USED; - tooltip = TIP_("NLA Track is the only one evaluated for the AnimData block it belongs to"); + //icon = ((enabled) ? ICON_SOLO_OFF : ICON_SOLO_ON); + icon = ICON_SOLO_OFF; + tooltip = TIP_("NLA Track is the only one evaluated in this Animation Data block, with all others muted"); break; /* --- */ @@ -3366,14 +3531,18 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann // TODO: what about when there's no protect needed? //icon = ((enabled) ? ICON_LOCKED : ICON_UNLOCKED); icon = ICON_UNLOCKED; - tooltip = TIP_("Editability of keyframes for this channel"); + + if (ale->datatype != ALE_NLASTRIP) + tooltip = TIP_("Editability of keyframes for this channel"); + else + tooltip = TIP_("Editability of NLA Strips in this track"); break; case ACHANNEL_SETTING_MUTE: /* muted speaker */ //icon = ((enabled) ? ICON_MUTE_IPO_ON : ICON_MUTE_IPO_OFF); icon = ICON_MUTE_IPO_OFF; - if (ale->type == ALE_FCURVE) + if (ale->type == ANIMTYPE_FCURVE) tooltip = TIP_("Does F-Curve contribute to result"); else tooltip = TIP_("Do channels contribute to result"); @@ -3420,6 +3589,11 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann uiButSetNFunc(but, achannel_setting_flush_widget_cb, MEM_dupallocN(ale), SET_INT_IN_POINTER(setting)); break; + /* settings needing special attention */ + case ACHANNEL_SETTING_SOLO: /* NLA Tracks - Solo toggle */ + uiButSetFunc(but, achannel_nlatrack_solo_widget_cb, ale->adt, ale->data); + break; + /* no flushing */ case ACHANNEL_SETTING_EXPAND: /* expanding - cannot flush, otherwise all would open/close at once */ default: diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index e04c51b33d8..33ca10420ec 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -58,6 +58,7 @@ #include "UI_view2d.h" #include "ED_anim_api.h" +#include "ED_armature.h" #include "ED_keyframes_edit.h" // XXX move the select modes out of there! #include "ED_screen.h" @@ -1106,7 +1107,6 @@ static int animchannels_rearrange_exec(bContext *C, wmOperator *op) break; case ANIMCONT_SHAPEKEY: // DOUBLE CHECK ME... - default: /* some collection of actions */ if (adt->action) rearrange_action_channels(&ac, adt->action, mode); @@ -2441,6 +2441,35 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in { bActionGroup *agrp = (bActionGroup *)ale->data; + Object *ob = NULL; + bPoseChannel *pchan = NULL; + + + /* Armatures-Specific Feature: + * Since groups are used to collect F-Curves of the same Bone by default + * (via Keying Sets) so that they can be managed better, we try to make + * things here easier for animators by mapping group selection to bone + * selection. + * + * Only do this if "Only Selected" dopesheet filter is not active, or else it + * becomes too unpredictable/tricky to manage + */ + if ((ac->ads->filterflag & ADS_FILTER_ONLYSEL) == 0) { + if ((ale->id) && (GS(ale->id->name) == ID_OB)) { + ob = (Object *)ale->id; + + if (ob->type == OB_ARMATURE) { + /* Assume for now that any group with corresponding name is what we want + * (i.e. for an armature whose location is animated, things would break + * if the user were to add a bone named "Location"). + * + * TODO: check the first F-Curve or so to be sure... + */ + pchan = BKE_pose_channel_find_name(ob->pose, agrp->name); + } + } + } + /* select/deselect group */ if (selectmode == SELECT_INVERT) { /* inverse selection status of this group only */ @@ -2452,6 +2481,7 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in /* deselect all other channels */ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); + if (pchan) ED_pose_deselectall(ob, 0); /* only select channels in group and group itself */ for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcu->next) @@ -2461,14 +2491,20 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in else { /* select group by itself */ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); + if (pchan) ED_pose_deselectall(ob, 0); + agrp->flag |= AGRP_SELECTED; } /* if group is selected now, make group the 'active' one in the visible list */ - if (agrp->flag & AGRP_SELECTED) + if (agrp->flag & AGRP_SELECTED) { ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP); - else + if (pchan) ED_pose_bone_select(ob, pchan, true); + } + else { ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, NULL, ANIMTYPE_GROUP); + if (pchan) ED_pose_bone_select(ob, pchan, false); + } notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); break; diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 9e8800fd91e..25fcd76b513 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -33,6 +33,7 @@ #include "DNA_anim_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_space_types.h" #include "DNA_userdef_types.h" #include "BLI_math.h" @@ -359,9 +360,68 @@ void ANIM_nla_mapping_apply_fcurve(AnimData *adt, FCurve *fcu, short restore, sh /* *************************************************** */ /* UNITS CONVERSION MAPPING (required for drawing and editing keyframes) */ +/* Get flags used for normalization in ANIM_unit_mapping_get_factor. */ +short ANIM_get_normalization_flags(bAnimContext *ac) +{ + if (ac->sl->spacetype == SPACE_IPO) { + SpaceIpo *sipo = (SpaceIpo *) ac->sl; + bool use_normalization = (sipo->flag & SIPO_NORMALIZE) != 0; + bool freeze_normalization = (sipo->flag & SIPO_NORMALIZE_FREEZE) != 0; + return use_normalization + ? (ANIM_UNITCONV_NORMALIZE | (freeze_normalization ? ANIM_UNITCONV_NORMALIZE_FREEZE : 0)) + : 0; + } + + return 0; +} + +static float normalzation_factor_get(FCurve *fcu, short flag) +{ + float factor = 1.0f; + + if (flag & ANIM_UNITCONV_RESTORE) { + return 1.0f / fcu->prev_norm_factor; + } + + if (flag & ANIM_UNITCONV_NORMALIZE_FREEZE) { + return fcu->prev_norm_factor; + } + + if (G.moving & G_TRANSFORM_FCURVES) { + return fcu->prev_norm_factor; + } + + fcu->prev_norm_factor = 1.0f; + if (fcu->bezt) { + BezTriple *bezt; + int i; + float max_coord = -FLT_MAX; + + if (fcu->totvert < 1) { + return 1.0f; + } + + for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) { + max_coord = max_ff(max_coord, fabsf(bezt->vec[0][1])); + max_coord = max_ff(max_coord, fabsf(bezt->vec[1][1])); + max_coord = max_ff(max_coord, fabsf(bezt->vec[2][1])); + } + + if (max_coord > FLT_EPSILON) { + factor = 1.0f / max_coord; + } + } + fcu->prev_norm_factor = factor; + return factor; +} + /* Get unit conversion factor for given ID + F-Curve */ -float ANIM_unit_mapping_get_factor(Scene *scene, ID *id, FCurve *fcu, short restore) +float ANIM_unit_mapping_get_factor(Scene *scene, ID *id, FCurve *fcu, short flag) { + if (flag & ANIM_UNITCONV_NORMALIZE) { + return normalzation_factor_get(fcu, flag); + } + /* sanity checks */ if (id && fcu && fcu->rna_path) { PointerRNA ptr, id_ptr; @@ -374,7 +434,7 @@ float ANIM_unit_mapping_get_factor(Scene *scene, ID *id, FCurve *fcu, short rest if (RNA_SUBTYPE_UNIT(RNA_property_subtype(prop)) == PROP_UNIT_ROTATION) { /* if the radians flag is not set, default to using degrees which need conversions */ if ((scene) && (scene->unit.system_rotation == USER_UNIT_ROT_RADIANS) == 0) { - if (restore) + if (flag & ANIM_UNITCONV_RESTORE) return DEG2RADF(1.0f); /* degrees to radians */ else return RAD2DEGF(1.0f); /* radians to degrees */ @@ -389,76 +449,4 @@ float ANIM_unit_mapping_get_factor(Scene *scene, ID *id, FCurve *fcu, short rest return 1.0f; } -/* ----------------------- */ - -/* helper function for ANIM_unit_mapping_apply_fcurve -> mapping callback for unit mapping */ -static short bezt_unit_mapping_apply(KeyframeEditData *ked, BezTriple *bezt) -{ - /* mapping factor is stored in f1, flags are stored in i1 */ - const bool only_keys = (ked->i1 & ANIM_UNITCONV_ONLYKEYS) != 0; - const bool sel_vs = (ked->i1 & ANIM_UNITCONV_SELVERTS) != 0; - const bool skip_knot = (ked->i1 & ANIM_UNITCONV_SKIPKNOTS) != 0; - float fac = ked->f1; - - /* adjust BezTriple handles only if allowed to */ - if (only_keys == false) { - if ((sel_vs == false) || (bezt->f1 & SELECT)) - bezt->vec[0][1] *= fac; - if ((sel_vs == false) || (bezt->f3 & SELECT)) - bezt->vec[2][1] *= fac; - } - - if (skip_knot == false) { - if ((sel_vs == false) || (bezt->f2 & SELECT)) - bezt->vec[1][1] *= fac; - } - - return 0; -} - -/* Apply/Unapply units conversions to keyframes */ -void ANIM_unit_mapping_apply_fcurve(Scene *scene, ID *id, FCurve *fcu, short flag) -{ - KeyframeEditData ked; - KeyframeEditFunc sel_cb; - float fac; - - /* abort if rendering - we may get some race condition issues... */ - if (G.is_rendering) return; - - /* calculate mapping factor, and abort if nothing to change */ - fac = ANIM_unit_mapping_get_factor(scene, id, fcu, (flag & ANIM_UNITCONV_RESTORE)); - if (fac == 1.0f) - return; - - /* init edit data - * - mapping factor is stored in f1 - * - flags are stored in 'i1' - */ - memset(&ked, 0, sizeof(KeyframeEditData)); - ked.f1 = (float)fac; - ked.i1 = (int)flag; - - /* only selected? */ - if (flag & ANIM_UNITCONV_ONLYSEL) - sel_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED); - else - sel_cb = NULL; - - /* apply to F-Curve */ - ANIM_fcurve_keyframes_loop(&ked, fcu, sel_cb, bezt_unit_mapping_apply, NULL); - - // FIXME: loop here for samples should be generalised - // TODO: only sel? - if (fcu->fpt) { - FPoint *fpt; - unsigned int i; - - for (i = 0, fpt = fcu->fpt; i < fcu->totvert; i++, fpt++) { - /* apply unit mapping */ - fpt->vec[1] *= fac; - } - } -} - /* *************************************************** */ diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 09b6e7d2206..ad745155286 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1503,8 +1503,7 @@ static size_t animdata_filter_mask(ListBase *anim_data, void *UNUSED(data), int } /* 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) +static size_t animdata_filter_ds_nodetree_group(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, bNodeTree *ntree, int filter_mode) { ListBase tmp_data = {NULL, NULL}; size_t tmp_items = 0; @@ -1538,6 +1537,32 @@ static size_t animdata_filter_ds_nodetree(bAnimContext *ac, ListBase *anim_data, return items; } +static size_t animdata_filter_ds_nodetree(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, bNodeTree *ntree, int filter_mode) +{ + bNode *node; + size_t items = 0; + int group_filter_mode = filter_mode & ~ADS_FILTER_ONLYSEL; + + items += animdata_filter_ds_nodetree_group(ac, anim_data, ads, owner_id, ntree, filter_mode); + + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == NODE_GROUP) { + if (node->id) { + int filterflag = ads->filterflag; + if ((filter_mode & ADS_FILTER_ONLYSEL) && (node->flag & NODE_SELECT) == 0) { + continue; + } + /* TODO(sergey): A bit creepy, but this flag is not used from threads anyway. */ + ads->filterflag &= ~ADS_FILTER_ONLYSEL; + items += animdata_filter_ds_nodetree_group(ac, anim_data, ads, owner_id, (bNodeTree *) node->id, group_filter_mode); + ads->filterflag = filterflag; + } + } + } + + return items; +} + static size_t animdata_filter_ds_linestyle(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode) { SceneRenderLayer *srl; @@ -2599,24 +2624,50 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, int filter_mo /* firstly filter the data */ switch (datatype) { + /* Action-Editing Modes */ case ANIMCONT_ACTION: /* 'Action Editor' */ { Object *obact = ac->obact; SpaceAction *saction = (SpaceAction *)ac->sl; bDopeSheet *ads = (saction) ? &saction->ads : NULL; - /* the check for the DopeSheet summary is included here since the summary works here too */ - if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items)) - items += animfilter_action(ac, anim_data, ads, data, filter_mode, (ID *)obact); + /* specially check for AnimData filter... [#36687] */ + if (UNLIKELY(filter_mode & ANIMFILTER_ANIMDATA)) { + /* all channels here are within the same AnimData block, hence this special case */ + if (LIKELY(obact->adt)) { + ANIMCHANNEL_NEW_CHANNEL(obact->adt, ANIMTYPE_ANIMDATA, (ID *)obact); + } + } + else { + /* the check for the DopeSheet summary is included here since the summary works here too */ + if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items)) + 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 */ - if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items)) - items = animdata_filter_shapekey(ac, anim_data, data, filter_mode); + Key *key = (Key *)data; + + /* specially check for AnimData filter... [#36687] */ + if (UNLIKELY(filter_mode & ANIMFILTER_ANIMDATA)) { + /* all channels here are within the same AnimData block, hence this special case */ + if (LIKELY(key->adt)) { + ANIMCHANNEL_NEW_CHANNEL(key->adt, ANIMTYPE_ANIMDATA, (ID *)key); + } + } + else { + /* the check for the DopeSheet summary is included here since the summary works here too */ + if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items)) + items = animdata_filter_shapekey(ac, anim_data, key, filter_mode); + } + break; } + + + /* Modes for Specialty Data Types (i.e. not keyframes) */ case ANIMCONT_GPENCIL: { if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items)) @@ -2629,6 +2680,9 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, int filter_mo items = animdata_filter_mask(anim_data, data, filter_mode); break; } + + + /* DopeSheet Based Modes */ case ANIMCONT_DOPESHEET: /* 'DopeSheet Editor' */ { /* the DopeSheet editor is the primary place where the DopeSheet summaries are useful */ @@ -2644,6 +2698,9 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, int filter_mo items = animdata_filter_dopesheet(ac, anim_data, data, filter_mode); break; } + + + /* Special/Internal Use */ case ANIMCONT_CHANNEL: /* animation channel */ { bDopeSheet *ads = ac->ads; diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index 34246427b7e..cab072675b2 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -197,58 +197,23 @@ void ED_markers_get_minmax(ListBase *markers, short sel, float *first, float *la { TimeMarker *marker; float min, max; - int selcount = 0; /* sanity check */ //printf("markers = %p - %p, %p\n", markers, markers->first, markers->last); - if (markers == NULL) { - *first = 0.0f; - *last = 0.0f; - return; - } - - if (markers->first && markers->last) { - TimeMarker *fm = markers->first; - TimeMarker *lm = markers->last; - - min = (float)fm->frame; - max = (float)lm->frame; - } - else { + if (ELEM3(NULL, markers, markers->first, markers->last)) { *first = 0.0f; *last = 0.0f; return; } - - /* count how many markers are usable - see later */ - if (sel) { - for (marker = markers->first; marker; marker = marker->next) { - if (marker->flag & SELECT) - selcount++; - } - } - else - selcount = BLI_countlist(markers); - - /* if only selected are to be considered, only consider the selected ones - * (optimization for not searching list) - */ - if (selcount > 1) { - for (marker = markers->first; marker; marker = marker->next) { - if (sel) { - if (marker->flag & SELECT) { - if (marker->frame < min) - min = (float)marker->frame; - if (marker->frame > max) - max = (float)marker->frame; - } - } - else { - if (marker->frame < min) - min = (float)marker->frame; - if (marker->frame > max) - max = (float)marker->frame; - } + + min = FLT_MAX; + max = -FLT_MAX; + for (marker = markers->first; marker; marker = marker->next) { + if (!sel || (marker->flag & SELECT)) { + if (marker->frame < min) + min = (float)marker->frame; + if (marker->frame > max) + max = (float)marker->frame; } } @@ -746,13 +711,11 @@ static void ed_marker_move_apply(bContext *C, wmOperator *op) } /* only for modal */ -static int ed_marker_move_cancel(bContext *C, wmOperator *op) +static void ed_marker_move_cancel(bContext *C, wmOperator *op) { RNA_int_set(op->ptr, "frames", 0); ed_marker_move_apply(C, op); ed_marker_move_exit(C, op); - - return OPERATOR_CANCELLED; } @@ -769,7 +732,6 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, const wmEvent *even case ESCKEY: ed_marker_move_cancel(C, op); return OPERATOR_CANCELLED; - case RIGHTMOUSE: /* press = user manually demands transform to be canceled */ if (event->val == KM_PRESS) { diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 15a75c57758..af9b58736ef 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -118,13 +118,21 @@ static int change_frame_exec(bContext *C, wmOperator *op) static int frame_from_event(bContext *C, const wmEvent *event) { ARegion *region = CTX_wm_region(C); + Scene *scene = CTX_data_scene(C); float viewx; + int frame; /* convert from region coordinates to View2D 'tot' space */ UI_view2d_region_to_view(®ion->v2d, event->mval[0], event->mval[1], &viewx, NULL); /* round result to nearest int (frames are ints!) */ - return (int)floor(viewx + 0.5f); + frame = (int)floor(viewx + 0.5f); + + if (scene->r.flag & SCER_LOCK_FRAME_SELECTION) { + CLAMP(frame, PSFRA, PEFRA); + } + + return frame; } /* Modal Operator init */ diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index 826e204d981..bbfa981c0c7 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -76,7 +76,7 @@ void free_anim_drivers_copybuf(void); * * - add: 0 - don't add anything if not found, * 1 - add new Driver FCurve (with keyframes for visual tweaking), - * 2 - add new Driver FCurve (with generator, for script backwards compatability) + * 2 - add new Driver FCurve (with generator, for script backwards compatibility) * -1 - add new Driver FCurve without driver stuff (for pasting) */ FCurve *verify_driver_fcurve(ID *id, const char rna_path[], const int array_index, short add) @@ -125,7 +125,7 @@ FCurve *verify_driver_fcurve(ID *id, const char rna_path[], const int array_inde /* F-Modifier or Keyframes? */ // FIXME: replace these magic numbers with defines if (add == 2) { - /* Python API Backwards compatability hack: + /* Python API Backwards compatibility hack: * Create FModifier so that old scripts won't break * for now before 2.7 series -- (September 4, 2013) */ diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 6b9200afb75..1028fb30ba4 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -1100,7 +1100,7 @@ short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char grou if (BKE_fcurve_is_protected(fcu)) { BKE_reportf(reports, RPT_WARNING, - "not deleting keyframe for locked F-Curve '%s' for %s '%s'", + "Not deleting keyframe for locked F-Curve '%s' for %s '%s'", fcu->rna_path, BKE_idcode_to_name(GS(id->name)), id->name + 2); continue; } @@ -1225,7 +1225,7 @@ static int modify_key_op_poll(bContext *C) /* if Outliner, don't allow in some views */ if (so) { - if (ELEM5(so->outlinevis, SO_GROUPS, SO_LIBRARIES, SO_SEQUENCE, SO_USERDEF, SO_KEYMAP)) { + if (ELEM4(so->outlinevis, SO_GROUPS, SO_LIBRARIES, SO_SEQUENCE, SO_USERDEF)) { return 0; } } @@ -1570,7 +1570,7 @@ static int delete_key_v3d_exec(bContext *C, wmOperator *op) if (BKE_fcurve_is_protected(fcu)) { BKE_reportf(op->reports, RPT_WARNING, - "not deleting keyframe for locked F-Curve '%s', object '%s'", + "Not deleting keyframe for locked F-Curve '%s', object '%s'", fcu->rna_path, id->name + 2); continue; } diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c index d480d41f5d6..b91deab6c8d 100644 --- a/source/blender/editors/armature/armature_add.c +++ b/source/blender/editors/armature/armature_add.c @@ -176,7 +176,7 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op)) newbone->flag |= BONE_CONNECTED; } - curs = give_cursor(scene, v3d); + curs = ED_view3d_cursor3d_get(scene, v3d); copy_v3_v3(newbone->tail, curs); sub_v3_v3v3(newbone->tail, newbone->tail, obedit->obmat[3]); @@ -216,7 +216,7 @@ static int armature_click_extrude_invoke(bContext *C, wmOperator *op, const wmEv ar = CTX_wm_region(C); v3d = CTX_wm_view3d(C); - fp = give_cursor(scene, v3d); + fp = ED_view3d_cursor3d_get(scene, v3d); copy_v3_v3(oldcurs, fp); @@ -624,7 +624,7 @@ static int armature_extrude_exec(bContext *C, wmOperator *op) BLI_strncpy(newbone->name, ebone->name, sizeof(newbone->name)); if (flipbone && forked) { // only set if mirror edit - if (strlen(newbone->name) < 30) { + if (strlen(newbone->name) < (MAXBONENAME - 2)) { if (a == 0) strcat(newbone->name, "_L"); else strcat(newbone->name, "_R"); } @@ -691,7 +691,7 @@ static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op) RNA_string_get(op->ptr, "name", name); - copy_v3_v3(curs, give_cursor(CTX_data_scene(C), CTX_wm_view3d(C))); + copy_v3_v3(curs, ED_view3d_cursor3d_get(CTX_data_scene(C), CTX_wm_view3d(C))); /* Get inverse point for head and orientation for tail */ invert_m4_m4(obedit->imat, obedit->obmat); diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c index 90c1a439a19..1bc5bf0fd74 100644 --- a/source/blender/editors/armature/armature_edit.c +++ b/source/blender/editors/armature/armature_edit.c @@ -252,7 +252,7 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); /* can be NULL */ float cursor_local[3]; - const float *cursor = give_cursor(scene, v3d); + const float *cursor = ED_view3d_cursor3d_get(scene, v3d); copy_v3_v3(cursor_local, cursor); @@ -484,7 +484,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op) /* the number of joints determines how we fill: * 1) between joint and cursor (joint=head, cursor=tail) - * 2) between the two joints (order is dependent on active-bone/hierachy) + * 2) between the two joints (order is dependent on active-bone/hierarchy) * 3+) error (a smarter method involving finding chains needs to be worked out */ count = BLI_countlist(&points); @@ -502,7 +502,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op) /* Get points - cursor (tail) */ invert_m4_m4(obedit->imat, obedit->obmat); - mul_v3_m4v3(curs, obedit->imat, give_cursor(scene, v3d)); + mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d)); /* Create a bone */ /* newbone = */ add_points_bone(obedit, ebp->vec, curs); @@ -536,7 +536,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op) /* get cursor location */ invert_m4_m4(obedit->imat, obedit->obmat); - mul_v3_m4v3(curs, obedit->imat, give_cursor(scene, v3d)); + mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d)); /* get distances */ sub_v3_v3v3(vecA, ebp->vec, curs); @@ -583,8 +583,11 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op) else newbone->parent = ebp2->head_owner; } - - newbone->flag |= BONE_CONNECTED; + + /* don't set for bone connecting two head points of bones */ + if (ebp->tail_owner || ebp2->tail_owner) { + newbone->flag |= BONE_CONNECTED; + } } } else { @@ -840,7 +843,7 @@ static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) armature_tag_select_mirrored(arm); /* clear BONE_TRANSFORM flags - * - used to prevent duplicate/cancelling operations from occurring [#34123] + * - used to prevent duplicate/canceling operations from occurring [#34123] * - BONE_DONE cannot be used here as that's already used for mirroring */ armature_clear_swap_done_flags(arm); @@ -1063,6 +1066,44 @@ void ARMATURE_OT_align(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/* ********************************* Split ******************************* */ + +static int armature_split_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *ob = CTX_data_edit_object(C); + bArmature *arm = (bArmature *)ob->data; + EditBone *bone; + + for (bone = arm->edbo->first; bone; bone = bone->next) { + if (bone->parent && (bone->flag & BONE_SELECTED) != (bone->parent->flag & BONE_SELECTED)) { + bone->parent = NULL; + bone->flag &= ~BONE_CONNECTED; + } + } + for (bone = arm->edbo->first; bone; bone = bone->next) { + ED_armature_ebone_select_set(bone, (bone->flag & BONE_SELECTED) != 0); + } + + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob); + + return OPERATOR_FINISHED; +} + +void ARMATURE_OT_split(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Split"; + ot->idname = "ARMATURE_OT_split"; + ot->description = "Split off selected bones from connected unselected bones"; + + /* api callbacks */ + ot->exec = armature_split_exec; + ot->poll = ED_operator_editarmature; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /* ********************************* Delete ******************************* */ /* previously delete_armature */ @@ -1086,7 +1127,7 @@ static int armature_delete_selected_exec(bContext *C, wmOperator *UNUSED(op)) bPoseChannel *pchan, *pchan_next; for (pchan = obedit->pose->chanbase.first; pchan; pchan = pchan_next) { pchan_next = pchan->next; - curBone = editbone_name_exists(arm->edbo, pchan->name); + curBone = ED_armature_bone_find_name(arm->edbo, pchan->name); if (curBone && (curBone->flag & BONE_SELECTED) && (arm->layer & curBone->layer)) { BKE_pose_channel_free(pchan); @@ -1105,7 +1146,7 @@ static int armature_delete_selected_exec(bContext *C, wmOperator *UNUSED(op)) for (ct = targets.first; ct; ct = ct->next) { if (ct->tar == obedit) { if (ct->subtarget[0]) { - curBone = editbone_name_exists(arm->edbo, ct->subtarget); + curBone = ED_armature_bone_find_name(arm->edbo, ct->subtarget); if (curBone && (curBone->flag & BONE_SELECTED) && (arm->layer & curBone->layer)) { con->flag |= CONSTRAINT_DISABLE; ct->subtarget[0] = 0; diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h index e58d8fd2380..f3db9042879 100644 --- a/source/blender/editors/armature/armature_intern.h +++ b/source/blender/editors/armature/armature_intern.h @@ -62,12 +62,13 @@ void ARMATURE_OT_parent_set(struct wmOperatorType *ot); void ARMATURE_OT_parent_clear(struct wmOperatorType *ot); void ARMATURE_OT_select_all(struct wmOperatorType *ot); -void ARMATURE_OT_select_inverse(struct wmOperatorType *ot); +void ARMATURE_OT_select_mirror(struct wmOperatorType *ot); void ARMATURE_OT_select_more(struct wmOperatorType *ot); void ARMATURE_OT_select_less(struct wmOperatorType *ot); void ARMATURE_OT_select_hierarchy(struct wmOperatorType *ot); void ARMATURE_OT_select_linked(struct wmOperatorType *ot); void ARMATURE_OT_select_similar(struct wmOperatorType *ot); +void ARMATURE_OT_shortest_path_pick(struct wmOperatorType *ot); void ARMATURE_OT_delete(struct wmOperatorType *ot); void ARMATURE_OT_duplicate(struct wmOperatorType *ot); @@ -78,6 +79,7 @@ void ARMATURE_OT_click_extrude(struct wmOperatorType *ot); void ARMATURE_OT_fill(struct wmOperatorType *ot); void ARMATURE_OT_merge(struct wmOperatorType *ot); void ARMATURE_OT_separate(struct wmOperatorType *ot); +void ARMATURE_OT_split(struct wmOperatorType *ot); void ARMATURE_OT_autoside_names(struct wmOperatorType *ot); void ARMATURE_OT_flip_names(struct wmOperatorType *ot); @@ -109,7 +111,7 @@ void POSE_OT_select_hierarchy(struct wmOperatorType *ot); void POSE_OT_select_linked(struct wmOperatorType *ot); void POSE_OT_select_constraint_target(struct wmOperatorType *ot); void POSE_OT_select_grouped(struct wmOperatorType *ot); -void POSE_OT_select_flip_active(struct wmOperatorType *ot); +void POSE_OT_select_mirror(struct wmOperatorType *ot); void POSE_OT_group_add(struct wmOperatorType *ot); void POSE_OT_group_remove(struct wmOperatorType *ot); @@ -228,9 +230,6 @@ struct EditBone *duplicateEditBoneObjects(struct EditBone *curBone, const char * /* editbones is the source list */ void updateDuplicateSubtargetObjects(struct EditBone *dupBone, struct ListBase *editbones, struct Object *src_ob, struct Object *dst_ob); - -EditBone *editbone_name_exists(struct ListBase *edbo, const char *name); - EditBone *add_points_bone(struct Object *obedit, float head[3], float tail[3]); void bone_free(struct bArmature *arm, struct EditBone *bone); diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c index 8745d571a28..c574fc6a297 100644 --- a/source/blender/editors/armature/armature_naming.c +++ b/source/blender/editors/armature/armature_naming.c @@ -67,17 +67,11 @@ /* ************************************************** */ /* EditBone Names */ -/* checks if an EditBone with a matching name already, returning the matching bone if it exists */ -EditBone *editbone_name_exists(ListBase *edbo, const char *name) -{ - return BLI_findstring(edbo, name, offsetof(EditBone, name)); -} - /* note: there's a unique_bone_name() too! */ static bool editbone_unique_check(void *arg, const char *name) { struct {ListBase *lb; void *bone; } *data = arg; - EditBone *dupli = editbone_name_exists(data->lb, name); + EditBone *dupli = ED_armature_bone_find_name(data->lb, name); return dupli && dupli != data->bone; } @@ -113,6 +107,7 @@ static void constraint_bone_name_fix(Object *ob, ListBase *conlist, const char * bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon); ListBase targets = {NULL, NULL}; + /* constraint targets */ if (cti && cti->get_constraint_targets) { cti->get_constraint_targets(curcon, &targets); @@ -126,6 +121,12 @@ static void constraint_bone_name_fix(Object *ob, ListBase *conlist, const char * if (cti->flush_constraint_targets) cti->flush_constraint_targets(curcon, &targets, 0); } + + /* action constraints */ + if (curcon->type == CONSTRAINT_TYPE_ACTION) { + bActionConstraint *actcon = (bActionConstraint *)curcon->data; + BKE_action_fix_paths_rename(&ob->id, actcon->act, "pose.bones", oldname, newname, 0, 0, 1); + } } } @@ -148,7 +149,7 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n /* now check if we're in editmode, we need to find the unique name */ if (arm->edbo) { - EditBone *eBone = editbone_name_exists(arm->edbo, oldname); + EditBone *eBone = ED_armature_bone_find_name(arm->edbo, oldname); if (eBone) { unique_editbone_name(arm->edbo, newname, NULL); @@ -282,7 +283,6 @@ static int armature_flip_names_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = CTX_data_edit_object(C); bArmature *arm; - char newname[MAXBONENAME]; /* paranoia checks */ if (ELEM(NULL, ob, ob->pose)) @@ -292,8 +292,9 @@ static int armature_flip_names_exec(bContext *C, wmOperator *UNUSED(op)) /* loop through selected bones, auto-naming them */ 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); + char name_flip[MAXBONENAME]; + BKE_deform_flip_side_name(name_flip, ebone->name, true); + ED_armature_bone_rename(arm, ebone->name, name_flip); } CTX_DATA_END; diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c index 0090522d1e1..feb9b0f939a 100644 --- a/source/blender/editors/armature/armature_ops.c +++ b/source/blender/editors/armature/armature_ops.c @@ -58,12 +58,13 @@ void ED_operatortypes_armature(void) WM_operatortype_append(ARMATURE_OT_parent_clear); WM_operatortype_append(ARMATURE_OT_select_all); - WM_operatortype_append(ARMATURE_OT_select_inverse); + WM_operatortype_append(ARMATURE_OT_select_mirror); WM_operatortype_append(ARMATURE_OT_select_more); WM_operatortype_append(ARMATURE_OT_select_less); WM_operatortype_append(ARMATURE_OT_select_hierarchy); WM_operatortype_append(ARMATURE_OT_select_linked); WM_operatortype_append(ARMATURE_OT_select_similar); + WM_operatortype_append(ARMATURE_OT_shortest_path_pick); WM_operatortype_append(ARMATURE_OT_delete); WM_operatortype_append(ARMATURE_OT_duplicate); @@ -74,6 +75,7 @@ void ED_operatortypes_armature(void) WM_operatortype_append(ARMATURE_OT_fill); WM_operatortype_append(ARMATURE_OT_merge); WM_operatortype_append(ARMATURE_OT_separate); + WM_operatortype_append(ARMATURE_OT_split); WM_operatortype_append(ARMATURE_OT_autoside_names); WM_operatortype_append(ARMATURE_OT_flip_names); @@ -115,7 +117,7 @@ void ED_operatortypes_armature(void) WM_operatortype_append(POSE_OT_select_linked); WM_operatortype_append(POSE_OT_select_constraint_target); WM_operatortype_append(POSE_OT_select_grouped); - WM_operatortype_append(POSE_OT_select_flip_active); + WM_operatortype_append(POSE_OT_select_mirror); WM_operatortype_append(POSE_OT_group_add); WM_operatortype_append(POSE_OT_group_remove); @@ -165,37 +167,31 @@ void ED_operatormacros_armature(void) { wmOperatorType *ot; wmOperatorTypeMacro *otmacro; - + ot = WM_operatortype_append_macro("ARMATURE_OT_duplicate_move", "Duplicate", "Make copies of the selected bones within the same armature and move them", OPTYPE_UNDO | OPTYPE_REGISTER); - if (ot) { - WM_operatortype_macro_define(ot, "ARMATURE_OT_duplicate"); - otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); - RNA_enum_set(otmacro->ptr, "proportional", 0); - } + WM_operatortype_macro_define(ot, "ARMATURE_OT_duplicate"); + otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); + RNA_enum_set(otmacro->ptr, "proportional", 0); ot = WM_operatortype_append_macro("ARMATURE_OT_extrude_move", "Extrude", "Create new bones from the selected joints and move them", OPTYPE_UNDO | OPTYPE_REGISTER); - if (ot) { - otmacro = WM_operatortype_macro_define(ot, "ARMATURE_OT_extrude"); - RNA_boolean_set(otmacro->ptr, "forked", FALSE); - otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); - RNA_enum_set(otmacro->ptr, "proportional", 0); - } - + otmacro = WM_operatortype_macro_define(ot, "ARMATURE_OT_extrude"); + RNA_boolean_set(otmacro->ptr, "forked", FALSE); + otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); + RNA_enum_set(otmacro->ptr, "proportional", 0); + /* XXX would it be nicer to just be able to have standard extrude_move, but set the forked property separate? * that would require fixing a properties bug 19733 */ ot = WM_operatortype_append_macro("ARMATURE_OT_extrude_forked", "Extrude Forked", "Create new bones from the selected joints and move them", OPTYPE_UNDO | OPTYPE_REGISTER); - if (ot) { - otmacro = WM_operatortype_macro_define(ot, "ARMATURE_OT_extrude"); - RNA_boolean_set(otmacro->ptr, "forked", TRUE); - otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); - RNA_enum_set(otmacro->ptr, "proportional", 0); - } + otmacro = WM_operatortype_macro_define(ot, "ARMATURE_OT_extrude"); + RNA_boolean_set(otmacro->ptr, "forked", TRUE); + otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); + RNA_enum_set(otmacro->ptr, "proportional", 0); } void ED_keymap_armature(wmKeyConfig *keyconf) @@ -245,6 +241,9 @@ void ED_keymap_armature(wmKeyConfig *keyconf) RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + + kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_select_mirror", MKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, 0, 0); RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT); @@ -266,6 +265,8 @@ void ED_keymap_armature(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "ARMATURE_OT_select_similar", GKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "ARMATURE_OT_select_linked", LKEY, KM_PRESS, 0, 0); + + WM_keymap_add_item(keymap, "ARMATURE_OT_shortest_path_pick", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "ARMATURE_OT_delete", XKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "ARMATURE_OT_delete", DELKEY, KM_PRESS, 0, 0); @@ -275,6 +276,7 @@ void ED_keymap_armature(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "ARMATURE_OT_click_extrude", ACTIONMOUSE, KM_CLICK, KM_CTRL, 0); WM_keymap_add_item(keymap, "ARMATURE_OT_fill", FKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "ARMATURE_OT_merge", MKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "ARMATURE_OT_split", YKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "ARMATURE_OT_separate", PKEY, KM_PRESS, KM_CTRL | KM_ALT, 0); @@ -364,7 +366,7 @@ void ED_keymap_armature(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "POSE_OT_select_linked", LKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "POSE_OT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0); - WM_keymap_add_item(keymap, "POSE_OT_select_flip_active", FKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "POSE_OT_select_mirror", FKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "POSE_OT_constraint_add_with_targets", CKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); WM_keymap_add_item(keymap, "POSE_OT_constraints_clear", CKEY, KM_PRESS, KM_CTRL | KM_ALT, 0); diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c index 79d75c9fcda..cd24e94f9e9 100644 --- a/source/blender/editors/armature/armature_relations.c +++ b/source/blender/editors/armature/armature_relations.c @@ -230,7 +230,7 @@ int join_armature_exec(bContext *C, wmOperator *op) /* Copy bones and posechannels from the object to the edit armature */ for (pchan = opose->chanbase.first; pchan; pchan = pchann) { pchann = pchan->next; - curbone = editbone_name_exists(curarm->edbo, pchan->name); + curbone = ED_armature_bone_find_name(curarm->edbo, pchan->name); /* Get new name */ unique_editbone_name(arm->edbo, curbone->name, NULL); @@ -414,7 +414,7 @@ static void separate_armature_bones(Object *ob, short sel) /* go through pose-channels, checking if a bone should be removed */ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchann) { pchann = pchan->next; - curbone = editbone_name_exists(arm->edbo, pchan->name); + curbone = ED_armature_bone_find_name(arm->edbo, pchan->name); /* check if bone needs to be removed */ if ( (sel && (curbone->flag & BONE_SELECTED)) || diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index fe1d2fa3765..0bc6f1e037c 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -54,6 +54,10 @@ #include "armature_intern.h" +/* utility macros fro storing a temp int in the bone (selection flag) */ +#define EBONE_PREV_FLAG_GET(ebone) ((void)0, (GET_INT_FROM_POINTER((ebone)->temp))) +#define EBONE_PREV_FLAG_SET(ebone, val) ((ebone)->temp = SET_INT_IN_POINTER(val)) + /* **************** PoseMode & EditMode Selection Buffer Queries *************************** */ /* only for opengl selection indices */ @@ -559,39 +563,6 @@ bool mouse_armature(bContext *C, const int mval[2], bool extend, bool deselect, /* **************** Selections ******************/ -static int armature_select_inverse_exec(bContext *C, wmOperator *UNUSED(op)) -{ - /* Set the flags */ - CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) - { - /* ignore bone if selection can't change */ - if ((ebone->flag & BONE_UNSELECTABLE) == 0) { - /* select bone */ - ebone->flag ^= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - } - } - CTX_DATA_END; - - WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, NULL); - - return OPERATOR_FINISHED; -} - -void ARMATURE_OT_select_inverse(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select Inverse"; - ot->idname = "ARMATURE_OT_select_inverse"; - ot->description = "Flip the selection status of bones (selected -> unselected, unselected -> selected)"; - - /* api callbacks */ - ot->exec = armature_select_inverse_exec; - ot->poll = ED_operator_editarmature; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - -} static int armature_de_select_all_exec(bContext *C, wmOperator *op) { int action = RNA_enum_get(op->ptr, "action"); @@ -667,9 +638,6 @@ void ARMATURE_OT_select_all(wmOperatorType *ot) /**************** Select more/less **************/ -#define EBONE_PREV_FLAG_GET(ebone) ((void)0, (GET_INT_FROM_POINTER(ebone->temp))) -#define EBONE_PREV_FLAG_SET(ebone, val) (ebone->temp = SET_INT_IN_POINTER(val)) - static void armature_select_more(bArmature *arm, EditBone *ebone) { if ((EBONE_PREV_FLAG_GET(ebone) & (BONE_ROOTSEL | BONE_TIPSEL)) != 0) { @@ -753,9 +721,6 @@ static void armature_select_more_less(Object *ob, bool more) ED_armature_sync_selection(arm->edbo); } -#undef EBONE_PREV_FLAG_GET -#undef EBONE_PREV_FLAG_SET - static int armature_de_select_more_exec(bContext *C, wmOperator *UNUSED(op)) { Object *obedit = CTX_data_edit_object(C); @@ -1083,3 +1048,195 @@ void ARMATURE_OT_select_hierarchy(wmOperatorType *ot) RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection"); } +/****************** Mirror Select ****************/ + +/** + * \note clone of #pose_select_mirror_exec keep in sync + */ +static int armature_select_mirror_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + bArmature *arm = obedit->data; + EditBone *ebone, *ebone_mirror_act = NULL; + const bool active_only = RNA_boolean_get(op->ptr, "only_active"); + const bool extend = RNA_boolean_get(op->ptr, "extend"); + + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + const int flag = ED_armature_ebone_selectflag_get(ebone); + EBONE_PREV_FLAG_SET(ebone, flag); + } + + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + if (EBONE_SELECTABLE(arm, ebone)) { + EditBone *ebone_mirror; + int flag_new = extend ? EBONE_PREV_FLAG_GET(ebone) : 0; + + if ((ebone_mirror = ED_armature_bone_get_mirrored(arm->edbo, ebone)) && + (EBONE_VISIBLE(arm, ebone_mirror))) + { + const int flag_mirror = EBONE_PREV_FLAG_GET(ebone_mirror); + flag_new |= flag_mirror; + + if (ebone == arm->act_edbone) { + ebone_mirror_act = ebone_mirror; + } + + /* skip all but the active or its mirror */ + if (active_only && !ELEM(arm->act_edbone, ebone, ebone_mirror)) { + continue; + } + } + + ED_armature_ebone_selectflag_set(ebone, flag_new); + } + } + + if (ebone_mirror_act) { + arm->act_edbone = ebone_mirror_act; + } + + ED_armature_sync_selection(arm->edbo); + + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit); + + return OPERATOR_FINISHED; +} + +void ARMATURE_OT_select_mirror(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Flip Active/Selected Bone"; + ot->idname = "ARMATURE_OT_select_mirror"; + ot->description = "Mirror the bone selection"; + + /* api callbacks */ + ot->exec = armature_select_mirror_exec; + ot->poll = ED_operator_editarmature; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "only_active", false, "Active Only", "Only operate on the active bone"); + RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection"); +} + + +/****************** Select Path ****************/ + +static bool armature_shortest_path_select(bArmature *arm, EditBone *ebone_parent, EditBone *ebone_child, + bool use_parent, bool is_test) +{ + do { + + if (!use_parent && (ebone_child == ebone_parent)) + break; + + if (is_test) { + if (!EBONE_SELECTABLE(arm, ebone_child)) { + return false; + } + } + else { + ED_armature_ebone_selectflag_set(ebone_child, (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)); + } + + if (ebone_child == ebone_parent) + break; + + ebone_child = ebone_child->parent; + } while (true); + + return true; +} + +static int armature_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + Object *obedit = CTX_data_edit_object(C); + bArmature *arm = obedit->data; + EditBone *ebone_src, *ebone_dst; + EditBone *ebone_isect_parent = NULL; + EditBone *ebone_isect_child[2]; + bool change; + + view3d_operator_needs_opengl(C); + + ebone_src = arm->act_edbone; + ebone_dst = get_nearest_bone(C, 0, event->mval[0], event->mval[1]); + + /* fallback to object selection */ + if (ELEM(NULL, ebone_src, ebone_dst) || (ebone_src == ebone_dst)) { + return OPERATOR_PASS_THROUGH; + } + + ebone_isect_child[0] = ebone_src; + ebone_isect_child[1] = ebone_dst; + + + /* ensure 'ebone_src' is the parent of 'ebone_dst', or set 'ebone_isect_parent' */ + if (ED_armature_ebone_is_child_recursive(ebone_src, ebone_dst)) { + /* pass */ + } + else if (ED_armature_ebone_is_child_recursive(ebone_dst, ebone_src)) { + SWAP(EditBone *, ebone_src, ebone_dst); + } + else if ((ebone_isect_parent = ED_armature_bone_find_shared_parent(ebone_isect_child, 2))) { + /* pass */ + } + else { + /* disconnected bones */ + return OPERATOR_CANCELLED; + } + + + if (ebone_isect_parent) { + if (armature_shortest_path_select(arm, ebone_isect_parent, ebone_src, false, true) && + armature_shortest_path_select(arm, ebone_isect_parent, ebone_dst, false, true)) + { + armature_shortest_path_select(arm, ebone_isect_parent, ebone_src, false, false); + armature_shortest_path_select(arm, ebone_isect_parent, ebone_dst, false, false); + change = true; + } + else { + /* unselectable */ + change = false; + } + } + else { + if (armature_shortest_path_select(arm, ebone_src, ebone_dst, true, true)) { + armature_shortest_path_select(arm, ebone_src, ebone_dst, true, false); + change = true; + } + else { + /* unselectable */ + change = false; + } + } + + if (change) { + arm->act_edbone = ebone_dst; + ED_armature_sync_selection(arm->edbo); + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit); + + return OPERATOR_FINISHED; + } + else { + BKE_report(op->reports, RPT_WARNING, "Unselectable bone in chain"); + return OPERATOR_CANCELLED; + } +} + +void ARMATURE_OT_shortest_path_pick(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Pick Shortest Path"; + ot->idname = "ARMATURE_OT_shortest_path_pick"; + ot->description = "Select shortest path between two bones"; + + /* api callbacks */ + ot->invoke = armature_shortest_path_pick_invoke; + ot->poll = ED_operator_editarmature; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c index 0301db4b4cf..5f15d15d478 100644 --- a/source/blender/editors/armature/armature_skinning.c +++ b/source/blender/editors/armature/armature_skinning.c @@ -346,11 +346,10 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob, /* find flipped group */ if (dgroup && mirror) { - char name[MAXBONENAME]; + char name_flip[MAXBONENAME]; - // 0 = don't strip off number extensions - flip_side_name(name, dgroup->name, FALSE); - dgroupflip[j] = defgroup_find_name(ob, name); + BKE_deform_flip_side_name(name_flip, dgroup->name, false); + dgroupflip[j] = defgroup_find_name(ob, name_flip); } } diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c index 76cd12f12f8..7d6b3710a38 100644 --- a/source/blender/editors/armature/armature_utils.c +++ b/source/blender/editors/armature/armature_utils.c @@ -156,6 +156,47 @@ bool ED_armature_ebone_is_child_recursive(EditBone *ebone_parent, EditBone *ebon return false; } +/** + * Finds the first parent shared by \a ebone_child + * + * \param ebone_child Children bones to search + * \param ebone_child_tot Size of the ebone_child array + * \return The shared parent or NULL. + */ +EditBone *ED_armature_bone_find_shared_parent(EditBone *ebone_child[], const unsigned int ebone_child_tot) +{ + unsigned int i; + EditBone *ebone_iter; + +#define EBONE_TEMP_UINT(ebone) (*((unsigned int *)(&((ebone)->temp)))) + + /* clear all */ + for (i = 0; i < ebone_child_tot; i++) { + for (ebone_iter = ebone_child[i]; ebone_iter; ebone_iter = ebone_iter->parent) { + EBONE_TEMP_UINT(ebone_iter) = 0; + } + } + + /* accumulate */ + for (i = 0; i < ebone_child_tot; i++) { + ebone_iter = ebone_child[i]; + for (ebone_iter = ebone_child[i]->parent; ebone_iter; ebone_iter = ebone_iter->parent) { + EBONE_TEMP_UINT(ebone_iter) += 1; + } + } + + /* only need search the first chain */ + for (ebone_iter = ebone_child[0]->parent; ebone_iter; ebone_iter = ebone_iter->parent) { + if (EBONE_TEMP_UINT(ebone_iter) == ebone_child_tot) { + return ebone_iter; + } + } + +#undef EBONE_TEMP_UINT + + return NULL; +} + void ED_armature_ebone_to_mat3(EditBone *ebone, float mat[3][3]) { float delta[3]; @@ -175,28 +216,35 @@ void ED_armature_ebone_to_mat4(EditBone *ebone, float mat[4][4]) copy_v3_v3(mat[3], ebone->head); } +/** + * Return a pointer to the bone of the given name + */ +EditBone *ED_armature_bone_find_name(const ListBase *edbo, const char *name) +{ + return BLI_findstring(edbo, name, offsetof(EditBone, name)); +} + + /* *************************************************************** */ /* Mirroring */ -/* context: editmode armature */ -EditBone *ED_armature_bone_get_mirrored(ListBase *edbo, EditBone *ebo) +/** + * \see #BKE_pose_channel_get_mirrored (pose-mode, matching function) + */ +EditBone *ED_armature_bone_get_mirrored(const ListBase *edbo, EditBone *ebo) { - EditBone *eboflip = NULL; - char name[MAXBONENAME]; - + char name_flip[MAXBONENAME]; + if (ebo == NULL) return NULL; - flip_side_name(name, ebo->name, FALSE); + BKE_deform_flip_side_name(name_flip, ebo->name, false); - for (eboflip = edbo->first; eboflip; eboflip = eboflip->next) { - if (ebo != eboflip) { - if (!strcmp(name, eboflip->name)) - break; - } + if (!STREQ(name_flip, ebo->name)) { + return ED_armature_bone_find_name(edbo, name_flip); } - return eboflip; + return NULL; } /* ------------------------------------- */ @@ -453,8 +501,9 @@ void ED_armature_from_edit(Object *obedit) /* armature bones */ BKE_armature_bonelist_free(&arm->bonebase); + arm->act_bone = NULL; - /* remove zero sized bones, this gives instable restposes */ + /* remove zero sized bones, this gives unstable restposes */ for (eBone = arm->edbo->first; eBone; eBone = neBone) { float len = len_v3v3(eBone->head, eBone->tail); neBone = eBone->next; @@ -586,7 +635,6 @@ void ED_armature_to_edit(Object *ob) ED_armature_edit_free(ob); arm->edbo = MEM_callocN(sizeof(ListBase), "edbo armature"); arm->act_edbone = make_boneList(arm->edbo, &arm->bonebase, NULL, arm->act_bone); - arm->act_bone = NULL; // BIF_freeTemplates(); /* force template update when entering editmode */ } diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 8ae1b9557ee..36999c15665 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -2339,7 +2339,7 @@ static int sketch_convert(bContext *C, wmOperator *UNUSED(op), const wmEvent *UN return OPERATOR_FINISHED; } -static int sketch_cancel(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event)) +static int sketch_cancel_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event)) { SK_Sketch *sketch = contextSketch(C, 0); if (sketch != NULL) { @@ -2374,12 +2374,11 @@ static int sketch_select(bContext *C, wmOperator *UNUSED(op), const wmEvent *eve return OPERATOR_FINISHED; } -static int sketch_draw_stroke_cancel(bContext *C, wmOperator *op) +static void sketch_draw_stroke_cancel(bContext *C, wmOperator *op) { SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */ sk_cancelStroke(sketch); MEM_freeN(op->customdata); - return OPERATOR_CANCELLED; } static int sketch_draw_stroke(bContext *C, wmOperator *op, const wmEvent *event) @@ -2400,12 +2399,11 @@ static int sketch_draw_stroke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static int sketch_draw_gesture_cancel(bContext *C, wmOperator *op) +static void sketch_draw_gesture_cancel(bContext *C, wmOperator *op) { SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */ sk_cancelStroke(sketch); MEM_freeN(op->customdata); - return OPERATOR_CANCELLED; } static int sketch_draw_gesture(bContext *C, wmOperator *op, const wmEvent *event) @@ -2622,7 +2620,7 @@ void SKETCH_OT_cancel_stroke(wmOperatorType *ot) ot->description = "Cancel the current sketch stroke"; /* api callbacks */ - ot->invoke = sketch_cancel; + ot->invoke = sketch_cancel_invoke; ot->poll = ED_operator_sketch_mode_active_stroke; diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c index 31ff1e161e8..d1c096e6cf5 100644 --- a/source/blender/editors/armature/pose_edit.c +++ b/source/blender/editors/armature/pose_edit.c @@ -577,9 +577,9 @@ static int pose_flip_names_exec(bContext *C, wmOperator *UNUSED(op)) /* loop through selected bones, auto-naming them */ CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones) { - char newname[MAXBONENAME]; - flip_side_name(newname, pchan->name, TRUE); - ED_armature_bone_rename(arm, pchan->name, newname); + char name_flip[MAXBONENAME]; + BKE_deform_flip_side_name(name_flip, pchan->name, true); + ED_armature_bone_rename(arm, pchan->name, name_flip); } CTX_DATA_END; diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c index 182f94b3693..69ee794e1d9 100644 --- a/source/blender/editors/armature/pose_lib.c +++ b/source/blender/editors/armature/pose_lib.c @@ -567,7 +567,7 @@ static int poselib_remove_exec(bContext *C, wmOperator *op) if (fcu->bezt) { for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) { /* check if remove */ - if (IS_EQ(bezt->vec[1][0], marker->frame)) { + if (IS_EQF(bezt->vec[1][0], (float)marker->frame)) { delete_fcurve_key(fcu, i, 1); break; } @@ -1532,10 +1532,9 @@ static int poselib_preview_exit(bContext *C, wmOperator *op) } /* Cancel previewing operation (called when exiting Blender) */ -static int poselib_preview_cancel(bContext *C, wmOperator *op) +static void poselib_preview_cancel(bContext *C, wmOperator *op) { poselib_preview_exit(C, op); - return OPERATOR_CANCELLED; } /* main modal status check */ diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c index 9449b5a49bf..765437f3622 100644 --- a/source/blender/editors/armature/pose_select.c +++ b/source/blender/editors/armature/pose_select.c @@ -62,8 +62,51 @@ #include "armature_intern.h" +/* utility macros fro storing a temp int in the bone (selection flag) */ +#define PBONE_PREV_FLAG_GET(pchan) ((void)0, (GET_INT_FROM_POINTER((pchan)->temp))) +#define PBONE_PREV_FLAG_SET(pchan, val) ((pchan)->temp = SET_INT_IN_POINTER(val)) + + /* ***************** Pose Select Utilities ********************* */ +/* Utility method for changing the selection status of a bone */ +void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select) +{ + bArmature *arm; + + /* sanity checks */ + // XXX: actually, we can probably still get away with no object - at most we have no updates + if (ELEM4(NULL, ob, ob->pose, pchan, pchan->bone)) + return; + + arm = ob->data; + + /* can only change selection state if bone can be modified */ + if (PBONE_SELECTABLE(arm, pchan->bone)) { + /* change selection state - activate too if selected */ + if (select) { + pchan->bone->flag |= BONE_SELECTED; + arm->act_bone = pchan->bone; + } + else { + pchan->bone->flag &= ~BONE_SELECTED; + arm->act_bone = NULL; + } + + // TODO: select and activate corresponding vgroup? + + /* tag necessary depsgraph updates + * (see rna_Bone_select_update() in rna_armature.c for details) + */ + if (arm->flag & ARM_HAS_VIZ_DEPS) { + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + } + + /* send necessary notifiers */ + WM_main_add_notifier(NC_GEOM | ND_DATA, ob); + } +} + /* called from editview.c, for mode-less pose selection */ /* assumes scene obact and basact is still on old situation */ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, @@ -86,9 +129,16 @@ 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 ((ob_act == NULL) || ((ob_act != ob) && (ob_act->mode & OB_MODE_WEIGHT_PAINT) == 0)) { + /* when we are entering into posemode via toggle-select, + * frop another active object - always select the bone. */ + if (!extend && !deselect && toggle) { + /* re-select below */ + nearBone->flag &= ~BONE_SELECTED; + } + } + + if (!extend && !deselect && !toggle) { ED_pose_deselectall(ob, 0); nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); arm->act_bone = nearBone; @@ -799,55 +849,85 @@ void POSE_OT_select_grouped(wmOperatorType *ot) /* -------------------------------------- */ -/* context active object, or weightpainted object with armature in posemode */ -static int pose_bone_flip_active_exec(bContext *C, wmOperator *UNUSED(op)) +/** + * \note clone of #armature_select_mirror_exec keep in sync + */ +static int pose_select_mirror_exec(bContext *C, wmOperator *op) { Object *ob_act = CTX_data_active_object(C); Object *ob = BKE_object_pose_armature_get(ob_act); - - if (ob && (ob->mode & OB_MODE_POSE)) { - bArmature *arm = ob->data; - - if (arm->act_bone) { - bPoseChannel *pchanf; - char name[MAXBONENAME]; - flip_side_name(name, arm->act_bone->name, TRUE); - - pchanf = BKE_pose_channel_find_name(ob->pose, name); - if (pchanf && pchanf->bone != arm->act_bone) { - arm->act_bone->flag &= ~BONE_SELECTED; - pchanf->bone->flag |= BONE_SELECTED; - - arm->act_bone = pchanf->bone; - - /* in weightpaint we select the associated vertex group too */ - if (ob_act->mode & OB_MODE_WEIGHT_PAINT) { - ED_vgroup_select_by_name(ob_act, name); - DAG_id_tag_update(&ob_act->id, OB_RECALC_DATA); + bArmature *arm; + bPoseChannel *pchan, *pchan_mirror_act = NULL; + const bool active_only = RNA_boolean_get(op->ptr, "only_active"); + const bool extend = RNA_boolean_get(op->ptr, "extend"); + + if ((ob && (ob->mode & OB_MODE_POSE)) == 0) { + return OPERATOR_CANCELLED; + } + + arm = ob->data; + + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + const int flag = (pchan->bone->flag & BONE_SELECTED); + PBONE_PREV_FLAG_SET(pchan, flag); + } + + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + if (PBONE_SELECTABLE(arm, pchan->bone)) { + bPoseChannel *pchan_mirror; + int flag_new = extend ? PBONE_PREV_FLAG_GET(pchan) : 0; + + if ((pchan_mirror = BKE_pose_channel_get_mirrored(ob->pose, pchan->name)) && + (PBONE_VISIBLE(arm, pchan_mirror->bone))) + { + const int flag_mirror = PBONE_PREV_FLAG_GET(pchan_mirror); + flag_new |= flag_mirror; + + if (pchan->bone == arm->act_bone) { + pchan_mirror_act = pchan_mirror; + } + + /* skip all but the active or its mirror */ + if (active_only && !ELEM(arm->act_bone, pchan->bone, pchan_mirror->bone)) { + continue; } - - WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob); - - return OPERATOR_FINISHED; } + + pchan->bone->flag = (pchan->bone->flag & ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)) | flag_new; } } - - return OPERATOR_CANCELLED; + + if (pchan_mirror_act) { + arm->act_bone = pchan_mirror_act->bone; + + /* in weightpaint we select the associated vertex group too */ + if (ob_act->mode & OB_MODE_WEIGHT_PAINT) { + ED_vgroup_select_by_name(ob_act, pchan_mirror_act->name); + DAG_id_tag_update(&ob_act->id, OB_RECALC_DATA); + } + } + + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob); + + return OPERATOR_FINISHED; } -void POSE_OT_select_flip_active(wmOperatorType *ot) +void POSE_OT_select_mirror(wmOperatorType *ot) { /* identifiers */ - ot->name = "Flip Selected Active Bone"; - ot->idname = "POSE_OT_select_flip_active"; - ot->description = "Activate the bone with a flipped name"; + ot->name = "Flip Active/Selected Bone"; + ot->idname = "POSE_OT_select_mirror"; + ot->description = "Mirror the bone selection"; /* api callbacks */ - ot->exec = pose_bone_flip_active_exec; + ot->exec = pose_select_mirror_exec; ot->poll = ED_operator_posemode; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "only_active", false, "Active Only", "Only operate on the active bone"); + RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection"); } diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c index d0e1b15064a..82652702fe7 100644 --- a/source/blender/editors/armature/pose_slide.c +++ b/source/blender/editors/armature/pose_slide.c @@ -682,11 +682,10 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event) } /* common code for cancel() */ -static int pose_slide_cancel(bContext *UNUSED(C), wmOperator *op) +static void pose_slide_cancel(bContext *UNUSED(C), wmOperator *op) { /* cleanup and done */ pose_slide_exit(op); - return OPERATOR_CANCELLED; } /* common code for exec() methods */ diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c index 79ca70a6189..578f048cb15 100644 --- a/source/blender/editors/armature/pose_transform.c +++ b/source/blender/editors/armature/pose_transform.c @@ -118,7 +118,7 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op) pose = ob->pose; for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { - curbone = editbone_name_exists(arm->edbo, pchan->name); + curbone = ED_armature_bone_find_name(arm->edbo, pchan->name); /* simply copy the head/tail values from pchan over to curbone */ copy_v3_v3(curbone->head, pchan->pose_head); @@ -302,7 +302,7 @@ static bPoseChannel *pose_bone_do_paste(Object *ob, bPoseChannel *chan, short se /* get the name - if flipping, we must flip this first */ if (flip) - flip_side_name(name, chan->name, 0); /* 0 = don't strip off number extensions */ + BKE_deform_flip_side_name(name, chan->name, false); else BLI_strncpy(name, chan->name, sizeof(name)); diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 2dc32f711b4..f576440fe92 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -111,7 +111,7 @@ typedef enum eCurveElem_Types { void selectend_nurb(Object *obedit, enum eEndPoint_Types selfirst, bool doswap, bool selstatus); static void select_adjacent_cp(ListBase *editnurb, short next, const bool cont, const bool selstatus); static void adduplicateflagNurb(Object *obedit, ListBase *newnurb, const short flag, const bool split); -static int curve_delete_selected(Object *obedit, const eCurveElem_Types type, const bool split); +static int curve_delete_segments(Object *obedit, const bool split); ListBase *object_editcurve_get(Object *ob) { @@ -1279,6 +1279,8 @@ void CU_deselect_all(Object *obedit) if (editnurb) { Nurb *nu; int a; + ((Curve *)obedit->data)->lastsel = NULL; + for (nu = editnurb->first; nu; nu = nu->next) { if (nu->bezt) { BezTriple *bezt; @@ -1373,16 +1375,15 @@ static int separate_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Nurb *nu, *nu1; Object *oldob, *newob; Base *oldbase, *newbase; Curve *oldcu, *newcu; - EditNurb *oldedit, *newedit; + EditNurb *newedit; + ListBase newnurb = {NULL, NULL}; oldbase = CTX_data_active_base(C); oldob = oldbase->object; oldcu = oldob->data; - oldedit = oldcu->editnurb; if (oldcu->key) { BKE_report(op->reports, RPT_ERROR, "Cannot separate a curve with vertex keys"); @@ -1390,44 +1391,43 @@ static int separate_exec(bContext *C, wmOperator *op) } WM_cursor_wait(1); - - /* 1. duplicate the object and data */ + + /* 1. duplicate geometry and check for valid selection for separate */ + adduplicateflagNurb(oldob, &newnurb, SELECT, true); + + if (newnurb.first == NULL) { + WM_cursor_wait(0); + BKE_report(op->reports, RPT_ERROR, "Cannot separate current selection"); + return OPERATOR_CANCELLED; + } + + /* 2. duplicate the object and data */ newbase = ED_object_add_duplicate(bmain, scene, oldbase, 0); /* 0 = fully linked */ DAG_relations_tag_update(bmain); - ED_base_object_select(newbase, BA_DESELECT); newob = newbase->object; - newcu = newob->data = BKE_curve_copy(oldcu); newcu->editnurb = NULL; oldcu->id.us--; /* because new curve is a copy: reduce user count */ - /* 2. put new object in editmode and clear it */ + /* 3. put new object in editmode, clear it and set separated nurbs */ make_editNurb(newob); newedit = newcu->editnurb; BKE_nurbList_free(&newedit->nurbs); BKE_curve_editNurb_keyIndex_free(newedit); newedit->keyindex = NULL; + BLI_movelisttolist(&newedit->nurbs, &newnurb); - /* 3. move over parts from old object */ - for (nu = oldedit->nurbs.first; nu; nu = nu1) { - nu1 = nu->next; - - if (isNurbsel(nu)) { - keyIndex_delNurb(oldedit, nu); - BLI_remlink(&oldedit->nurbs, nu); - BLI_addtail(&newedit->nurbs, nu); - } - } - - /* 4. put old object out of editmode */ + /* 4. put old object out of editmode and delete separated geometry */ load_editNurb(newob); free_editNurb(newob); + curve_delete_segments(oldob, true); DAG_id_tag_update(&oldob->id, OB_RECALC_DATA); /* this is the original one */ DAG_id_tag_update(&newob->id, OB_RECALC_DATA); /* this is the separated one */ WM_event_add_notifier(C, NC_GEOM | ND_DATA, oldob->data); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, newob); WM_cursor_wait(0); @@ -1439,7 +1439,7 @@ void CURVE_OT_separate(wmOperatorType *ot) /* identifiers */ ot->name = "Separate"; ot->idname = "CURVE_OT_separate"; - ot->description = "Separate (partly) selected curves or surfaces into a new object"; + ot->description = "Separate selected points from connected unselected points into a new object"; /* api callbacks */ ot->exec = separate_exec; @@ -1460,7 +1460,7 @@ static int curve_split_exec(bContext *C, wmOperator *op) adduplicateflagNurb(obedit, &newnurb, SELECT, true); if (newnurb.first != NULL) { - curve_delete_selected(obedit, CURVE_SEGMENT, true); + curve_delete_segments(obedit, true); BLI_movelisttolist(editnurb, &newnurb); if (ED_curve_updateAnimPaths(obedit->data)) @@ -1486,7 +1486,7 @@ void CURVE_OT_split(wmOperatorType *ot) /* api callbacks */ ot->exec = curve_split_exec; - ot->poll = ED_operator_editcurve; + ot->poll = ED_operator_editsurfcurve; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1539,6 +1539,57 @@ static short isNurbselUV(Nurb *nu, int *u, int *v, int flag) return 0; } +/* return true if U direction is selected and number of selected columns v */ +static bool isNurbselU(Nurb *nu, int *v, int flag) +{ + BPoint *bp; + int a, b, sel; + + *v = 0; + + for (b = 0, bp = nu->bp; b < nu->pntsv; b++) { + sel = 0; + for (a = 0; a < nu->pntsu; a++, bp++) { + if (bp->f1 & flag) sel++; + } + if (sel == nu->pntsu) { + (*v)++; + } + else if (sel >= 1) { + *v = 0; + return 0; + } + } + + return 1; +} + +/* return true if V direction is selected and number of selected rows u */ +static bool isNurbselV(Nurb *nu, int *u, int flag) +{ + BPoint *bp; + int a, b, sel; + + *u = 0; + + for (a = 0; a < nu->pntsu; a++) { + bp = &nu->bp[a]; + sel = 0; + for (b = 0; b < nu->pntsv; b++, bp += nu->pntsu) { + if (bp->f1 & flag) sel++; + } + if (sel == nu->pntsv) { + (*u)++; + } + else if (sel >= 1) { + *u = 0; + return 0; + } + } + + return 1; +} + static void rotateflagNurb(ListBase *editnurb, short flag, const float cent[3], float rotmat[3][3]) { /* all verts with (flag & 'flag') rotate */ @@ -1622,7 +1673,7 @@ static int deleteflagNurb(Object *obedit, short flag) ListBase *editnurb = object_editcurve_get(obedit); Nurb *nu, *next; BPoint *bp, *bpn, *newbp; - int a, b, newu, newv, sel; + int a, b, newu, newv; if (obedit->type != OB_SURF) { return OPERATOR_CANCELLED; @@ -1653,62 +1704,36 @@ static int deleteflagNurb(Object *obedit, short flag) BKE_nurb_free(nu); nu = NULL; } else { - /* is nurb in U direction selected */ - newv = nu->pntsv; - bp = nu->bp; - for (b = 0; b < nu->pntsv; b++) { - sel = 0; - for (a = 0; a < nu->pntsu; a++, bp++) { - if (bp->f1 & flag) sel++; - } - if (sel == nu->pntsu) { - newv--; - } - else if (sel >= 1) { - /* don't delete */ - break; - } - } - if (newv != nu->pntsv && b == nu->pntsv) { - /* delete */ - bp = nu->bp; - bpn = newbp = (BPoint *)MEM_mallocN(newv * nu->pntsu * sizeof(BPoint), "deleteNurb"); - for (b = 0; b < nu->pntsv; b++) { - if ((bp->f1 & flag) == 0) { - memcpy(bpn, bp, nu->pntsu * sizeof(BPoint)); - keyIndex_updateBP(cu->editnurb, bp, bpn, nu->pntsu); - bpn += nu->pntsu; - } - else { - keyIndex_delBP(cu->editnurb, bp); + if (isNurbselU(nu, &newv, flag)) { + /* U direction selected */ + newv = nu->pntsv - newv; + if (newv != nu->pntsv) { + /* delete */ + bp = nu->bp; + bpn = newbp = (BPoint *)MEM_mallocN(newv * nu->pntsu * sizeof(BPoint), "deleteNurb"); + for (b = 0; b < nu->pntsv; b++) { + if ((bp->f1 & flag) == 0) { + memcpy(bpn, bp, nu->pntsu * sizeof(BPoint)); + keyIndex_updateBP(cu->editnurb, bp, bpn, nu->pntsu); + bpn += nu->pntsu; + } + else { + keyIndex_delBP(cu->editnurb, bp); + } + bp += nu->pntsu; } - bp += nu->pntsu; - } - nu->pntsv = newv; - MEM_freeN(nu->bp); - nu->bp = newbp; - BKE_nurb_order_clamp_v(nu); + nu->pntsv = newv; + MEM_freeN(nu->bp); + nu->bp = newbp; + BKE_nurb_order_clamp_v(nu); - BKE_nurb_knot_calc_v(nu); - } - else { - /* is the nurb in V direction selected */ - newu = nu->pntsu; - for (a = 0; a < nu->pntsu; a++) { - bp = &nu->bp[a]; - sel = 0; - for (b = 0; b < nu->pntsv; b++, bp += nu->pntsu) { - if (bp->f1 & flag) sel++; - } - if (sel == nu->pntsv) { - newu--; - } - else if (sel >= 1) { - /* don't delete */ - break; - } + BKE_nurb_knot_calc_v(nu); } - if (newu != nu->pntsu && a == nu->pntsu) { + } + else if (isNurbselV(nu, &newu, flag)) { + /* V direction selected */ + newu = nu->pntsu - newu; + if (newu != nu->pntsu) { /* delete */ bp = nu->bp; bpn = newbp = (BPoint *)MEM_mallocN(newu * nu->pntsv * sizeof(BPoint), "deleteNurb"); @@ -1872,21 +1897,17 @@ static void adduplicateflagNurb(Object *obedit, ListBase *newnurb, const short flag, const bool split) { ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu, *newnu, *startnu; + Nurb *nu = editnurb->last, *newnu; BezTriple *bezt, *bezt1; - BPoint *bp, *bp1; + BPoint *bp, *bp1, *bp2, *bp3; Curve *cu = (Curve *)obedit->data; - int a, b, starta, enda, diffa, newu, newv; + int a, b, c, starta, enda, diffa, cyclicu, cyclicv, newu, newv; char *usel; - cu->lastsel = NULL; - - nu = editnurb->last; while (nu) { - startnu = NULL; + cyclicu = cyclicv = 0; if (nu->type == CU_BEZIER) { - bezt = nu->bezt; - for (a = 0; a < nu->pntsu; a++) { + for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) { enda = -1; starta = a; while ((bezt->f1 & flag) || (bezt->f2 & flag) || (bezt->f3 & flag)) { @@ -1897,46 +1918,44 @@ static void adduplicateflagNurb(Object *obedit, ListBase *newnurb, bezt++; } if (enda >= starta) { - diffa = enda - starta + 1; - - if (startnu != NULL && enda == nu->pntsu - 1) { - /* end point of cyclic spline selected, so merge end points with start points */ - bezt1 = (BezTriple *)MEM_mallocN((startnu->pntsu + diffa) * sizeof(BezTriple), "adduplicateN"); - memcpy(bezt1, &nu->bezt[starta], diffa * sizeof(BezTriple)); - memcpy(&bezt1[diffa], startnu->bezt, startnu->pntsu * sizeof(BezTriple)); - - MEM_freeN(startnu->bezt); - startnu->bezt = bezt1; - startnu->pntsu += diffa; - newnu = startnu; + newu = diffa = enda - starta + 1; /* set newu and diffa, may use both */ + + if (starta == 0 && newu != nu->pntsu && (nu->flagu & CU_NURB_CYCLIC)) { + cyclicu = newu; } else { - newnu = ED_curve_nurbcpy(nu, diffa); + if (enda == nu->pntsu - 1) newu += cyclicu; + + newnu = BKE_nurb_copy(nu, newu, 1); BLI_addtail(newnurb, newnu); - set_actNurb(obedit, newnu); - memcpy(newnu->bezt, &nu->bezt[starta], newnu->pntsu * sizeof(BezTriple)); - } + memcpy(newnu->bezt, &nu->bezt[starta], diffa * sizeof(BezTriple)); + if (newu != diffa) { + memcpy(&newnu->bezt[diffa], nu->bezt, cyclicu * sizeof(BezTriple)); + cyclicu = 0; + } - b = newnu->pntsu; - bezt1 = newnu->bezt; - while (b--) { - select_beztriple(bezt1, SELECT, flag, HIDDEN); - bezt1++; - } + if (newu != nu->pntsu) newnu->flagu &= ~CU_NURB_CYCLIC; - if (nu->flagu & CU_NURB_CYCLIC) { - if (starta != 0 || enda != nu->pntsu - 1) { - newnu->flagu &= ~CU_NURB_CYCLIC; - if (starta == 0) startnu = newnu; + for (b = 0, bezt1 = newnu->bezt; b < newnu->pntsu; b++, bezt1++) { + select_beztriple(bezt1, SELECT, flag, HIDDEN); } } } - bezt++; + } + + if (cyclicu != 0) { + newnu = BKE_nurb_copy(nu, cyclicu, 1); + BLI_addtail(newnurb, newnu); + memcpy(newnu->bezt, nu->bezt, cyclicu * sizeof(BezTriple)); + newnu->flagu &= ~CU_NURB_CYCLIC; + + for (b = 0, bezt1 = newnu->bezt; b < newnu->pntsu; b++, bezt1++) { + select_beztriple(bezt1, SELECT, flag, HIDDEN); + } } } else if (nu->pntsv == 1) { /* because UV Nurb has a different method for dupli */ - bp = nu->bp; - for (a = 0; a < nu->pntsu; a++) { + for (a = 0, bp = nu->bp; a < nu->pntsu; a++, bp++) { enda = -1; starta = a; while (bp->f1 & flag) { @@ -1947,46 +1966,45 @@ static void adduplicateflagNurb(Object *obedit, ListBase *newnurb, bp++; } if (enda >= starta) { - diffa = enda - starta + 1; - - if (startnu != NULL && enda == nu->pntsu - 1) { - /* end point of cyclic spline selected, so merge end points with start points */ - bp1 = (BPoint *)MEM_mallocN((startnu->pntsu + diffa) * sizeof(BPoint), "adduplicateN2"); - memcpy(bp1, &nu->bp[starta], diffa * sizeof(BPoint)); - memcpy(&bp1[diffa], startnu->bp, startnu->pntsu * sizeof(BPoint)); - - MEM_freeN(startnu->bp); - startnu->bp = bp1; - startnu->pntsu += diffa; - newnu = startnu; + newu = diffa = enda - starta + 1; /* set newu and diffa, may use both */ + + if (starta == 0 && newu != nu->pntsu && (nu->flagu & CU_NURB_CYCLIC)) { + cyclicu = newu; } else { - newnu = ED_curve_nurbcpy(nu, diffa); + if (enda == nu->pntsu - 1) newu += cyclicu; + + newnu = BKE_nurb_copy(nu, newu, 1); BLI_addtail(newnurb, newnu); - set_actNurb(obedit, newnu); - memcpy(newnu->bp, &nu->bp[starta], newnu->pntsu * sizeof(BPoint)); - } + memcpy(newnu->bp, &nu->bp[starta], diffa * sizeof(BPoint)); + if (newu != diffa) { + memcpy(&newnu->bp[diffa], nu->bp, cyclicu * sizeof(BPoint)); + cyclicu = 0; + } - b = newnu->pntsu; - bp1 = newnu->bp; - while (b--) { - select_bpoint(bp1, SELECT, flag, HIDDEN); - bp1++; - } + if (newu != nu->pntsu) newnu->flagu &= ~CU_NURB_CYCLIC; - if (nu->flagu & CU_NURB_CYCLIC) { - if (starta != 0 || enda != nu->pntsu - 1) { - newnu->flagu &= ~CU_NURB_CYCLIC; - if (starta == 0) startnu = newnu; + for (b = 0, bp1 = newnu->bp; b < newnu->pntsu; b++, bp1++) { + select_bpoint(bp1, SELECT, flag, HIDDEN); } } } - bp++; + } + + if (cyclicu != 0) { + newnu = BKE_nurb_copy(nu, cyclicu, 1); + BLI_addtail(newnurb, newnu); + memcpy(newnu->bp, nu->bp, cyclicu * sizeof(BPoint)); + newnu->flagu &= ~CU_NURB_CYCLIC; + + for (b = 0, bp1 = newnu->bp; b < newnu->pntsu; b++, bp1++) { + select_bpoint(bp1, SELECT, flag, HIDDEN); + } } } else { - /* a rectangular area in nurb has to be selected */ if (isNurbsel(nu)) { + /* a rectangular area in nurb has to be selected and if splitting must be in U or V direction */ usel = MEM_callocN(nu->pntsu, "adduplicateN3"); bp = nu->bp; for (a = 0; a < nu->pntsv; a++) { @@ -2008,78 +2026,131 @@ static void adduplicateflagNurb(Object *obedit, ListBase *newnurb, } } } - if (newu == 0 || newv == 0) { + MEM_freeN(usel); + + if ((newu == 0 || newv == 0) || + (split && !isNurbselU(nu, &newv, SELECT) && !isNurbselV(nu, &newu, SELECT))) + { if (G.debug & G_DEBUG) printf("Can't duplicate Nurb\n"); } else { + for (a = 0, bp1 = nu->bp; a < nu->pntsu * nu->pntsv; a++, bp1++) { + newv = newu = 0; + + if ((bp1->f1 & flag) && !(bp1->f1 & SURF_SEEN)) { + /* point selected, now loop over points in U and V directions */ + for (b = a % nu->pntsu, bp2 = bp1; b < nu->pntsu; b++, bp2++) { + if (bp2->f1 & flag) { + newu++; + for (c = a / nu->pntsu, bp3 = bp2; c < nu->pntsv; c++, bp3 += nu->pntsu) { + if (bp3->f1 & flag) { + bp3->f1 |= SURF_SEEN; /* flag as seen so skipped on future iterations */ + if (newu == 1) newv++; + } + else { + break; + } + } + } + else { + break; + } + } + } - if (newu == 1) SWAP(int, newu, newv); + if ((newu + newv) > 2) { + /* ignore single points */ + if (a == 0) { + /* check if need to save cyclic selection and continue if so */ + if (newu == nu->pntsu && (nu->flagv & CU_NURB_CYCLIC)) cyclicv = newv; + if (newv == nu->pntsv && (nu->flagu & CU_NURB_CYCLIC)) cyclicu = newu; + if (cyclicu != 0 || cyclicv != 0) continue; + } - newnu = (Nurb *)MEM_mallocN(sizeof(Nurb), "adduplicateN4"); - memcpy(newnu, nu, sizeof(Nurb)); - BLI_addtail(newnurb, newnu); - set_actNurb(obedit, newnu); - newnu->pntsu = newu; - newnu->pntsv = newv; - newnu->bp = (BPoint *)MEM_mallocN(newu * newv * sizeof(BPoint), "adduplicateN5"); - BKE_nurb_order_clamp_u(newnu); - BKE_nurb_order_clamp_v(newnu); - - newnu->knotsu = newnu->knotsv = NULL; - - bp = newnu->bp; - bp1 = nu->bp; - for (a = 0; a < nu->pntsv; a++) { - for (b = 0; b < nu->pntsu; b++, bp1++) { - if (bp1->f1 & flag) { - memcpy(bp, bp1, sizeof(BPoint)); - select_bpoint(bp1, DESELECT, flag, HIDDEN); - bp++; + if (a + newu == nu->pntsu && cyclicu != 0) { + /* cyclic in U direction */ + newnu = BKE_nurb_copy(nu, newu + cyclicu, newv); + for (b = 0; b < newv; b++) { + memcpy(&newnu->bp[b * newnu->pntsu], &nu->bp[b * nu->pntsu + a], newu * sizeof(BPoint)); + memcpy(&newnu->bp[b * newnu->pntsu + newu], &nu->bp[b * nu->pntsu], cyclicu * sizeof(BPoint)); + } + cyclicu = cyclicv = 0; + } + else if ((a / nu->pntsu) + newv == nu->pntsv && cyclicv != 0) { + /* cyclic in V direction */ + newnu = BKE_nurb_copy(nu, newu, newv + cyclicv); + memcpy(newnu->bp, &nu->bp[a], newu * newv * sizeof(BPoint)); + memcpy(&newnu->bp[newu * newv], nu->bp, newu * cyclicv * sizeof(BPoint)); + cyclicu = cyclicv = 0; } + else { + newnu = BKE_nurb_copy(nu, newu, newv); + for (b = 0; b < newv; b++) { + memcpy(&newnu->bp[b * newu], &nu->bp[b * nu->pntsu + a], newu * sizeof(BPoint)); + } + } + BLI_addtail(newnurb, newnu); + + if (newu != nu->pntsu) newnu->flagu &= ~CU_NURB_CYCLIC; + if (newv != nu->pntsv) newnu->flagv &= ~CU_NURB_CYCLIC; } } - if (BKE_nurb_check_valid_u(newnu)) { - if (nu->pntsu == newnu->pntsu && nu->knotsu) { - newnu->knotsu = MEM_dupallocN(nu->knotsu); - } - else { - BKE_nurb_knot_calc_u(newnu); + + if (cyclicu != 0 || cyclicv != 0) { + /* copy start of a cyclic surface, or copying all selected points */ + newu = cyclicu == 0 ? nu->pntsu : cyclicu; + newv = cyclicv == 0 ? nu->pntsv : cyclicv; + + newnu = BKE_nurb_copy(nu, newu, newv); + for (b = 0; b < newv; b++) { + memcpy(&newnu->bp[b * newu], &nu->bp[b * nu->pntsu], newu * sizeof(BPoint)); } + BLI_addtail(newnurb, newnu); + + if (newu != nu->pntsu) newnu->flagu &= ~CU_NURB_CYCLIC; + if (newv != nu->pntsv) newnu->flagv &= ~CU_NURB_CYCLIC; } - if (BKE_nurb_check_valid_v(newnu)) { - if (nu->pntsv == newnu->pntsv && nu->knotsv) { - newnu->knotsv = MEM_dupallocN(nu->knotsv); - } - else { - BKE_nurb_knot_calc_v(newnu); - } + + for (b = 0, bp1 = nu->bp; b < nu->pntsu * nu->pntsv; b++, bp1++) { + bp1->f1 &= ~SURF_SEEN; + if (!split) select_bpoint(bp1, DESELECT, flag, HIDDEN); } } - MEM_freeN(usel); } } - nu = nu->prev; } - - for (nu = newnurb->first; nu; nu = nu->next) { - /* knots done after duplicate as pntsu may change */ - if (nu->pntsv == 1) { - nu->knotsu = NULL; - BKE_nurb_knot_calc_u(nu); - } - if (split) { + if (newnurb->first != NULL) { + cu->lastsel = NULL; + cu->actnu = -1; + + for (nu = newnurb->first; nu; nu = nu->next) { if (nu->type == CU_BEZIER) { - /* recalc first and last */ - BKE_nurb_handle_calc_simple(nu, &nu->bezt[0]); - BKE_nurb_handle_calc_simple(nu, &nu->bezt[nu->pntsu - 1]); + if (split) { + /* recalc first and last */ + BKE_nurb_handle_calc_simple(nu, &nu->bezt[0]); + BKE_nurb_handle_calc_simple(nu, &nu->bezt[nu->pntsu - 1]); + } + } + else { + /* knots done after duplicate as pntsu may change */ + nu->knotsu = nu->knotsv = NULL; + BKE_nurb_order_clamp_u(nu); + BKE_nurb_knot_calc_u(nu); + + if (obedit->type == OB_SURF) { + for (a = 0, bp = nu->bp; a < nu->pntsu * nu->pntsv; a++, bp++) { + bp->f1 &= ~SURF_SEEN; + } + + BKE_nurb_order_clamp_v(nu); + BKE_nurb_knot_calc_v(nu); + } } } } - - /* actnu changed */ } /**************** switch direction operator ***************/ @@ -4412,7 +4483,7 @@ static int spin_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event) if (rv3d) copy_v3_v3(axis, rv3d->viewinv[2]); - RNA_float_set_array(op->ptr, "center", give_cursor(scene, v3d)); + RNA_float_set_array(op->ptr, "center", ED_view3d_cursor3d_get(scene, v3d)); RNA_float_set_array(op->ptr, "axis", axis); return spin_exec(C, op); @@ -4748,7 +4819,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event) mul_v3_m4v3(location, vc.obedit->obmat, bp->vec); } else { - copy_v3_v3(location, give_cursor(vc.scene, vc.v3d)); + copy_v3_v3(location, ED_view3d_cursor3d_get(vc.scene, vc.v3d)); } ED_view3d_win_to_3d_int(vc.ar, location, event->mval, location); @@ -5708,7 +5779,7 @@ void CURVE_OT_select_nth(wmOperatorType *ot) /********************** add duplicate operator *********************/ -static int duplicate_exec(bContext *C, wmOperator *UNUSED(op)) +static int duplicate_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); ListBase newnurb = {NULL, NULL}; @@ -5719,6 +5790,10 @@ static int duplicate_exec(bContext *C, wmOperator *UNUSED(op)) BLI_movelisttolist(object_editcurve_get(obedit), &newnurb); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); } + else { + BKE_report(op->reports, RPT_ERROR, "Cannot duplicate current selection"); + return OPERATOR_CANCELLED; + } return OPERATOR_FINISHED; } @@ -5727,7 +5802,7 @@ void CURVE_OT_duplicate(wmOperatorType *ot) { /* identifiers */ ot->name = "Duplicate Curve"; - ot->description = "Duplicate selected control points and segments between them"; + ot->description = "Duplicate selected control points"; ot->idname = "CURVE_OT_duplicate"; /* api callbacks */ @@ -5740,178 +5815,296 @@ void CURVE_OT_duplicate(wmOperatorType *ot) /********************** delete operator *********************/ -static int curve_delete_selected(Object *obedit, eCurveElem_Types type, const bool split) +static int curve_delete_vertices(Object *obedit) { Curve *cu = obedit->data; EditNurb *editnurb = cu->editnurb; ListBase *nubase = &editnurb->nurbs; - Nurb *nu, *nu1, *startnu; - BezTriple *bezt, *bezt1, *bezt2; - BPoint *bp, *bp1, *bp2; - int a, b, starta, enda, cut = 0; - int nuindex = 0; - ListBase newnurb = {NULL, NULL}; + Nurb *nu, *next; + BezTriple *bezt, *bezt1; + BPoint *bp, *bp1; + int a, type, nuindex = 0; if (obedit->type == OB_SURF) { - if (type == CURVE_VERTEX) { - return deleteflagNurb(obedit, SELECT); - } - else { - keyIndex_delNurbList(editnurb, nubase); - BKE_nurbList_free(nubase); - - return OPERATOR_FINISHED; - } + return deleteflagNurb(obedit, SELECT); } - if (type == CURVE_VERTEX) { - /* first loop, can we remove entire pieces? */ - Nurb *next; - nu = nubase->first; - while (nu) { - next = nu->next; - if (nu->type == CU_BEZIER) { - bezt = nu->bezt; - a = nu->pntsu; - if (a) { - while (a) { - if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) { - /* pass */ - } - else { - break; - } - a--; - bezt++; + /* first loop, can we remove entire pieces? */ + nu = nubase->first; + while (nu) { + next = nu->next; + if (nu->type == CU_BEZIER) { + bezt = nu->bezt; + a = nu->pntsu; + if (a) { + while (a) { + if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) { + /* pass */ } - if (a == 0) { - if (cu->actnu == nuindex) - cu->actnu = -1; - - BLI_remlink(nubase, nu); - keyIndex_delNurb(editnurb, nu); - BKE_nurb_free(nu); nu = NULL; + else { + break; } + a--; + bezt++; + } + if (a == 0) { + if (cu->actnu == nuindex) + cu->actnu = -1; + + BLI_remlink(nubase, nu); + keyIndex_delNurb(editnurb, nu); + BKE_nurb_free(nu); nu = NULL; } } - else { - bp = nu->bp; - a = nu->pntsu * nu->pntsv; - if (a) { - while (a) { - if (bp->f1 & SELECT) { - /* pass */ - } - else { - break; - } - a--; - bp++; + } + else { + bp = nu->bp; + a = nu->pntsu * nu->pntsv; + if (a) { + while (a) { + if (bp->f1 & SELECT) { + /* pass */ } - if (a == 0) { - if (cu->actnu == nuindex) - cu->actnu = -1; - - BLI_remlink(nubase, nu); - keyIndex_delNurb(editnurb, nu); - BKE_nurb_free(nu); nu = NULL; + else { + break; } + a--; + bp++; + } + if (a == 0) { + if (cu->actnu == nuindex) + cu->actnu = -1; + + BLI_remlink(nubase, nu); + keyIndex_delNurb(editnurb, nu); + BKE_nurb_free(nu); nu = NULL; } } - - /* Never allow the order to exceed the number of points - * - note, this is ok but changes unselected nurbs, disable for now */ + } + + /* Never allow the order to exceed the number of points + * - note, this is ok but changes unselected nurbs, disable for now */ #if 0 - if ((nu != NULL) && (nu->type == CU_NURBS)) { - clamp_nurb_order_u(nu); - } + if ((nu != NULL) && (nu->type == CU_NURBS)) { + clamp_nurb_order_u(nu); + } #endif - nu = next; - nuindex++; + nu = next; + nuindex++; + } + /* 2nd loop, delete small pieces: just for curves */ + nu = nubase->first; + while (nu) { + next = nu->next; + type = 0; + if (nu->type == CU_BEZIER) { + int delta = 0; + bezt = nu->bezt; + for (a = 0; a < nu->pntsu; a++) { + if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) { + memmove(bezt, bezt + 1, (nu->pntsu - a - 1) * sizeof(BezTriple)); + keyIndex_delBezt(editnurb, bezt + delta); + keyIndex_updateBezt(editnurb, bezt + 1, bezt, nu->pntsu - a - 1); + nu->pntsu--; + a--; + type = 1; + delta++; + } + else { + bezt++; + } + } + if (type) { + bezt1 = (BezTriple *)MEM_mallocN((nu->pntsu) * sizeof(BezTriple), "delNurb"); + memcpy(bezt1, nu->bezt, (nu->pntsu) * sizeof(BezTriple)); + keyIndex_updateBezt(editnurb, nu->bezt, bezt1, nu->pntsu); + MEM_freeN(nu->bezt); + nu->bezt = bezt1; + BKE_nurb_handles_calc(nu); + } } - /* 2nd loop, delete small pieces: just for curves */ - nu = nubase->first; - while (nu) { - next = nu->next; - type = 0; - if (nu->type == CU_BEZIER) { - int delta = 0; - bezt = nu->bezt; - for (a = 0; a < nu->pntsu; a++) { - if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) { - memmove(bezt, bezt + 1, (nu->pntsu - a - 1) * sizeof(BezTriple)); - keyIndex_delBezt(editnurb, bezt + delta); - keyIndex_updateBezt(editnurb, bezt + 1, bezt, nu->pntsu - a - 1); - nu->pntsu--; - a--; - type = 1; - delta++; - } - else { - bezt++; - } + else if (nu->pntsv == 1) { + int delta = 0; + bp = nu->bp; + + for (a = 0; a < nu->pntsu; a++) { + if (bp->f1 & SELECT) { + memmove(bp, bp + 1, (nu->pntsu - a - 1) * sizeof(BPoint)); + keyIndex_delBP(editnurb, bp + delta); + keyIndex_updateBP(editnurb, bp + 1, bp, nu->pntsu - a - 1); + nu->pntsu--; + a--; + type = 1; + delta++; } - if (type) { - bezt1 = (BezTriple *)MEM_mallocN((nu->pntsu) * sizeof(BezTriple), "delNurb"); - memcpy(bezt1, nu->bezt, (nu->pntsu) * sizeof(BezTriple)); - keyIndex_updateBezt(editnurb, nu->bezt, bezt1, nu->pntsu); - MEM_freeN(nu->bezt); - nu->bezt = bezt1; - BKE_nurb_handles_calc(nu); + else { + bp++; } } - else if (nu->pntsv == 1) { - int delta = 0; - bp = nu->bp; + if (type) { + bp1 = (BPoint *)MEM_mallocN(nu->pntsu * sizeof(BPoint), "delNurb2"); + memcpy(bp1, nu->bp, (nu->pntsu) * sizeof(BPoint)); + keyIndex_updateBP(editnurb, nu->bp, bp1, nu->pntsu); + MEM_freeN(nu->bp); + nu->bp = bp1; - for (a = 0; a < nu->pntsu; a++) { - if (bp->f1 & SELECT) { - memmove(bp, bp + 1, (nu->pntsu - a - 1) * sizeof(BPoint)); - keyIndex_delBP(editnurb, bp + delta); - keyIndex_updateBP(editnurb, bp + 1, bp, nu->pntsu - a - 1); - nu->pntsu--; - a--; - type = 1; - delta++; + /* Never allow the order to exceed the number of points + * - note, this is ok but changes unselected nurbs, disable for now */ +#if 0 + if (nu->type == CU_NURBS) { + clamp_nurb_order_u(nu); + } +#endif + } + BKE_nurb_order_clamp_u(nu); + BKE_nurb_knot_calc_u(nu); + } + nu = next; + } + + return OPERATOR_FINISHED; +} + +static int curve_delete_segments(Object *obedit, const bool split) +{ + Curve *cu = obedit->data; + EditNurb *editnurb = cu->editnurb; + ListBase *nubase = &editnurb->nurbs, newnurb = {NULL, NULL}; + Nurb *nu, *nu1; + BezTriple *bezt, *bezt1, *bezt2; + BPoint *bp, *bp1, *bp2; + int a, b, starta, enda, cut, cyclicut; + + for (nu = nubase->first; nu; nu = nu->next) { + nu1 = NULL; + starta = enda = cut = -1; + cyclicut = 0; + + if (nu->type == CU_BEZIER) { + for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) { + if (!BEZSELECTED_HIDDENHANDLES(cu, bezt)) { + enda = a; + if (starta == -1) starta = a; + if (a < nu->pntsu - 1) continue; + } + else if (a < nu->pntsu - 1 && !BEZSELECTED_HIDDENHANDLES(cu, bezt + 1)) { + /* if just single selected point then continue */ + continue; + } + + if (starta >= 0) { + /* got selected segment, now check where and copy */ + if (starta <= 1 && a == nu->pntsu - 1) { + /* copying all points in spline */ + if (starta == 1 && enda != a) nu->flagu &= ~CU_NURB_CYCLIC; + + starta = 0; + enda = a; + cut = enda - starta + 1; + nu1 = BKE_nurb_copy(nu, cut, 1); + } + else if (starta == 0) { + /* if start of curve copy next end point */ + enda++; + cut = enda - starta + 1; + bezt1 = &nu->bezt[nu->pntsu - 1]; + bezt2 = &nu->bezt[nu->pntsu - 2]; + + if ((nu->flagu & CU_NURB_CYCLIC) && + BEZSELECTED_HIDDENHANDLES(cu, bezt1) && + BEZSELECTED_HIDDENHANDLES(cu, bezt2)) + { + /* check if need to join start of spline to end */ + nu1 = BKE_nurb_copy(nu, cut + 1, 1); + ED_curve_beztcpy(editnurb, &nu1->bezt[1], nu->bezt, cut); + starta = nu->pntsu - 1; + cut = 1; + } + else { + if (nu->flagu & CU_NURB_CYCLIC) cyclicut = cut; + else nu1 = BKE_nurb_copy(nu, cut, 1); + } + } + else if (enda == nu->pntsu - 1) { + /* if end of curve copy previous start point */ + starta--; + cut = enda - starta + 1; + bezt1 = nu->bezt; + bezt2 = &nu->bezt[1]; + + if ((nu->flagu & CU_NURB_CYCLIC) && + BEZSELECTED_HIDDENHANDLES(cu, bezt1) && + BEZSELECTED_HIDDENHANDLES(cu, bezt2)) + { + /* check if need to join start of spline to end */ + nu1 = BKE_nurb_copy(nu, cut + 1, 1); + ED_curve_beztcpy(editnurb, &nu1->bezt[cut], nu->bezt, 1); + } + else if (cyclicut != 0) { + /* if cyclicut exists it is a cyclic spline, start and end should be connected */ + nu1 = BKE_nurb_copy(nu, cut + cyclicut, 1); + ED_curve_beztcpy(editnurb, &nu1->bezt[cut], nu->bezt, cyclicut); + cyclicut = 0; + } + else { + nu1 = BKE_nurb_copy(nu, cut, 1); + } } else { - bp++; + /* mid spline selection, copy adjacent start and end */ + starta--; + enda++; + cut = enda - starta + 1; + nu1 = BKE_nurb_copy(nu, cut, 1); } - } - if (type) { - bp1 = (BPoint *)MEM_mallocN(nu->pntsu * sizeof(BPoint), "delNurb2"); - memcpy(bp1, nu->bp, (nu->pntsu) * sizeof(BPoint)); - keyIndex_updateBP(editnurb, nu->bp, bp1, nu->pntsu); - MEM_freeN(nu->bp); - nu->bp = bp1; - - /* Never allow the order to exceed the number of points - * - note, this is ok but changes unselected nurbs, disable for now */ -#if 0 - if (nu->type == CU_NURBS) { - clamp_nurb_order_u(nu); + + if (nu1 != NULL) { + ED_curve_beztcpy(editnurb, nu1->bezt, &nu->bezt[starta], cut); + BLI_addtail(&newnurb, nu1); + + if (starta != 0 || enda != nu->pntsu - 1) nu1->flagu &= ~CU_NURB_CYCLIC; + nu1 = NULL; } -#endif + starta = enda = -1; + } + } + + if (!split && cut != -1 && nu->pntsu > 2 && !(nu->flagu & CU_NURB_CYCLIC)) { + /* start and points copied if connecting segment was deleted and not cylic spline */ + bezt1 = nu->bezt; + bezt2 = &nu->bezt[1]; + + if (BEZSELECTED_HIDDENHANDLES(cu, bezt1) && + BEZSELECTED_HIDDENHANDLES(cu, bezt2)) + { + nu1 = BKE_nurb_copy(nu, 1, 1); + ED_curve_beztcpy(editnurb, nu1->bezt, bezt1, 1); + BLI_addtail(&newnurb, nu1); + } + + bezt1 = &nu->bezt[nu->pntsu - 1]; + bezt2 = &nu->bezt[nu->pntsu - 2]; + + if (BEZSELECTED_HIDDENHANDLES(cu, bezt1) && + BEZSELECTED_HIDDENHANDLES(cu, bezt2)) + { + nu1 = BKE_nurb_copy(nu, 1, 1); + ED_curve_beztcpy(editnurb, nu1->bezt, bezt1, 1); + BLI_addtail(&newnurb, nu1); } - BKE_nurb_order_clamp_u(nu); - BKE_nurb_knot_calc_u(nu); } - nu = next; } - } - else if (type == CURVE_SEGMENT) { - for (nu = nubase->first; nu; nu = nu->next) { - startnu = nu1 = NULL; - starta = enda = cut = -1; + else if (nu->pntsv >= 1) { + int u, v; - if (nu->type == CU_BEZIER) { - for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) { - if (!BEZSELECTED_HIDDENHANDLES(cu, bezt)) { + if (isNurbselV(nu, &u, SELECT)) { + for (a = 0, bp = nu->bp; a < nu->pntsu; a++, bp++) { + if (!(bp->f1 & SELECT)) { enda = a; if (starta == -1) starta = a; if (a < nu->pntsu - 1) continue; } - else if (a < nu->pntsu - 1 && !BEZSELECTED_HIDDENHANDLES(cu, bezt + 1)) { + else if (a < nu->pntsu - 1 && !((bp + 1)->f1 & SELECT)) { /* if just single selected point then continue */ continue; } @@ -5925,69 +6118,52 @@ static int curve_delete_selected(Object *obedit, eCurveElem_Types type, const bo starta = 0; enda = a; cut = enda - starta + 1; - - nu1 = ED_curve_nurbcpy(nu, cut); + nu1 = BKE_nurb_copy(nu, cut, nu->pntsv); } else if (starta == 0) { /* if start of curve copy next end point */ enda++; cut = enda - starta + 1; + bp1 = &nu->bp[nu->pntsu - 1]; + bp2 = &nu->bp[nu->pntsu - 2]; - bezt1 = &nu->bezt[nu->pntsu - 1]; - bezt2 = &nu->bezt[nu->pntsu - 2]; - - if ((nu->flagu & CU_NURB_CYCLIC) && - BEZSELECTED_HIDDENHANDLES(cu, bezt1) && - BEZSELECTED_HIDDENHANDLES(cu, bezt2)) - { + if ((nu->flagu & CU_NURB_CYCLIC) && (bp1->f1 & SELECT) && (bp2->f1 & SELECT)) { /* check if need to join start of spline to end */ - nu1 = ED_curve_nurbcpy(nu, cut + 1); - ED_curve_beztcpy(editnurb, &nu1->bezt[1], nu->bezt, cut); + nu1 = BKE_nurb_copy(nu, cut + 1, nu->pntsv); + for (b = 0; b < nu->pntsv; b++) { + ED_curve_bpcpy(editnurb, &nu1->bp[b * nu1->pntsu + 1], &nu->bp[b * nu->pntsu], cut); + } starta = nu->pntsu - 1; cut = 1; } else { - nu1 = ED_curve_nurbcpy(nu, cut); - - if (nu->flagu & CU_NURB_CYCLIC) startnu = nu1; + if (nu->flagu & CU_NURB_CYCLIC) cyclicut = cut; + else nu1 = BKE_nurb_copy(nu, cut, nu->pntsv); } } else if (enda == nu->pntsu - 1) { /* if end of curve copy previous start point */ starta--; cut = enda - starta + 1; + bp1 = nu->bp; + bp2 = &nu->bp[1]; - bezt1 = nu->bezt; - bezt2 = &nu->bezt[1]; - - if ((nu->flagu & CU_NURB_CYCLIC) && - BEZSELECTED_HIDDENHANDLES(cu, bezt1) && - BEZSELECTED_HIDDENHANDLES(cu, bezt2)) - { + if ((nu->flagu & CU_NURB_CYCLIC) && (bp1->f1 & SELECT) && (bp2->f1 & SELECT)) { /* check if need to join start of spline to end */ - nu1 = ED_curve_nurbcpy(nu, cut + 1); - ED_curve_beztcpy(editnurb, &nu1->bezt[cut], nu->bezt, 1); + nu1 = BKE_nurb_copy(nu, cut + 1, nu->pntsv); + for (b = 0; b < nu->pntsv; b++) { + ED_curve_bpcpy(editnurb, &nu1->bp[b * nu1->pntsu + cut], &nu->bp[b * nu->pntsu], 1); + } } - else if (startnu != NULL) { - /* if startnu exists it is a cyclic spline, start and end should be connected */ - bezt1 = (BezTriple *)MEM_mallocN((cut + startnu->pntsu) * sizeof(BezTriple), "delNurb3"); - ED_curve_beztcpy(editnurb, bezt1, &nu->bezt[starta], cut); - ED_curve_beztcpy(editnurb, &bezt1[cut], nu->bezt, startnu->pntsu); - - MEM_freeN(startnu->bezt); - startnu->bezt = bezt1; - startnu->pntsu += cut; - - if (split) { - for (b = 0; b < startnu->pntsu; b++, bezt1++) { - select_beztriple(bezt1, DESELECT, SELECT, true); - } + else if (cyclicut != 0) { + /* if cyclicut exists it is a cyclic spline, start and end should be connected */ + nu1 = BKE_nurb_copy(nu, cut + cyclicut, nu->pntsv); + for (b = 0; b < nu->pntsv; b++) { + ED_curve_bpcpy(editnurb, &nu1->bp[b * nu1->pntsu + cut], &nu->bp[b * nu->pntsu], cyclicut); } - - BKE_nurb_handles_calc(startnu); } else { - nu1 = ED_curve_nurbcpy(nu, cut); + nu1 = BKE_nurb_copy(nu, cut, nu->pntsv); } } else { @@ -5995,24 +6171,16 @@ static int curve_delete_selected(Object *obedit, eCurveElem_Types type, const bo starta--; enda++; cut = enda - starta + 1; - - nu1 = ED_curve_nurbcpy(nu, cut); + nu1 = BKE_nurb_copy(nu, cut, nu->pntsv); } if (nu1 != NULL) { - ED_curve_beztcpy(editnurb, nu1->bezt, &nu->bezt[starta], cut); - - if (starta != 0 || enda != nu->pntsu - 1) nu1->flagu &= ~CU_NURB_CYCLIC; - - if (split) { - /* deselect for split operator */ - for (b = 0, bezt1 = nu1->bezt; b < nu1->pntsu; b++, bezt1++) { - select_beztriple(bezt1, DESELECT, SELECT, true); - } + for (b = 0; b < nu->pntsv; b++) { + ED_curve_bpcpy(editnurb, &nu1->bp[b * nu1->pntsu], &nu->bp[b * nu->pntsu + starta], cut); } - BLI_addtail(&newnurb, nu1); - BKE_nurb_handles_calc(nu1); + + if (starta != 0 || enda != nu->pntsu - 1) nu1->flagu &= ~CU_NURB_CYCLIC; nu1 = NULL; } starta = enda = -1; @@ -6021,102 +6189,91 @@ static int curve_delete_selected(Object *obedit, eCurveElem_Types type, const bo if (!split && cut != -1 && nu->pntsu > 2 && !(nu->flagu & CU_NURB_CYCLIC)) { /* start and points copied if connecting segment was deleted and not cylic spline */ - bezt1 = nu->bezt; - bezt2 = &nu->bezt[1]; - if (BEZSELECTED_HIDDENHANDLES(cu, bezt1) && BEZSELECTED_HIDDENHANDLES(cu, bezt2)) { - nu1 = ED_curve_nurbcpy(nu, 1); - ED_curve_beztcpy(editnurb, nu1->bezt, bezt1, 1); + bp1 = nu->bp; + bp2 = &nu->bp[1]; + + if ((bp1->f1 & SELECT) && (bp2->f1 & SELECT)) { + nu1 = BKE_nurb_copy(nu, 1, nu->pntsv); + for (b = 0; b < nu->pntsv; b++) { + ED_curve_bpcpy(editnurb, &nu1->bp[b], &nu->bp[b * nu->pntsu], 1); + } BLI_addtail(&newnurb, nu1); } - bezt1 = &nu->bezt[nu->pntsu - 1]; - bezt2 = &nu->bezt[nu->pntsu - 2]; - if (BEZSELECTED_HIDDENHANDLES(cu, bezt1) && BEZSELECTED_HIDDENHANDLES(cu, bezt2)) { - nu1 = ED_curve_nurbcpy(nu, 1); - ED_curve_beztcpy(editnurb, nu1->bezt, bezt1, 1); + bp1 = &nu->bp[nu->pntsu - 1]; + bp2 = &nu->bp[nu->pntsu - 2]; + + if ((bp1->f1 & SELECT) && (bp2->f1 & SELECT)) { + nu1 = BKE_nurb_copy(nu, 1, nu->pntsv); + for (b = 0; b < nu->pntsv; b++) { + ED_curve_bpcpy(editnurb, &nu1->bp[b], &nu->bp[b * nu->pntsu + nu->pntsu - 1], 1); + } BLI_addtail(&newnurb, nu1); } } } - else if (nu->pntsv == 1) { - for (a = 0, bp = nu->bp; a < nu->pntsu; a++, bp++) { + else if (isNurbselU(nu, &v, SELECT)) { + for (a = 0, bp = nu->bp; a < nu->pntsv; a++, bp += nu->pntsu) { if (!(bp->f1 & SELECT)) { enda = a; if (starta == -1) starta = a; - if (a < nu->pntsu - 1) continue; + if (a < nu->pntsv - 1) continue; } - else if (a < nu->pntsu - 1 && !((bp + 1)->f1 & SELECT)) { + else if (a < nu->pntsv - 1 && !((bp + nu->pntsu)->f1 & SELECT)) { /* if just single selected point then continue */ continue; } if (starta >= 0) { /* got selected segment, now check where and copy */ - if (starta <= 1 && a == nu->pntsu - 1) { + if (starta <= 1 && a == nu->pntsv - 1) { /* copying all points in spline */ - if (starta == 1 && enda != a) nu->flagu &= ~CU_NURB_CYCLIC; + if (starta == 1 && enda != a) nu->flagv &= ~CU_NURB_CYCLIC; starta = 0; enda = a; cut = enda - starta + 1; - - nu1 = ED_curve_nurbcpy(nu, cut); + nu1 = BKE_nurb_copy(nu, nu->pntsu, cut); } else if (starta == 0) { /* if start of curve copy next end point */ enda++; cut = enda - starta + 1; + bp1 = &nu->bp[nu->pntsv * nu->pntsu - nu->pntsu]; + bp2 = &nu->bp[nu->pntsv * nu->pntsu - (nu->pntsu * 2)]; - bp1 = &nu->bp[nu->pntsu - 1]; - bp2 = &nu->bp[nu->pntsu - 2]; - - if ((nu->flagu & CU_NURB_CYCLIC) && (bp1->f1 & SELECT) && (bp2->f1 & SELECT)) { + if ((nu->flagv & CU_NURB_CYCLIC) && (bp1->f1 & SELECT) && (bp2->f1 & SELECT)) { /* check if need to join start of spline to end */ - nu1 = ED_curve_nurbcpy(nu, cut + 1); - ED_curve_bpcpy(editnurb, &nu1->bp[1], nu->bp, cut); - starta = nu->pntsu - 1; + nu1 = BKE_nurb_copy(nu, nu->pntsu, cut + 1); + ED_curve_bpcpy(editnurb, &nu1->bp[nu->pntsu], nu->bp, cut * nu->pntsu); + starta = nu->pntsv - 1; cut = 1; } else { - nu1 = ED_curve_nurbcpy(nu, cut); - - if (nu->flagu & CU_NURB_CYCLIC) startnu = nu1; + if (nu->flagv & CU_NURB_CYCLIC) cyclicut = cut; + else nu1 = BKE_nurb_copy(nu, nu->pntsu, cut); } } - else if (enda == nu->pntsu - 1) { + else if (enda == nu->pntsv - 1) { /* if end of curve copy previous start point */ starta--; cut = enda - starta + 1; - bp1 = nu->bp; - bp2 = &nu->bp[1]; + bp2 = &nu->bp[nu->pntsu]; - if ((nu->flagu & CU_NURB_CYCLIC) && (bp1->f1 & SELECT) && (bp2->f1 & SELECT)) { + if ((nu->flagv & CU_NURB_CYCLIC) && (bp1->f1 & SELECT) && (bp2->f1 & SELECT)) { /* check if need to join start of spline to end */ - nu1 = ED_curve_nurbcpy(nu, cut + 1); - ED_curve_bpcpy(editnurb, &nu1->bp[cut], nu->bp, 1); + nu1 = BKE_nurb_copy(nu, nu->pntsu, cut + 1); + ED_curve_bpcpy(editnurb, &nu1->bp[cut * nu->pntsu], nu->bp, nu->pntsu); } - else if (startnu != NULL) { - /* if startnu exists it is a cyclic spline, start and end should be connected */ - bp1 = (BPoint *)MEM_mallocN((cut + startnu->pntsu) * sizeof(BPoint), "delNurb4"); - ED_curve_bpcpy(editnurb, bp1, &nu->bp[starta], cut); - ED_curve_bpcpy(editnurb, &bp1[cut], nu->bp, startnu->pntsu); - - MEM_freeN(startnu->bp); - startnu->bp = bp1; - startnu->pntsu += cut; - - if (split) { - for (b = 0; b < startnu->pntsu; b++, bp1++) { - select_bpoint(bp1, DESELECT, SELECT, HIDDEN); - } - } - - BKE_nurb_order_clamp_u(startnu); - BKE_nurb_knot_calc_u(startnu); + else if (cyclicut != 0) { + /* if cyclicut exists it is a cyclic spline, start and end should be connected */ + nu1 = BKE_nurb_copy(nu, nu->pntsu, cut + cyclicut); + ED_curve_bpcpy(editnurb, &nu1->bp[cut * nu->pntsu], nu->bp, nu->pntsu * cyclicut); + cyclicut = 0; } else { - nu1 = ED_curve_nurbcpy(nu, cut); + nu1 = BKE_nurb_copy(nu, nu->pntsu, cut); } } else { @@ -6124,72 +6281,102 @@ static int curve_delete_selected(Object *obedit, eCurveElem_Types type, const bo starta--; enda++; cut = enda - starta + 1; - - nu1 = ED_curve_nurbcpy(nu, cut); + nu1 = BKE_nurb_copy(nu, nu->pntsu, cut); } if (nu1 != NULL) { - ED_curve_bpcpy(editnurb, nu1->bp, &nu->bp[starta], cut); - - if (starta != 0 || enda != nu->pntsu - 1) nu1->flagu &= ~CU_NURB_CYCLIC; - - if (split) { - /* deselect for split operator */ - for (b = 0, bp1 = nu1->bp; b < nu1->pntsu; b++, bp1++) { - select_bpoint(bp1, DESELECT, SELECT, HIDDEN); - } - } - + ED_curve_bpcpy(editnurb, nu1->bp, &nu->bp[starta * nu->pntsu], cut * nu->pntsu); BLI_addtail(&newnurb, nu1); - nu1->knotsu = NULL; - BKE_nurb_order_clamp_u(nu1); - BKE_nurb_knot_calc_u(nu1); + + if (starta != 0 || enda != nu->pntsv - 1) nu1->flagv &= ~CU_NURB_CYCLIC; nu1 = NULL; } starta = enda = -1; } } - if (!split && cut != -1 && nu->pntsu > 2 && !(nu->flagu & CU_NURB_CYCLIC)) { + if (!split && cut != -1 && nu->pntsv > 2 && !(nu->flagv & CU_NURB_CYCLIC)) { /* start and points copied if connecting segment was deleted and not cylic spline */ bp1 = nu->bp; - bp2 = &nu->bp[1]; + bp2 = &nu->bp[nu->pntsu]; + if ((bp1->f1 & SELECT) && (bp2->f1 & SELECT)) { - nu1 = ED_curve_nurbcpy(nu, 1); - ED_curve_bpcpy(editnurb, nu1->bp, bp1, 1); + nu1 = BKE_nurb_copy(nu, nu->pntsu, 1); + ED_curve_bpcpy(editnurb, nu1->bp, nu->bp, nu->pntsu); BLI_addtail(&newnurb, nu1); - nu1->knotsu = NULL; } - bp1 = &nu->bp[nu->pntsu - 1]; - bp2 = &nu->bp[nu->pntsu - 2]; + bp1 = &nu->bp[nu->pntsu * nu->pntsv - nu->pntsu]; + bp2 = &nu->bp[nu->pntsu * nu->pntsv - (nu->pntsu * 2)]; + if ((bp1->f1 & SELECT) && (bp2->f1 & SELECT)) { - nu1 = ED_curve_nurbcpy(nu, 1); - ED_curve_bpcpy(editnurb, nu1->bp, bp1, 1); + nu1 = BKE_nurb_copy(nu, nu->pntsu, 1); + ED_curve_bpcpy(editnurb, nu1->bp, &nu->bp[nu->pntsu * nu->pntsv - nu->pntsu], nu->pntsu); BLI_addtail(&newnurb, nu1); - nu1->knotsu = NULL; } } } + else { + /* selection not valid, just copy nurb to new list */ + nu1 = BKE_nurb_copy(nu, nu->pntsu, nu->pntsv); + ED_curve_bpcpy(editnurb, nu1->bp, nu->bp, nu->pntsu * nu->pntsv); + BLI_addtail(&newnurb, nu1); + } } - - BKE_nurbList_free(nubase); - BLI_movelisttolist(nubase, &newnurb); } - else { - BLI_assert(0); + + for (nu = newnurb.first; nu; nu = nu->next) { + if (nu->type == CU_BEZIER) { + if (split) { + /* deselect for split operator */ + for (b = 0, bezt1 = nu->bezt; b < nu->pntsu; b++, bezt1++) { + select_beztriple(bezt1, DESELECT, SELECT, true); + } + } + + BKE_nurb_handles_calc(nu); + } + else { + if (split) { + /* deselect for split operator */ + for (b = 0, bp1 = nu->bp; b < nu->pntsu * nu->pntsv; b++, bp1++) { + select_bpoint(bp1, DESELECT, SELECT, HIDDEN); + } + } + + nu->knotsu = nu->knotsv = NULL; + BKE_nurb_order_clamp_u(nu); + BKE_nurb_knot_calc_u(nu); + + if (nu->pntsv > 1) { + BKE_nurb_order_clamp_v(nu); + BKE_nurb_knot_calc_v(nu); + } + } } + keyIndex_delNurbList(editnurb, nubase); + BKE_nurbList_free(nubase); + BLI_movelisttolist(nubase, &newnurb); + return OPERATOR_FINISHED; } static int curve_delete_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); + Curve *cu = (Curve *)obedit->data; eCurveElem_Types type = RNA_enum_get(op->ptr, "type"); - int retval = curve_delete_selected(obedit, type, false); + int retval; + + if (type == CURVE_VERTEX) retval = curve_delete_vertices(obedit); + else if (type == CURVE_SEGMENT) retval = curve_delete_segments(obedit, false); + else BLI_assert(0); if (retval == OPERATOR_FINISHED) { + cu->lastsel = NULL; + cu->actnu = -1; + if (ED_curve_updateAnimPaths(obedit->data)) WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); @@ -6210,23 +6397,14 @@ static EnumPropertyItem curve_delete_type_items[] = { static EnumPropertyItem *rna_curve_delete_type_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) { - Object *obedit; EnumPropertyItem *item = NULL; int totitem = 0; - if (!C) /* needed for docs and i18n tools */ return curve_delete_type_items; - obedit = CTX_data_edit_object(C); - if (obedit->type == OB_SURF) { - RNA_enum_items_add_value(&item, &totitem, curve_delete_type_items, CURVE_VERTEX); - } - else { - RNA_enum_items_add_value(&item, &totitem, curve_delete_type_items, CURVE_VERTEX); - RNA_enum_items_add_value(&item, &totitem, curve_delete_type_items, CURVE_SEGMENT); - } - + RNA_enum_items_add_value(&item, &totitem, curve_delete_type_items, CURVE_VERTEX); + RNA_enum_items_add_value(&item, &totitem, curve_delete_type_items, CURVE_SEGMENT); RNA_enum_item_end(&item, &totitem); *free = true; @@ -6615,22 +6793,6 @@ void ED_curve_bpcpy(EditNurb *editnurb, BPoint *dst, BPoint *src, int count) keyIndex_updateBP(editnurb, src, dst, count); } -Nurb *ED_curve_nurbcpy(Nurb *src, int count) -{ - Nurb *newnu = (Nurb *)MEM_mallocN(sizeof(Nurb), "copyNurb"); - memcpy(newnu, src, sizeof(Nurb)); - newnu->pntsu = count; - - if (src->bezt) { - newnu->bezt = (BezTriple *)MEM_mallocN(count * sizeof(BezTriple), "copyNurb2"); - } - else { - newnu->bp = (BPoint *)MEM_mallocN(count * sizeof(BPoint), "copyNurb3"); - } - - return newnu; -} - int ED_curve_actSelection(Curve *cu, float center[3]) { Nurb *nu = get_lastsel_nurb(cu); diff --git a/source/blender/editors/curve/editcurve_add.c b/source/blender/editors/curve/editcurve_add.c index 9b858a2c4e9..6804aa3584f 100644 --- a/source/blender/editors/curve/editcurve_add.c +++ b/source/blender/editors/curve/editcurve_add.c @@ -458,6 +458,8 @@ Nurb *add_nurbs_primitive(bContext *C, Object *obedit, float mat[4][4], int type if (nu) { /* should always be set */ nu->flag |= CU_SMOOTH; + cu->actnu = BLI_countlist(editnurb); + cu->lastsel = NULL; BKE_nurb_test2D(nu); } diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index ac9c338e431..8f536575a28 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -1442,18 +1442,14 @@ void make_editText(Object *obedit) ef->textbufinfo = MEM_callocN((MAXTEXT + 4) * sizeof(CharInfo), "texteditbufinfo"); ef->copybuf = MEM_callocN((MAXTEXT + 4) * sizeof(wchar_t), "texteditcopybuf"); ef->copybufinfo = MEM_callocN((MAXTEXT + 4) * sizeof(CharInfo), "texteditcopybufinfo"); - ef->oldstr = MEM_callocN((MAXTEXT + 4) * sizeof(wchar_t), "oldstrbuf"); - ef->oldstrinfo = MEM_callocN((MAXTEXT + 4) * sizeof(CharInfo), "oldstrbuf"); } /* Convert the original text to wchar_t */ BLI_strncpy_wchar_from_utf8(ef->textbuf, cu->str, MAXTEXT + 4); /* length is bogus */ - wcscpy(ef->oldstr, ef->textbuf); cu->len = wcslen(ef->textbuf); memcpy(ef->textbufinfo, cu->strinfo, (cu->len) * sizeof(CharInfo)); - memcpy(ef->oldstrinfo, cu->strinfo, (cu->len) * sizeof(CharInfo)); if (cu->pos > cu->len) cu->pos = cu->len; @@ -1471,11 +1467,6 @@ void load_editText(Object *obedit) Curve *cu = obedit->data; EditFont *ef = cu->editfont; - MEM_freeN(ef->oldstr); - ef->oldstr = NULL; - MEM_freeN(ef->oldstrinfo); - ef->oldstrinfo = NULL; - update_string(cu); if (cu->strinfo) @@ -1484,13 +1475,6 @@ void load_editText(Object *obedit) memcpy(cu->strinfo, ef->textbufinfo, (cu->len) * sizeof(CharInfo)); cu->len = strlen(cu->str); - - /* this memory system is weak... */ - - if (cu->selboxes) { - MEM_freeN(cu->selboxes); - cu->selboxes = NULL; - } } void free_editText(Object *obedit) @@ -1613,11 +1597,10 @@ static void font_ui_template_init(bContext *C, wmOperator *op) uiIDContextProperty(C, &pprop->ptr, &pprop->prop); } -static int font_open_cancel(bContext *UNUSED(C), wmOperator *op) +static void font_open_cancel(bContext *UNUSED(C), wmOperator *op) { MEM_freeN(op->customdata); op->customdata = NULL; - return OPERATOR_CANCELLED; } static int font_open_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index c5dc8654e9d..0298699fac5 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -454,7 +454,7 @@ static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoin copy_v3_v3(p3d, &pt->x); } else { - const float *fp = give_cursor(scene, v3d); + const float *fp = ED_view3d_cursor3d_get(scene, v3d); float mvalf[2]; /* get screen coordinate */ diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 255f0b7cfba..2cf8d9c27af 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -211,7 +211,7 @@ static int gpencil_project_check(tGPsdata *p) static void gp_get_3d_reference(tGPsdata *p, float vec[3]) { View3D *v3d = p->sa->spacedata.first; - const float *fp = give_cursor(p->scene, v3d); + const float *fp = ED_view3d_cursor3d_get(p->scene, v3d); /* the reference point used depends on the owner... */ #if 0 /* XXX: disabled for now, since we can't draw relative to the owner yet */ @@ -1456,11 +1456,10 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op) op->customdata = NULL; } -static int gpencil_draw_cancel(bContext *C, wmOperator *op) +static void gpencil_draw_cancel(bContext *C, wmOperator *op) { /* this is just a wrapper around exit() */ gpencil_draw_exit(C, op); - return OPERATOR_CANCELLED; } /* ------------------------------- */ @@ -1875,7 +1874,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) //printf("\tGP - handle modal event...\n"); /* exit painting mode (and/or end current stroke) - * NOTE: cannot do RIGHTMOUSE (as is standard for cancelling) as that would break polyline [#32647] + * NOTE: cannot do RIGHTMOUSE (as is standard for canceling) as that would break polyline [#32647] */ if (ELEM4(event->type, RETKEY, PADENTER, ESCKEY, SPACEKEY)) { /* exit() ends the current stroke before cleaning up */ diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 61f9cec15d9..8b9bb0a4ab0 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -396,15 +396,15 @@ typedef struct bAnimChannelType { /* get name (for channel lists) */ void (*name)(bAnimListElem *ale, char *name); /* get RNA property+pointer for editing the name */ - short (*name_prop)(bAnimListElem *ale, struct PointerRNA *ptr, struct PropertyRNA **prop); + bool (*name_prop)(bAnimListElem *ale, struct PointerRNA *ptr, struct PropertyRNA **prop); /* get icon (for channel lists) */ int (*icon)(bAnimListElem *ale); /* settings */ /* check if the given setting is valid in the current context */ - short (*has_setting)(bAnimContext *ac, bAnimListElem *ale, int setting); + bool (*has_setting)(bAnimContext *ac, bAnimListElem *ale, int setting); /* get the flag used for this setting */ - int (*setting_flag)(bAnimContext *ac, int setting, short *neg); + int (*setting_flag)(bAnimContext *ac, int setting, bool *neg); /* get the pointer to int/short where data is stored, * with type being sizeof(ptr_data) which should be fine for runtime use... * - assume that setting has been checked to be valid for current context @@ -559,13 +559,19 @@ typedef enum eAnimUnitConv_Flags { /* only touch selected vertices */ ANIM_UNITCONV_SELVERTS = (1 << 3), ANIM_UNITCONV_SKIPKNOTS = (1 << 4), + /* Scale FCurve i a way it fits to -1..1 space */ + ANIM_UNITCONV_NORMALIZE = (1 << 5), + /* Only whennormalization is used: use scale factor from previous run, + * prevents curves from jumping all over the place when tweaking them. + */ + ANIM_UNITCONV_NORMALIZE_FREEZE = (1 << 6), } eAnimUnitConv_Flags; -/* Get unit conversion factor for given ID + F-Curve */ -float ANIM_unit_mapping_get_factor(struct Scene *scene, struct ID *id, struct FCurve *fcu, short restore); +/* Normalizatin flags from Space Graph passing to ANIM_unit_mapping_get_factor */ +short ANIM_get_normalization_flags(bAnimContext *ac); -/* Apply/Unapply units conversions to keyframes */ -void ANIM_unit_mapping_apply_fcurve(struct Scene *scene, struct ID *id, struct FCurve *fcu, short flag); +/* Get unit conversion factor for given ID + F-Curve */ +float ANIM_unit_mapping_get_factor(struct Scene *scene, struct ID *id, struct FCurve *fcu, short flag); /* ------------- Utility macros ----------------------- */ diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 225d8a0e5a3..e9caf89d9da 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -106,7 +106,7 @@ typedef struct EditBone { (((ebone)->flag & BONE_SELECTED) && !((ebone)->flag & BONE_EDITMODE_LOCKED)) \ ) -/* used in bone_select_hierachy() */ +/* used in armature_select_hierarchy_exec() */ #define BONE_SELECT_PARENT 0 #define BONE_SELECT_CHILD 1 @@ -128,7 +128,8 @@ bool mouse_armature(struct bContext *C, const int mval[2], bool extend, bool des int join_armature_exec(struct bContext *C, struct wmOperator *op); struct Bone *get_indexed_bone(struct Object *ob, int index); float ED_rollBoneToVector(EditBone *bone, const float new_up_axis[3], const short axis_only); -EditBone *ED_armature_bone_get_mirrored(struct ListBase *edbo, EditBone *ebo); // XXX this is needed for populating the context iterators +EditBone *ED_armature_bone_find_name(const ListBase *edbo, const char *name); +EditBone *ED_armature_bone_get_mirrored(const struct ListBase *edbo, EditBone *ebo); void ED_armature_sync_selection(struct ListBase *edbo); void ED_armature_validate_active(struct bArmature *arm); @@ -137,6 +138,7 @@ struct EditBone *ED_armature_edit_bone_add(struct bArmature *arm, const char *na void ED_armature_edit_bone_remove(struct bArmature *arm, EditBone *exBone); bool ED_armature_ebone_is_child_recursive(EditBone *ebone_parent, EditBone *ebone_child); +EditBone *ED_armature_bone_find_shared_parent(EditBone *ebone_child[], const unsigned int ebone_child_tot); void ED_armature_ebone_to_mat3(EditBone *ebone, float mat[3][3]); void ED_armature_ebone_to_mat4(EditBone *ebone, float mat[4][4]); @@ -168,6 +170,7 @@ void ED_armature_ebone_selectflag_disable(EditBone *ebone, int flag); void ED_armature_exit_posemode(struct bContext *C, struct Base *base); void ED_armature_enter_posemode(struct bContext *C, struct Base *base); void ED_pose_deselectall(struct Object *ob, int test); +void ED_pose_bone_select(struct Object *ob, struct bPoseChannel *pchan, bool select); void ED_pose_recalculate_paths(struct Scene *scene, struct Object *ob); struct Object *ED_pose_object_from_context(struct bContext *C); diff --git a/source/blender/editors/include/ED_mball.h b/source/blender/editors/include/ED_mball.h index 1842b84a3f5..22aec69838b 100644 --- a/source/blender/editors/include/ED_mball.h +++ b/source/blender/editors/include/ED_mball.h @@ -37,6 +37,7 @@ struct Object; struct wmKeyConfig; void ED_operatortypes_metaball(void); +void ED_operatormacros_metaball(void); void ED_keymap_metaball(struct wmKeyConfig *keyconf); struct MetaElem *add_metaball_primitive(struct bContext *C, struct Object *obedit, float mat[4][4], float dia, int type); diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 5d3d72d0e3d..9d3404aa29b 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -97,16 +97,6 @@ void EDBM_mesh_free(struct BMEditMesh *em); void EDBM_mesh_load(struct Object *ob); struct DerivedMesh *EDBM_mesh_deform_dm_get(struct BMEditMesh *em); -void EDBM_index_arrays_ensure(struct BMEditMesh *em, const char htype); -void EDBM_index_arrays_init(struct BMEditMesh *em, const char htype); -void EDBM_index_arrays_free(struct BMEditMesh *em); -#ifndef NDEBUG -bool EDBM_index_arrays_check(struct BMEditMesh *em); -#endif -struct BMVert *EDBM_vert_at_index(struct BMEditMesh *em, int index); -struct BMEdge *EDBM_edge_at_index(struct BMEditMesh *em, int index); -struct BMFace *EDBM_face_at_index(struct BMEditMesh *em, int index); - /* flushes based on the current select mode. if in vertex select mode, * verts select/deselect edges and faces, if in edge select mode, * edges select/deselect faces and vertices, and in face select mode faces select/deselect @@ -129,16 +119,16 @@ void EDBM_mesh_reveal(struct BMEditMesh *em); void EDBM_update_generic(struct BMEditMesh *em, const bool do_tessface, const bool is_destructive); -struct UvElementMap *EDBM_uv_element_map_create(struct BMEditMesh *em, const bool selected, const bool do_islands); -void EDBM_uv_element_map_free(struct UvElementMap *vmap); -struct UvElement *ED_uv_element_get(struct UvElementMap *map, struct BMFace *efa, struct BMLoop *l); +struct UvElementMap *BM_uv_element_map_create(struct BMesh *em, const bool selected, const bool do_islands); +void BM_uv_element_map_free(struct UvElementMap *vmap); +struct UvElement *BM_uv_element_get(struct UvElementMap *map, struct BMFace *efa, struct BMLoop *l); bool EDBM_mtexpoly_check(struct BMEditMesh *em); struct MTexPoly *EDBM_mtexpoly_active_get(struct BMEditMesh *em, struct BMFace **r_act_efa, const bool sloppy, const bool selected); -void EDBM_uv_vert_map_free(struct UvVertMap *vmap); -struct UvMapVert *EDBM_uv_vert_map_at_index(struct UvVertMap *vmap, unsigned int v); -struct UvVertMap *EDBM_uv_vert_map_create(struct BMEditMesh *em, bool use_select, const float limit[2]); +void BM_uv_vert_map_free(struct UvVertMap *vmap); +struct UvMapVert *BM_uv_vert_map_at_index(struct UvVertMap *vmap, unsigned int v); +struct UvVertMap *BM_uv_vert_map_create(struct BMesh *bm, bool use_select, const float limit[2]); void EDBM_flag_enable_all(struct BMEditMesh *em, const char hflag); void EDBM_flag_disable_all(struct BMEditMesh *em, const char hflag); diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h index 2f16d84aed0..de83df9cc05 100644 --- a/source/blender/editors/include/ED_node.h +++ b/source/blender/editors/include/ED_node.h @@ -54,6 +54,8 @@ typedef enum { NODE_RIGHT = 8 } NodeBorder; +#define NODE_GRID_STEPS 5 + /* space_node.c */ int ED_node_tree_path_length(struct SpaceNode *snode); void ED_node_tree_path_get(struct SpaceNode *snode, char *value); @@ -81,6 +83,7 @@ void ED_node_tree_update(const struct bContext *C); void ED_node_tag_update_id(struct ID *id); void ED_node_tag_update_nodetree(struct Main *bmain, struct bNodeTree *ntree); void ED_node_sort(struct bNodeTree *ntree); +float ED_node_grid_size(void); /* node_relationships.c */ void ED_node_link_intersect_test(struct ScrArea *sa, int test); diff --git a/source/blender/editors/include/ED_numinput.h b/source/blender/editors/include/ED_numinput.h index e7d80d96f89..f46332c9a82 100644 --- a/source/blender/editors/include/ED_numinput.h +++ b/source/blender/editors/include/ED_numinput.h @@ -27,7 +27,6 @@ #ifndef __ED_NUMINPUT_H__ #define __ED_NUMINPUT_H__ - /* * The ctrl value has different meaning: * 0 : No value has been typed @@ -59,11 +58,11 @@ typedef struct NumInput { void initNumInput(NumInput *n); #define NUM_STR_REP_LEN 20 /* str must be NUM_STR_LEN * (idx_max + 1) length. */ void outputNumInput(NumInput *n, char *str); -short hasNumInput(NumInput *n); +bool hasNumInput(const NumInput *n); void applyNumInput(NumInput *n, float *vec); -char handleNumInput(NumInput *n, const struct wmEvent *event); +bool handleNumInput(NumInput *n, const struct wmEvent *event); #define NUM_MODAL_INCREMENT_UP 18 #define NUM_MODAL_INCREMENT_DOWN 19 -#endif +#endif /* __ED_NUMINPUT_H__ */ diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index eae2141e527..4155dbb5565 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -51,6 +51,7 @@ struct Main; struct Mesh; struct MetaElem; struct ModifierData; +struct HookModifierData; struct Nurb; struct Object; struct ReportList; @@ -218,6 +219,8 @@ struct EnumPropertyItem *ED_object_vgroup_selection_itemf_helper( int *free, const unsigned int selection_mask); +void ED_object_check_force_modifiers(struct Main *bmain, struct Scene *scene, struct Object *object); + #ifdef __cplusplus } #endif diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h index 518bee665ae..8f39502b2fe 100644 --- a/source/blender/editors/include/ED_render.h +++ b/source/blender/editors/include/ED_render.h @@ -55,6 +55,7 @@ void ED_render_scene_update(struct Main *bmain, struct Scene *scene, int updated void ED_render_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrArea *sa); void ED_viewport_render_kill_jobs(const struct bContext *C, bool free_database); +struct Scene *ED_render_job_get_scene(const struct bContext *C); /* render_preview.c */ diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h index a50a8a50eaa..e85f11e5b78 100644 --- a/source/blender/editors/include/ED_sculpt.h +++ b/source/blender/editors/include/ED_sculpt.h @@ -37,6 +37,8 @@ struct Object; struct RegionView3D; struct wmKeyConfig; struct wmWindowManager; +struct ViewContext; +struct rcti; /* sculpt.c */ void ED_operatortypes_sculpt(void); @@ -48,6 +50,8 @@ void ED_sculpt_get_average_stroke(struct Object *ob, float stroke[3]); int ED_sculpt_minmax(struct bContext *C, float min[3], float max[3]); int ED_sculpt_mask_layers_ensure(struct Object *ob, struct MultiresModifierData *mmd); +int do_sculpt_mask_box_select(struct ViewContext *vc, struct rcti *rect, bool select, bool extend); + enum { ED_SCULPT_MASK_LAYER_CALC_VERT = (1 << 0), ED_SCULPT_MASK_LAYER_CALC_LOOP = (1 << 1) diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index eff79b6a039..dde1aa30a26 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -62,7 +62,7 @@ enum TfmMode { TFM_SKIN_RESIZE, TFM_TOSPHERE, TFM_SHEAR, - TFM_WARP, + TFM_BEND, TFM_SHRINKFATTEN, TFM_TILT, TFM_TRACKBALL, @@ -130,8 +130,6 @@ void ED_getTransformOrientationMatrix(const struct bContext *C, float orientatio int BIF_countTransformOrientation(const struct bContext *C); -void BIF_TransformSetUndo(const char *str); - /* to be able to add operator properties to other operators */ #define P_MIRROR (1 << 0) diff --git a/source/blender/editors/include/ED_transverts.h b/source/blender/editors/include/ED_transverts.h new file mode 100644 index 00000000000..a82e54e425b --- /dev/null +++ b/source/blender/editors/include/ED_transverts.h @@ -0,0 +1,70 @@ +/* + * ***** 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. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file ED_transverts.h + * \ingroup editors + */ + +#ifndef __ED_TRANSVERTS_H__ +#define __ED_TRANSVERTS_H__ + +struct Object; + +typedef struct TransVert { + float *loc; + float oldloc[3], maploc[3]; + float *val, oldval; + int flag; +} TransVert; + +typedef struct TransVertStore { + struct TransVert *transverts; + int transverts_tot; +} TransVertStore; + +void ED_transverts_create_from_obedit(TransVertStore *tvs, struct Object *obedit, int mode); +void ED_transverts_update_obedit(TransVertStore *tvs, struct Object *obedit); +void ED_transverts_free(TransVertStore *tvs); +bool ED_transverts_check_obedit(Object *obedit); + +/* currently only used for bmesh index values */ +enum { + TM_INDEX_ON = 1, /* tag to make trans verts */ + TM_INDEX_OFF = 0, /* don't make verts */ + TM_INDEX_SKIP = -1 /* dont make verts (when the index values point to trans-verts) */ +}; + +/* mode flags: */ +enum { + TM_ALL_JOINTS = 1, /* all joints (for bones only) */ + TM_SKIP_HANDLES = 2 /* skip handles when control point is selected (for curves only) */ +}; + + + /* SELECT == (1 << 0) */ +#define TX_VERT_USE_MAPLOC (1 << 1) + +#endif /* __ED_TRANSVERTS_H__ */ diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 86abf29c308..0f3106794f5 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -82,8 +82,8 @@ typedef struct ViewDepths { bool damaged; } ViewDepths; -float *give_cursor(struct Scene *scene, struct View3D *v3d); -void ED_view3d_cursor3d_position(struct bContext *C, float fp[3], const int mval[2]); +float *ED_view3d_cursor3d_get(struct Scene *scene, struct View3D *v3d); +void ED_view3d_cursor3d_position(struct bContext *C, float fp[3], const int mval[2]); void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist); void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist); @@ -328,6 +328,8 @@ float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float float ED_scene_grid_scale(struct Scene *scene, const char **grid_unit); float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit); +void ED_scene_draw_fps(struct Scene *scene, struct rcti *rect); + /* view matrix properties utilities */ /* unused */ #if 0 diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 38aad640ee1..0c37d35a93b 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -93,7 +93,7 @@ typedef struct uiLayout uiLayout; /* use for clamping popups within the screen */ #define UI_SCREEN_MARGIN 10 -/* uiBlock->dt */ +/* uiBlock->dt and uiBut->dt */ #define UI_EMBOSS 0 /* use widget style for drawing */ #define UI_EMBOSSN 1 /* Nothing, only icon and/or text */ #define UI_EMBOSSP 2 /* Pulldown menu style */ @@ -130,8 +130,7 @@ typedef struct uiLayout uiLayout; #define UI_BLOCK_POPUP_MEMORY (1 << 12) #define UI_BLOCK_CLIP_EVENTS (1 << 13) /* stop handling mouse events */ -/* XXX This comment is no more valid! Maybe it is now bits 14-17? */ -/* block->flag bits 12-15 are identical to but->flag bits */ +/* block->flag bits 14-17 are identical to but->drawflag bits */ #define UI_BLOCK_LIST_ITEM (1 << 19) @@ -148,46 +147,55 @@ typedef struct uiLayout uiLayout; #define UI_PNL_CLOSE (1 << 5) #define UI_PNL_SCALE (1 << 9) -/* warning the first 6 flags are internal */ -/* but->flag */ -#define UI_TEXT_LEFT (1 << 6) -#define UI_ICON_LEFT (1 << 7) -#define UI_ICON_SUBMENU (1 << 8) -#define UI_ICON_PREVIEW (1 << 9) - -#define UI_TEXT_RIGHT (1 << 10) -#define UI_BUT_NODE_LINK (1 << 11) -#define UI_BUT_NODE_ACTIVE (1 << 12) -#define UI_BUT_DRAG_LOCK (1 << 13) - -/* button align flag, for drawing groups together */ -#define UI_BUT_ALIGN (UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_LEFT | UI_BUT_ALIGN_RIGHT | UI_BUT_ALIGN_DOWN) -#define UI_BUT_ALIGN_TOP (1 << 14) -#define UI_BUT_ALIGN_LEFT (1 << 15) -#define UI_BUT_ALIGN_RIGHT (1 << 16) -#define UI_BUT_ALIGN_DOWN (1 << 17) - -#define UI_BUT_DISABLED (1 << 18) -#define UI_BUT_COLOR_LOCK (1 << 19) -#define UI_BUT_ANIMATED (1 << 20) -#define UI_BUT_ANIMATED_KEY (1 << 21) -#define UI_BUT_DRIVEN (1 << 22) -#define UI_BUT_REDALERT (1 << 23) -#define UI_BUT_INACTIVE (1 << 24) -#define UI_BUT_LAST_ACTIVE (1 << 25) -#define UI_BUT_UNDO (1 << 26) -#define UI_BUT_IMMEDIATE (1 << 27) -#define UI_BUT_NO_TOOLTIP (1 << 28) -#define UI_BUT_NO_UTF8 (1 << 29) - -#define UI_BUT_VEC_SIZE_LOCK (1 << 30) /* used to flag if color hsv-circle should keep luminance */ -#define UI_BUT_COLOR_CUBIC (1 << 31) /* cubic saturation for the color wheel */ +/* but->flag - general state flags. */ +enum { + /* warning, the first 6 flags are internal */ + UI_ICON_SUBMENU = (1 << 6), + UI_ICON_PREVIEW = (1 << 7), + + UI_BUT_NODE_LINK = (1 << 8), + UI_BUT_NODE_ACTIVE = (1 << 9), + UI_BUT_DRAG_LOCK = (1 << 10), + UI_BUT_DISABLED = (1 << 11), + UI_BUT_COLOR_LOCK = (1 << 12), + UI_BUT_ANIMATED = (1 << 13), + UI_BUT_ANIMATED_KEY = (1 << 14), + UI_BUT_DRIVEN = (1 << 15), + UI_BUT_REDALERT = (1 << 16), + UI_BUT_INACTIVE = (1 << 17), + UI_BUT_LAST_ACTIVE = (1 << 18), + UI_BUT_UNDO = (1 << 19), + UI_BUT_IMMEDIATE = (1 << 20), + UI_BUT_NO_UTF8 = (1 << 21), + + UI_BUT_VEC_SIZE_LOCK = (1 << 22), /* used to flag if color hsv-circle should keep luminance */ + UI_BUT_COLOR_CUBIC = (1 << 23), /* cubic saturation for the color wheel */ + UI_BUT_LIST_ITEM = (1 << 24), /* This but is "inside" a list item (currently used to change theme colors). */ +}; #define UI_PANEL_WIDTH 340 #define UI_COMPACT_PANEL_WIDTH 160 -/* uiBut->drawflag */ -#define UI_BUT_DRAW_ENUM_ARROWS (1 << 0) /* draw enum-like up/down arrows for button */ +/* but->drawflag - these flags should only affect how the button is drawn. */ +/* Note: currently, these flags _are not passed_ to the widget's state() or draw() functions + * (except for the 'align' ones)! + */ +enum { + /* draw enum-like up/down arrows for button */ + UI_BUT_DRAW_ENUM_ARROWS = (1 << 0), + /* Text and icon alignment (by default, they are centered). */ + UI_BUT_TEXT_LEFT = (1 << 1), + UI_BUT_ICON_LEFT = (1 << 2), + UI_BUT_TEXT_RIGHT = (1 << 3), + /* Prevent the button to show any tooltip. */ + UI_BUT_NO_TOOLTIP = (1 << 4), + /* button align flag, for drawing groups together (also used in uiBlock->flag!) */ + UI_BUT_ALIGN_TOP = (1 << 14), + UI_BUT_ALIGN_LEFT = (1 << 15), + UI_BUT_ALIGN_RIGHT = (1 << 16), + UI_BUT_ALIGN_DOWN = (1 << 17), + UI_BUT_ALIGN = (UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_LEFT | UI_BUT_ALIGN_RIGHT | UI_BUT_ALIGN_DOWN), +}; /* scale fixed button widths by this to account for DPI */ @@ -259,7 +267,6 @@ typedef enum { PROGRESSBAR = (51 << 9), SEARCH_MENU_UNLINK = (52 << 9), NODESOCKET = (53 << 9), - LISTLABEL = (54 << 9), } eButType; #define BUTTYPE (63 << 9) @@ -641,9 +648,13 @@ void uiButSetFocusOnEnter(struct wmWindow *win, uiBut *but); typedef struct AutoComplete AutoComplete; +#define AUTOCOMPLETE_NO_MATCH 0 +#define AUTOCOMPLETE_FULL_MATCH 1 +#define AUTOCOMPLETE_PARTIAL_MATCH 2 + AutoComplete *autocomplete_begin(const char *startname, size_t maxlen); void autocomplete_do_name(AutoComplete *autocpl, const char *name); -bool autocomplete_end(AutoComplete *autocpl, char *autoname); +int autocomplete_end(AutoComplete *autocpl, char *autoname); /* Panels * diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 3bad2577409..3f48446f029 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -78,8 +78,8 @@ #include "interface_intern.h" -#define PRECISION_FLOAT_MAX 6 -#define PRECISION_FLOAT_MAX_POW 1000000 /* pow(10, PRECISION_FLOAT_MAX) */ +#define PRECISION_FLOAT_MAX 7 +#define PRECISION_FLOAT_MAX_POW 10000000 /* pow(10, PRECISION_FLOAT_MAX) */ /* avoid unneeded calls to ui_get_but_val */ #define UI_BUT_VALUE_UNSET DBL_MAX @@ -443,7 +443,7 @@ void uiExplicitBoundsBlock(uiBlock *block, int minx, int miny, int maxx, int max static int ui_but_float_precision(uiBut *but, double value) { int prec; - const double pow10_neg[PRECISION_FLOAT_MAX + 1] = {1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001}; + const double pow10_neg[PRECISION_FLOAT_MAX + 1] = {1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001}; /* first check if prec is 0 and fallback to a simple default */ if ((prec = (int)but->a2) == -1) { @@ -613,6 +613,7 @@ static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut { /* flags from the buttons we want to refresh, may want to add more here... */ const int flag_copy = UI_BUT_REDALERT; + const int drawflag_copy = 0; /* None currently. */ uiBlock *oldblock; uiBut *oldbut, *but = *butpp; @@ -670,8 +671,9 @@ static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut SWAP(char *, oldbut->poin, but->poin); SWAP(void *, oldbut->func_argN, but->func_argN); } - + oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy); + oldbut->drawflag = (oldbut->drawflag & ~drawflag_copy) | (but->drawflag & drawflag_copy); /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position * when scrolling without moving mouse (see [#28432]) */ @@ -2604,7 +2606,7 @@ static void ui_block_do_align_but(uiBut *first, short nr) next = NULL; /* clear old flag */ - but->flag &= ~UI_BUT_ALIGN; + but->drawflag &= ~UI_BUT_ALIGN; if (flag == 0) { /* first case */ if (next) { @@ -2683,7 +2685,7 @@ static void ui_block_do_align_but(uiBut *first, short nr) } } - but->flag |= flag; + but->drawflag |= flag; /* merge coordinates */ if (prev) { @@ -2863,10 +2865,10 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, if ((block->flag & UI_BLOCK_LOOP) || ELEM8(but->type, MENU, TEX, LABEL, BLOCK, BUTM, SEARCH_MENU, PROGRESSBAR, SEARCH_MENU_UNLINK)) { - but->flag |= (UI_TEXT_LEFT | UI_ICON_LEFT); + but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT); } - but->flag |= (block->flag & UI_BUT_ALIGN); + but->drawflag |= (block->flag & UI_BUT_ALIGN); if (but->lock == TRUE) { if (but->lockstr) { @@ -3041,7 +3043,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s if (icon) { but->icon = (BIFIconID)icon; but->flag |= UI_HAS_ICON; - but->flag |= UI_ICON_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT; } if (!RNA_property_editable(&but->rnapoin, prop)) { @@ -3158,9 +3160,14 @@ uiBut *uiDefBut(uiBlock *block, int type, int retval, const char *str, int x, in return but; } -/* if _x_ is a power of two (only one bit) return the power, +/** + * if \a _x_ is a power of two (only one bit) return the power, * otherwise return -1. - * (1<<findBitIndex(x))==x for powers of two. + * + * for powers of two: + * \code{.c} + * ((1 << findBitIndex(x)) == x); + * \endcode */ static int findBitIndex(unsigned int x) { @@ -3183,6 +3190,7 @@ static int findBitIndex(unsigned int x) /* autocomplete helper functions */ struct AutoComplete { size_t maxlen; + int matches; char *truncate; const char *startname; }; @@ -3193,6 +3201,7 @@ AutoComplete *autocomplete_begin(const char *startname, size_t maxlen) autocpl = MEM_callocN(sizeof(AutoComplete), "AutoComplete"); autocpl->maxlen = maxlen; + autocpl->matches = 0; autocpl->truncate = MEM_callocN(sizeof(char) * maxlen, "AutoCompleteTruncate"); autocpl->startname = startname; @@ -3211,6 +3220,7 @@ void autocomplete_do_name(AutoComplete *autocpl, const char *name) } /* found a match */ if (startname[a] == 0) { + autocpl->matches++; /* first match */ if (truncate[0] == 0) BLI_strncpy(truncate, name, autocpl->maxlen); @@ -3228,21 +3238,27 @@ void autocomplete_do_name(AutoComplete *autocpl, const char *name) } } -bool autocomplete_end(AutoComplete *autocpl, char *autoname) +int autocomplete_end(AutoComplete *autocpl, char *autoname) { - bool change = false; + int match = AUTOCOMPLETE_NO_MATCH; if (autocpl->truncate[0]) { + if (autocpl->matches == 1) { + match = AUTOCOMPLETE_FULL_MATCH; + } + else { + match = AUTOCOMPLETE_PARTIAL_MATCH; + } BLI_strncpy(autoname, autocpl->truncate, autocpl->maxlen); - change = true; } else { if (autoname != autocpl->startname) { /* don't copy a string over its self */ BLI_strncpy(autoname, autocpl->startname, autocpl->maxlen); } } + MEM_freeN(autocpl->truncate); MEM_freeN(autocpl); - return change; + return match; } static void ui_check_but_and_iconize(uiBut *but, int icon) @@ -3416,7 +3432,7 @@ uiBut *uiDefIconTextBut(uiBlock *block, int type, int retval, int icon, const ch { uiBut *but = ui_def_but(block, type, retval, str, x, y, width, height, poin, min, max, a1, a2, tip); ui_check_but_and_iconize(but, icon); - but->flag |= UI_ICON_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT; return but; } static uiBut *uiDefIconTextButBit(uiBlock *block, int type, int bit, int retval, int icon, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) @@ -3467,7 +3483,7 @@ uiBut *uiDefIconTextButR(uiBlock *block, int type, int retval, int icon, const c uiBut *but; but = ui_def_but_rna_propname(block, type, retval, str, x, y, width, height, ptr, propname, index, min, max, a1, a2, tip); ui_check_but_and_iconize(but, icon); - but->flag |= UI_ICON_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT; return but; } uiBut *uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) @@ -3475,7 +3491,7 @@ uiBut *uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, co uiBut *but; but = ui_def_but_rna(block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip); ui_check_but_and_iconize(but, icon); - but->flag |= UI_ICON_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT; return but; } uiBut *uiDefIconTextButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext, int icon, const char *str, int x, int y, short width, short height, const char *tip) @@ -3483,7 +3499,7 @@ uiBut *uiDefIconTextButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int o uiBut *but; but = ui_def_but_operator_ptr(block, type, ot, opcontext, str, x, y, width, height, tip); ui_check_but_and_iconize(but, icon); - but->flag |= UI_ICON_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT; return but; } uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x, int y, short width, short height, const char *tip) @@ -3539,7 +3555,7 @@ void uiBlockFlipOrder(uiBlock *block) return; for (but = block->buttons.first; but; but = but->next) { - if (but->flag & UI_BUT_ALIGN) return; + if (but->drawflag & UI_BUT_ALIGN) return; if (but->rect.ymin < miny) miny = but->rect.ymin; if (but->rect.ymax > maxy) maxy = but->rect.ymax; } @@ -3780,7 +3796,7 @@ uiBut *uiDefIconTextMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, in but->icon = (BIFIconID) icon; but->flag |= UI_HAS_ICON; - but->flag |= UI_ICON_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT; but->flag |= UI_ICON_SUBMENU; but->menu_create_func = func; @@ -3795,7 +3811,7 @@ uiBut *uiDefIconMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int ic but->icon = (BIFIconID) icon; but->flag |= UI_HAS_ICON; - but->flag &= ~UI_ICON_LEFT; + but->drawflag &= ~UI_BUT_ICON_LEFT; but->menu_create_func = func; ui_check_but(but); @@ -3811,7 +3827,7 @@ uiBut *uiDefIconTextBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, /* XXX temp, old menu calls pass on icon arrow, which is now UI_ICON_SUBMENU flag */ if (icon != ICON_RIGHTARROW_THIN) { but->icon = (BIFIconID) icon; - but->flag |= UI_ICON_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT; } but->flag |= UI_HAS_ICON; but->flag |= UI_ICON_SUBMENU; @@ -3830,7 +3846,7 @@ uiBut *uiDefIconBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int but->icon = (BIFIconID) icon; but->flag |= UI_HAS_ICON; - but->flag |= UI_ICON_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT; but->block_create_func = func; ui_check_but(but); @@ -3865,7 +3881,7 @@ uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxle but->icon = (BIFIconID) icon; but->flag |= UI_HAS_ICON; - but->flag |= UI_ICON_LEFT | UI_TEXT_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT; ui_check_but(but); @@ -4186,5 +4202,6 @@ void UI_reinit_font(void) void UI_exit(void) { ui_resources_free(); + ui_button_clipboard_free(); } diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c index 783a777a2fe..a01c7eecda1 100644 --- a/source/blender/editors/interface/interface_eyedropper.c +++ b/source/blender/editors/interface/interface_eyedropper.c @@ -122,10 +122,9 @@ static void eyedropper_exit(bContext *C, wmOperator *op) } } -static int eyedropper_cancel(bContext *C, wmOperator *op) +static void eyedropper_cancel(bContext *C, wmOperator *op) { eyedropper_exit(C, op); - return OPERATOR_CANCELLED; } /* *** eyedropper_color_ helper functions *** */ @@ -243,7 +242,8 @@ static int eyedropper_modal(bContext *C, wmOperator *op, const wmEvent *event) switch (event->type) { case ESCKEY: case RIGHTMOUSE: - return eyedropper_cancel(C, op); + eyedropper_cancel(C, op); + return OPERATOR_CANCELLED; case LEFTMOUSE: if (event->val == KM_RELEASE) { if (eye->accum_tot == 0) { @@ -439,7 +439,9 @@ static void datadropper_exit(bContext *C, wmOperator *op) if (op->customdata) { DataDropper *ddr = (DataDropper *)op->customdata; - ED_region_draw_cb_exit(ddr->art, ddr->draw_handle_pixel); + if (ddr->art) { + ED_region_draw_cb_exit(ddr->art, ddr->draw_handle_pixel); + } MEM_freeN(op->customdata); @@ -447,10 +449,9 @@ static void datadropper_exit(bContext *C, wmOperator *op) } } -static int datadropper_cancel(bContext *C, wmOperator *op) +static void datadropper_cancel(bContext *C, wmOperator *op) { datadropper_exit(C, op); - return OPERATOR_CANCELLED; } /* *** datadropper id helper functions *** */ @@ -552,7 +553,8 @@ static int datadropper_modal(bContext *C, wmOperator *op, const wmEvent *event) switch (event->type) { case ESCKEY: case RIGHTMOUSE: - return datadropper_cancel(C, op); + datadropper_cancel(C, op); + return OPERATOR_CANCELLED; case LEFTMOUSE: if (event->val == KM_RELEASE) { bool success; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index c5faa99e067..db53809c7c4 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -242,7 +242,29 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *userd static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type); static void button_timers_tooltip_remove(bContext *C, uiBut *but); +/* buttons clipboard */ +static ColorBand but_copypaste_coba = {0}; +static CurveMapping but_copypaste_curve = {0}; +static bool but_copypaste_curve_alive = false; + /* ******************** menu navigation helpers ************** */ +enum eSnapType { + SNAP_OFF = 0, + SNAP_ON, + SNAP_ON_SMALL, +}; + +static enum eSnapType ui_event_to_snap(const wmEvent *event) +{ + return (event->ctrl) ? (event->shift) ? SNAP_ON_SMALL : SNAP_ON : SNAP_OFF; +} + +static void ui_color_snap_hue(const enum eSnapType snap, float *r_hue) +{ + const float snap_increment = (snap == SNAP_ON_SMALL) ? 24 : 12; + BLI_assert(snap != SNAP_OFF); + *r_hue = floorf(0.5f + ((*r_hue) * snap_increment)) / snap_increment; +} /* assumes event type is MOUSEPAN */ void ui_pan_to_scroll(const wmEvent *event, int *type, int *val) @@ -279,7 +301,7 @@ void ui_pan_to_scroll(const wmEvent *event, int *type, int *val) static bool ui_but_editable(uiBut *but) { - return ELEM6(but->type, LABEL, LISTLABEL, SEPR, ROUNDBOX, LISTBOX, PROGRESSBAR); + return ELEM5(but->type, LABEL, SEPR, ROUNDBOX, LISTBOX, PROGRESSBAR); } static uiBut *ui_but_prev(uiBut *but) @@ -335,7 +357,7 @@ static bool ui_is_a_warp_but(uiBut *but) return false; } -static float ui_mouse_scale_warp_factor(const short shift) +static float ui_mouse_scale_warp_factor(const bool shift) { return shift ? 0.05f : 1.0f; } @@ -343,7 +365,7 @@ static float ui_mouse_scale_warp_factor(const short shift) static void ui_mouse_scale_warp(uiHandleButtonData *data, const float mx, const float my, float *r_mx, float *r_my, - const short shift) + const bool shift) { const float fac = ui_mouse_scale_warp_factor(shift); @@ -837,6 +859,13 @@ static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void } } +static bool ui_is_but_drag_toggle(uiBut *but) +{ + return ((ui_is_but_bool(but) == true) && + /* menu check is importnt so the button dragged over isn't removed instantly */ + (ui_block_is_menu(but->block) == false)); +} + #endif /* USE_DRAG_TOGGLE */ @@ -852,7 +881,7 @@ static bool ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, const wmEvent *eve if (but->imb) { /* use button size itself */ } - else if (but->flag & UI_ICON_LEFT) { + else if (but->drawflag & UI_BUT_ICON_LEFT) { rect.xmax = rect.xmin + (BLI_rcti_size_y(&rect)); } else { @@ -1324,7 +1353,6 @@ static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleB /* c = copy, v = paste */ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, char mode) { - static ColorBand but_copypaste_coba = {0}; char buf[UI_MAX_DRAW_STR + 1] = {0}; if (mode == 'v' && but->lock == TRUE) { @@ -1372,6 +1400,32 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, } } + /* NORMAL button */ + else if (but->type == BUT_NORMAL) { + float xyz[3]; + + if (but->poin == NULL && but->rnapoin.data == NULL) { + /* pass */ + } + else if (mode == 'c') { + ui_get_but_vectorf(but, xyz); + BLI_snprintf(buf, sizeof(buf), "[%f, %f, %f]", xyz[0], xyz[1], xyz[2]); + WM_clipboard_text_set(buf, 0); + } + else { + if (sscanf(buf, "[%f, %f, %f]", &xyz[0], &xyz[1], &xyz[2]) == 3) { + if (normalize_v3(xyz) == 0.0f) { + /* better set Z up then have a zero vector */ + xyz[2] = 1.0; + } + button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); + ui_set_but_vectorf(but, xyz); + button_activate_state(C, but, BUTTON_STATE_EXIT); + } + } + } + + /* RGB triple */ else if (but->type == COLOR) { float rgba[4]; @@ -1458,6 +1512,28 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, button_activate_state(C, but, BUTTON_STATE_EXIT); } } + else if (but->type == BUT_CURVE) { + if (mode == 'c') { + if (but->poin == NULL) + return; + + but_copypaste_curve_alive = true; + curvemapping_free_data(&but_copypaste_curve); + curvemapping_copy_data(&but_copypaste_curve, (CurveMapping *) but->poin); + } + else { + if (!but_copypaste_curve_alive) + return; + + if (!but->poin) + but->poin = MEM_callocN(sizeof(CurveMapping), "curvemapping"); + + button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); + curvemapping_free_data((CurveMapping *) but->poin); + curvemapping_copy_data((CurveMapping *) but->poin, &but_copypaste_curve); + button_activate_state(C, but, BUTTON_STATE_EXIT); + } + } /* operator button (any type) */ else if (but->optype) { if (mode == 'c') { @@ -1465,7 +1541,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, char *str; opptr = uiButGetOperatorPtrRNA(but); /* allocated when needed, the button owns it */ - str = WM_operator_pystring(C, but->optype, opptr, 0); + str = WM_operator_pystring_ex(C, NULL, false, but->optype, opptr); WM_clipboard_text_set(str, 0); @@ -1716,7 +1792,7 @@ static bool ui_textedit_type_ascii(uiBut *but, uiHandleButtonData *data, char as } static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, strCursorJumpDirection direction, - int select, strCursorJumpType jump) + const bool select, strCursorJumpType jump) { const char *str = data->str; const int len = strlen(str); @@ -2021,7 +2097,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa uiBut *but; /* label and roundbox can overlap real buttons (backdrops...) */ - if (ELEM5(actbut->type, LABEL, LISTLABEL, SEPR, ROUNDBOX, LISTBOX)) + if (ELEM4(actbut->type, LABEL, SEPR, ROUNDBOX, LISTBOX)) return; for (but = actbut->next; but; but = but->next) { @@ -2049,7 +2125,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa uiBut *but; /* label and roundbox can overlap real buttons (backdrops...) */ - if (ELEM5(actbut->type, LABEL, LISTLABEL, SEPR, ROUNDBOX, LISTBOX)) + if (ELEM4(actbut->type, LABEL, SEPR, ROUNDBOX, LISTBOX)) return; for (but = actbut->prev; but; but = but->prev) { @@ -2137,7 +2213,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle /* only select a word in button if there was no selection before */ if (event->val == KM_DBL_CLICK && had_selection == false) { - ui_textedit_move(but, data, STRCUR_DIR_PREV, 0, STRCUR_JUMP_DELIM); + ui_textedit_move(but, data, STRCUR_DIR_PREV, false, STRCUR_JUMP_DELIM); ui_textedit_move(but, data, STRCUR_DIR_NEXT, true, STRCUR_JUMP_DELIM); retval = WM_UI_HANDLER_BREAK; changed = true; @@ -2171,12 +2247,12 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle break; case RIGHTARROWKEY: ui_textedit_move(but, data, STRCUR_DIR_NEXT, - event->shift, event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE); + event->shift != 0, event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE); retval = WM_UI_HANDLER_BREAK; break; case LEFTARROWKEY: ui_textedit_move(but, data, STRCUR_DIR_PREV, - event->shift, event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE); + event->shift != 0, event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE); retval = WM_UI_HANDLER_BREAK; break; case WHEELDOWNMOUSE: @@ -2191,7 +2267,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle /* fall-through */ case ENDKEY: ui_textedit_move(but, data, STRCUR_DIR_NEXT, - event->shift, STRCUR_JUMP_ALL); + event->shift != 0, STRCUR_JUMP_ALL); retval = WM_UI_HANDLER_BREAK; break; case WHEELUPMOUSE: @@ -2206,7 +2282,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle /* fall-through */ case HOMEKEY: ui_textedit_move(but, data, STRCUR_DIR_PREV, - event->shift, STRCUR_JUMP_ALL); + event->shift != 0, STRCUR_JUMP_ALL); retval = WM_UI_HANDLER_BREAK; break; case PADENTER: @@ -2648,7 +2724,9 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { /* unlink icon is on right */ - if (ELEM4(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS) { + if (ELEM4(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS && + ui_is_but_search_unlink_visible(but)) + { ARegion *ar = data->region; rcti rect; int x = event->x, y = event->y; @@ -2659,9 +2737,14 @@ static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHa rect.xmin = rect.xmax - (BLI_rcti_size_y(&rect)); if (BLI_rcti_isect_pt(&rect, x, y)) { - ui_set_but_string(C, but, ""); + /* most likely NULL, but let's check, and give it temp zero string */ + if (data->str == NULL) + data->str = MEM_callocN(1, "temp str"); + data->str[0] = 0; + + ui_apply_but_TEX(C, but, data); button_activate_state(C, but, BUTTON_STATE_EXIT); - + return WM_UI_HANDLER_BREAK; } } @@ -2672,7 +2755,7 @@ static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, cons { #ifdef USE_DRAG_TOGGLE if (data->state == BUTTON_STATE_HIGHLIGHT) { - if (event->type == LEFTMOUSE && event->val == KM_PRESS && ui_is_but_bool(but)) { + if (event->type == LEFTMOUSE && event->val == KM_PRESS && ui_is_but_drag_toggle(but)) { #if 0 /* UNUSED */ data->togdual = event->ctrl; data->togonly = !event->shift; @@ -2721,7 +2804,7 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, con } } #ifdef USE_DRAG_TOGGLE - if (event->type == LEFTMOUSE && ui_is_but_bool(but)) { + if (event->type == LEFTMOUSE && ui_is_but_drag_toggle(but)) { button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG); data->dragstartx = event->x; data->dragstarty = event->y; @@ -2763,9 +2846,10 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, con } /* var names match ui_numedit_but_NUM */ -static float ui_numedit_apply_snapf(uiBut *but, float tempf, float softmin, float softmax, float softrange, int snap) +static float ui_numedit_apply_snapf(uiBut *but, float tempf, float softmin, float softmax, float softrange, + const enum eSnapType snap) { - if (tempf == softmin || tempf == softmax || snap == 0) { + if (tempf == softmin || tempf == softmax || snap == SNAP_OFF) { /* pass */ } else { @@ -2791,16 +2875,19 @@ static float ui_numedit_apply_snapf(uiBut *but, float tempf, float softmin, floa softrange /= fac; } - if (snap == 1) { + if (snap == SNAP_ON) { if (softrange < 2.10f) tempf = 0.1f * floorf(10.0f * tempf); else if (softrange < 21.0f) tempf = floorf(tempf); else tempf = 10.0f * floorf(tempf / 10.0f); } - else if (snap == 2) { + else if (snap == SNAP_ON_SMALL) { if (softrange < 2.10f) tempf = 0.01f * floorf(100.0f * tempf); else if (softrange < 21.0f) tempf = 0.1f * floorf(10.0f * tempf); else tempf = floor(tempf); } + else { + BLI_assert(0); + } if (fac != 1.0f) tempf *= fac; @@ -2809,18 +2896,19 @@ static float ui_numedit_apply_snapf(uiBut *but, float tempf, float softmin, floa return tempf; } -static float ui_numedit_apply_snap(int temp, float softmin, float softmax, int snap) +static float ui_numedit_apply_snap(int temp, float softmin, float softmax, + const enum eSnapType snap) { if (temp == softmin || temp == softmax) return temp; switch (snap) { - case 0: + case SNAP_OFF: break; - case 1: + case SNAP_ON: temp = 10 * (temp / 10); break; - case 2: + case SNAP_ON_SMALL: temp = 100 * (temp / 100); break; } @@ -2828,7 +2916,9 @@ static float ui_numedit_apply_snap(int temp, float softmin, float softmax, int s return temp; } -static bool ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, int snap, int mx) +static bool ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, + int mx, + const enum eSnapType snap, float fac) { float deler, tempf, softmin, softmax, softrange; int lvalue, temp; @@ -3037,16 +3127,14 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton click = 1; } else if (event->type == MOUSEMOVE) { + const enum eSnapType snap = ui_event_to_snap(event); float fac; - int snap; fac = 1.0f; if (event->shift) fac /= 10.0f; if (event->alt) fac /= 20.0f; - - snap = (event->ctrl) ? (event->shift) ? 2 : 1 : 0; - if (ui_numedit_but_NUM(but, data, fac, snap, (ui_is_a_warp_but(but) ? screen_mx : mx))) + if (ui_numedit_but_NUM(but, data, (ui_is_a_warp_but(but) ? screen_mx : mx), snap, fac)) ui_numedit_apply(C, block, but, data); } retval = WM_UI_HANDLER_BREAK; @@ -3127,7 +3215,8 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton } static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, - const bool is_horizontal, const bool shift, const bool ctrl, int mx) + int mx, const bool is_horizontal, + const bool snap, const bool shift) { float deler, f, tempf, softmin, softmax, softrange; int temp, lvalue; @@ -3182,7 +3271,7 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, tempf = softmin + f * softrange; temp = floorf(tempf + 0.5f); - if (ctrl) { + if (snap) { if (tempf == softmin || tempf == softmax) { /* pass */ } @@ -3303,7 +3392,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton click = 1; } else if (event->type == MOUSEMOVE) { - if (ui_numedit_but_SLI(but, data, true, event->shift, event->ctrl, mx)) + if (ui_numedit_but_SLI(but, data, mx, true, event->ctrl != 0, event->shift != 0)) ui_numedit_apply(C, block, but, data); } retval = WM_UI_HANDLER_BREAK; @@ -3419,7 +3508,7 @@ static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut button_activate_state(C, but, BUTTON_STATE_EXIT); } else if (event->type == MOUSEMOVE) { - if (ui_numedit_but_SLI(but, data, horizontal, false, false, (horizontal) ? mx : my)) + if (ui_numedit_but_SLI(but, data, (horizontal) ? mx : my, horizontal, false, false)) ui_numedit_apply(C, block, but, data); } @@ -3541,7 +3630,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co } } #ifdef USE_DRAG_TOGGLE - if (event->type == LEFTMOUSE && ui_is_but_bool(but)) { + if (event->type == LEFTMOUSE && ui_is_but_drag_toggle(but)) { button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG); data->dragstartx = event->x; data->dragstarty = event->y; @@ -3610,7 +3699,9 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co return WM_UI_HANDLER_CONTINUE; } -static bool ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data, int mx, int my) +static bool ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data, + int mx, int my, + const enum eSnapType snap) { float dx, dy, rad, radsq, mrad, *fp; int mdx, mdy; @@ -3666,6 +3757,23 @@ static bool ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data, int mx, } normalize_v3(fp); + if (snap != SNAP_OFF) { + const int snap_steps = (snap == SNAP_ON) ? 4 : 12; /* 45 or 15 degree increments */ + const float snap_steps_angle = M_PI / snap_steps; + float angle, angle_snap; + int i; + + /* round each axis of 'fp' to the next increment + * do this in "angle" space - this gives increments of same size */ + for (i = 0; i < 3; i++) { + angle = asinf(fp[i]); + angle_snap = floorf(0.5f + (angle / snap_steps_angle)) * snap_steps_angle; + fp[i] = sinf(angle_snap); + } + normalize_v3(fp); + changed = !compare_v3v3(fp, data->origvec, FLT_EPSILON); + } + data->draglastx = mx; data->draglasty = my; @@ -3717,6 +3825,7 @@ static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut if (data->state == BUTTON_STATE_HIGHLIGHT) { if (event->type == LEFTMOUSE && event->val == KM_PRESS) { + const enum eSnapType snap = ui_event_to_snap(event); data->dragstartx = mx; data->dragstarty = my; data->draglastx = mx; @@ -3724,7 +3833,7 @@ static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); /* also do drag the first time */ - if (ui_numedit_but_NORMAL(but, data, mx, my)) + if (ui_numedit_but_NORMAL(but, data, mx, my, snap)) ui_numedit_apply(C, block, but, data); return WM_UI_HANDLER_BREAK; @@ -3733,7 +3842,8 @@ static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut else if (data->state == BUTTON_STATE_NUM_EDITING) { if (event->type == MOUSEMOVE) { if (mx != data->draglastx || my != data->draglasty) { - if (ui_numedit_but_NORMAL(but, data, mx, my)) + const enum eSnapType snap = ui_event_to_snap(event); + if (ui_numedit_but_NORMAL(but, data, mx, my, snap)) ui_numedit_apply(C, block, but, data); } } @@ -3760,15 +3870,17 @@ static void clamp_axis_max_v3(float v[3], const float max) } } -static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, int my, const short shift) +static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, + int mx, int my, + const enum eSnapType snap, const bool shift) { float rgb[3]; float *hsv = ui_block_hsv_get(but->block); float x, y; float mx_fl, my_fl; bool changed = true; - int color_profile = but->block->color_profile; - + bool use_display_colorspace = ui_hsvcube_use_display_colorspace(but); + ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift); #ifdef USE_CONT_MOUSE_CORRECT @@ -3780,14 +3892,9 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, } #endif - if (but->rnaprop) { - if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) - color_profile = FALSE; - } - ui_get_but_vectorf(but, rgb); - if (color_profile && (int)but->a1 != UI_GRAD_SV) + if (use_display_colorspace) ui_block_to_display_space_v3(but->block, rgb); rgb_to_hsv_compat_v(rgb, hsv); @@ -3801,7 +3908,7 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, /* calculate original hsv again */ copy_v3_v3(rgb, data->origvec); - if (color_profile && (int)but->a1 != UI_GRAD_SV) + if (use_display_colorspace) ui_block_to_display_space_v3(but->block, rgb); copy_v3_v3(hsvo, ui_block_hsv_get(but->block)); @@ -3854,9 +3961,15 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, break; } + if (snap != SNAP_OFF) { + if (ELEM3((int)but->a1, UI_GRAD_HV, UI_GRAD_HS, UI_GRAD_H)) { + ui_color_snap_hue(snap, &hsv[0]); + } + } + hsv_to_rgb_v(hsv, rgb); - if (color_profile && ((int)but->a1 != UI_GRAD_SV)) + if (use_display_colorspace) ui_block_to_scene_linear_v3(but->block, rgb); /* clamp because with color conversion we can exceed range [#34295] */ @@ -3872,22 +3985,18 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, return changed; } -static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, wmNDOFMotionData *ndof, const short shift) +static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, + wmNDOFMotionData *ndof, + const enum eSnapType snap, const bool shift) { float *hsv = ui_block_hsv_get(but->block); float rgb[3]; float sensitivity = (shift ? 0.15f : 0.3f) * ndof->dt; - - int color_profile = but->block->color_profile; - - if (but->rnaprop) { - if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) - color_profile = FALSE; - } + bool use_display_colorspace = ui_hsvcube_use_display_colorspace(but); ui_get_but_vectorf(but, rgb); - if (color_profile && (int)but->a1 != UI_GRAD_SV) + if (use_display_colorspace) ui_block_to_display_space_v3(but->block, rgb); rgb_to_hsv_compat_v(rgb, hsv); @@ -3927,9 +4036,15 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, wmNDOF break; } + if (snap != SNAP_OFF) { + if (ELEM3((int)but->a1, UI_GRAD_HV, UI_GRAD_HS, UI_GRAD_H)) { + ui_color_snap_hue(snap, &hsv[0]); + } + } + hsv_to_rgb_v(hsv, rgb); - if (color_profile && (int)but->a1 != UI_GRAD_SV) + if (use_display_colorspace) ui_block_to_scene_linear_v3(but->block, rgb); copy_v3_v3(data->vec, rgb); @@ -3946,6 +4061,8 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu if (data->state == BUTTON_STATE_HIGHLIGHT) { if (event->type == LEFTMOUSE && event->val == KM_PRESS) { + const enum eSnapType snap = ui_event_to_snap(event); + data->dragstartx = mx; data->dragstarty = my; data->draglastx = mx; @@ -3953,15 +4070,16 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); /* also do drag the first time */ - if (ui_numedit_but_HSVCUBE(but, data, mx, my, event->shift)) + if (ui_numedit_but_HSVCUBE(but, data, mx, my, snap, event->shift != 0)) ui_numedit_apply(C, block, but, data); return WM_UI_HANDLER_BREAK; } else if (event->type == NDOF_MOTION) { wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata; + const enum eSnapType snap = ui_event_to_snap(event); - ui_ndofedit_but_HSVCUBE(but, data, ndof, event->shift); + ui_ndofedit_but_HSVCUBE(but, data, ndof, snap, event->shift != 0); button_activate_state(C, but, BUTTON_STATE_EXIT); ui_apply_button(C, but->block, but, data, true); @@ -4012,7 +4130,9 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu } else if (event->type == MOUSEMOVE) { if (mx != data->draglastx || my != data->draglasty) { - if (ui_numedit_but_HSVCUBE(but, data, mx, my, event->shift)) + const enum eSnapType snap = ui_event_to_snap(event); + + if (ui_numedit_but_HSVCUBE(but, data, mx, my, snap, event->shift != 0)) ui_numedit_apply(C, block, but, data); } } @@ -4026,7 +4146,9 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu return WM_UI_HANDLER_CONTINUE; } -static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, float mx, float my, int shift) +static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, + float mx, float my, + const enum eSnapType snap, const bool shift) { rcti rect; bool changed = true; @@ -4084,6 +4206,10 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, float if (but->flag & UI_BUT_COLOR_CUBIC) hsv[1] = 1.0f - sqrt3f(1.0f - hsv[1]); + if (snap != SNAP_OFF) { + ui_color_snap_hue(snap, &hsv[0]); + } + hsv_to_rgb_v(hsv, rgb); if ((but->flag & UI_BUT_VEC_SIZE_LOCK) && (rgb[0] || rgb[1] || rgb[2])) { @@ -4099,7 +4225,9 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, float return changed; } -static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, wmNDOFMotionData *ndof, const short shift) +static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, + wmNDOFMotionData *ndof, + const enum eSnapType snap, const bool shift) { float *hsv = ui_block_hsv_get(but->block); float rgb[3]; @@ -4140,7 +4268,11 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, wmND if (but->flag & UI_BUT_COLOR_LOCK) { // lock if (hsv[2] == 0.0f) hsv[2] = 0.0001f; } - + + if (snap != SNAP_OFF) { + ui_color_snap_hue(snap, &hsv[0]); + } + hsv_to_rgb_v(hsv, data->vec); if ((but->flag & UI_BUT_VEC_SIZE_LOCK) && (data->vec[0] || data->vec[1] || data->vec[2])) { @@ -4161,6 +4293,7 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle if (data->state == BUTTON_STATE_HIGHLIGHT) { if (event->type == LEFTMOUSE && event->val == KM_PRESS) { + const enum eSnapType snap = ui_event_to_snap(event); data->dragstartx = mx; data->dragstarty = my; data->draglastx = mx; @@ -4168,15 +4301,16 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); /* also do drag the first time */ - if (ui_numedit_but_HSVCIRCLE(but, data, mx, my, event->shift)) + if (ui_numedit_but_HSVCIRCLE(but, data, mx, my, snap, event->shift != 0)) ui_numedit_apply(C, block, but, data); return WM_UI_HANDLER_BREAK; } else if (event->type == NDOF_MOTION) { + const enum eSnapType snap = ui_event_to_snap(event); wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata; - ui_ndofedit_but_HSVCIRCLE(but, data, ndof, event->shift); + ui_ndofedit_but_HSVCIRCLE(but, data, ndof, snap, event->shift != 0); button_activate_state(C, but, BUTTON_STATE_EXIT); ui_apply_button(C, but->block, but, data, true); @@ -4238,8 +4372,11 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle } else if (event->type == MOUSEMOVE) { if (mx != data->draglastx || my != data->draglasty) { - if (ui_numedit_but_HSVCIRCLE(but, data, mx, my, event->shift)) + const enum eSnapType snap = ui_event_to_snap(event); + + if (ui_numedit_but_HSVCIRCLE(but, data, mx, my, snap, event->shift != 0)) { ui_numedit_apply(C, block, but, data); + } } } else if (event->type == LEFTMOUSE && event->val != KM_PRESS) { @@ -4334,8 +4471,9 @@ static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiHandle return WM_UI_HANDLER_CONTINUE; } -static bool ui_numedit_but_CURVE(uiBlock *block, uiBut *but, uiHandleButtonData *data, int snap, - int evtx, int evty, const short shift) +static bool ui_numedit_but_CURVE(uiBlock *block, uiBut *but, uiHandleButtonData *data, + int evtx, int evty, + bool snap, const bool shift) { CurveMapping *cumap = (CurveMapping *)but->poin; CurveMap *cuma = cumap->cm + cumap->cur; @@ -4363,7 +4501,7 @@ static bool ui_numedit_but_CURVE(uiBlock *block, uiBut *but, uiHandleButtonData d[1] = my - data->dragstarty; if (len_v2(d) < 3.0f) - snap = 0; + snap = false; } if (data->dragsel != -1) { @@ -4558,7 +4696,7 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt if (event->type == MOUSEMOVE) { if (event->x != data->draglastx || event->y != data->draglasty) { - if (ui_numedit_but_CURVE(block, but, data, event->ctrl, event->x, event->y, event->shift)) + if (ui_numedit_but_CURVE(block, but, data, event->x, event->y, event->ctrl != 0, event->shift != 0)) ui_numedit_apply(C, block, but, data); } } @@ -4867,7 +5005,8 @@ static int ui_do_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data, con } static bool ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonData *data, - int mx, int my, const short shift) + int mx, int my, + const bool shift) { MovieClipScopes *scopes = (MovieClipScopes *)but->poin; bool changed = true; @@ -4923,7 +5062,7 @@ static int ui_do_but_TRACKPREVIEW(bContext *C, uiBlock *block, uiBut *but, uiHan button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); /* also do drag the first time */ - if (ui_numedit_but_TRACKPREVIEW(C, but, data, mx, my, event->shift)) + if (ui_numedit_but_TRACKPREVIEW(C, but, data, mx, my, event->shift != 0)) ui_numedit_apply(C, block, but, data); return WM_UI_HANDLER_BREAK; @@ -4939,7 +5078,7 @@ static int ui_do_but_TRACKPREVIEW(bContext *C, uiBlock *block, uiBut *but, uiHan } else if (event->type == MOUSEMOVE) { if (mx != data->draglastx || my != data->draglasty) { - if (ui_numedit_but_TRACKPREVIEW(C, but, data, mx, my, event->shift)) + if (ui_numedit_but_TRACKPREVIEW(C, but, data, mx, my, event->shift != 0)) ui_numedit_apply(C, block, but, data); } } @@ -5536,7 +5675,6 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * break; case ROUNDBOX: case LABEL: - case LISTLABEL: case ROW: case LISTROW: case BUT_IMAGE: @@ -5749,7 +5887,7 @@ static bool ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y) bool ui_is_but_interactive(uiBut *but) { /* note, LABEL is included for highlights, this allows drags */ - if (ELEM(but->type, LABEL, LISTLABEL) && but->dragpoin == NULL) + if ((but->type == LABEL) && but->dragpoin == NULL) return false; if (ELEM3(but->type, ROUNDBOX, SEPR, LISTBOX)) return false; @@ -5761,6 +5899,13 @@ bool ui_is_but_interactive(uiBut *but) return true; } +bool ui_is_but_search_unlink_visible(uiBut *but) +{ + BLI_assert(but->type == SEARCH_MENU_UNLINK); + return ((but->editstr == NULL) && + (but->drawstr[0] != '\0')); +} + uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y) { uiBlock *block; @@ -6572,6 +6717,8 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) // retval = WM_UI_HANDLER_BREAK; XXX why ? } + /* may have been re-allocated above (eyedropper for eg) */ + data = but->active; if (data->state == BUTTON_STATE_EXIT) { uiBut *post_but = data->postbut; uiButtonActivateType post_type = data->posttype; @@ -6635,7 +6782,7 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar) is_over_dragbut = true; } - if (is_over_dragbut && type == LEFTMOUSE && val == KM_PRESS) { + if (is_over_dragbut && type == LEFTMOUSE && val == KM_PRESS && !(but->flag & UI_BUT_DISABLED)) { uiHandleButtonData *data; int *size = (int *)but->poin; @@ -7296,7 +7443,7 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH for (but = block->buttons.first; but; but = but->next) { int doit = FALSE; - if (but->type != LABEL && but->type != LISTLABEL && but->type != SEPR) + if (!ELEM(but->type, LABEL, SEPR)) count++; /* exception for rna layer buts */ @@ -7842,3 +7989,7 @@ bool UI_textbutton_activate_event(const bContext *C, ARegion *ar, } } +void ui_button_clipboard_free(void) +{ + curvemapping_free_data(&but_copypaste_curve); +} diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 9cc16d82810..30d8535e471 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -95,7 +95,6 @@ typedef enum { UI_WTYPE_SCROLL, UI_WTYPE_LISTITEM, UI_WTYPE_PROGRESSBAR, - UI_WTYPE_LISTLABEL, } uiWidgetTypeEnum; /* menu scrolling */ @@ -108,13 +107,15 @@ typedef enum { #define UI_PANEL_MINY 70 /* uiBut->flag */ -#define UI_SELECT 1 /* use when the button is pressed */ -#define UI_SCROLLED 2 /* temp hidden, scrolled away */ -#define UI_ACTIVE 4 -#define UI_HAS_ICON 8 -#define UI_TEXTINPUT 16 -#define UI_HIDDEN 32 -/* warn: rest of uiBut->flag in UI_interface.h */ +enum { + UI_SELECT = (1 << 0), /* use when the button is pressed */ + UI_SCROLLED = (1 << 1), /* temp hidden, scrolled away */ + UI_ACTIVE = (1 << 2), + UI_HAS_ICON = (1 << 3), + UI_TEXTINPUT = (1 << 4), + UI_HIDDEN = (1 << 5), + /* warn: rest of uiBut->flag in UI_interface.h */ +}; /* internal panel drawing defines */ #define PNL_GRID (UI_UNIT_Y / 5) /* 4 default */ @@ -385,6 +386,7 @@ extern void ui_hsvcircle_vals_from_pos(float *val_rad, float *val_dist, const rc const float mx, const float my); extern void ui_hsvcircle_pos_from_vals(struct uiBut *but, const rcti *rect, float *hsv, float *xpos, float *ypos); extern void ui_hsvcube_pos_from_vals(struct uiBut *but, const rcti *rect, float *hsv, float *xp, float *yp); +bool ui_hsvcube_use_display_colorspace(struct uiBut *but); extern void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision); extern void ui_get_but_string(uiBut *but, char *str, const size_t maxlen); @@ -402,6 +404,7 @@ extern bool ui_is_but_unit(uiBut *but); extern bool ui_is_but_rna_valid(uiBut *but); extern bool ui_is_but_utf8(uiBut *but); extern bool ui_is_but_interactive(uiBut *but); +extern bool ui_is_but_search_unlink_visible(uiBut *but); extern int ui_is_but_push_ex(uiBut *but, double *value); extern int ui_is_but_push(uiBut *but); @@ -522,6 +525,7 @@ extern void ui_button_active_free(const struct bContext *C, uiBut *but); extern bool ui_button_is_active(struct ARegion *ar); extern int ui_button_open_menu_direction(uiBut *but); extern void ui_button_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiBut *but, int restore); +void ui_button_clipboard_free(void); /* interface_widgets.c */ void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index b453a3b8363..b85c30b8710 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -54,6 +54,8 @@ #include "UI_interface.h" +#include "ED_armature.h" + #include "WM_api.h" #include "WM_types.h" @@ -375,6 +377,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in int cols = (len >= 20) ? 2 : 1; const unsigned int colbuts = len / (2 * cols); unsigned int layer_used = 0; + unsigned int layer_active = 0; uiBlockSetCurLayout(block, uiLayoutAbsolute(layout, FALSE)); @@ -384,27 +387,59 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in if (ptr->type == &RNA_Armature) { bArmature *arm = (bArmature *)ptr->data; + layer_used = arm->layer_used; + + if (arm->edbo) { + if (arm->act_edbone) { + layer_active |= arm->act_edbone->layer; + } + } + else { + if (arm->act_bone) { + layer_active |= arm->act_bone->layer; + } + } } for (b = 0; b < cols; b++) { uiBlockBeginAlign(block); for (a = 0; a < colbuts; a++) { - if (layer_used & (1 << (a + b * colbuts))) icon = ICON_LAYER_USED; - else icon = ICON_BLANK1; + int layer_num = a + b * colbuts; + int layer_flag = 1 << layer_num; + + if (layer_used & layer_flag) { + if (layer_active & layer_flag) + icon = ICON_LAYER_ACTIVE; + else + icon = ICON_LAYER_USED; + } + else { + icon = ICON_BLANK1; + } - but = uiDefAutoButR(block, ptr, prop, a + b * colbuts, "", icon, x + butw * a, y + buth, butw, buth); + but = uiDefAutoButR(block, ptr, prop, layer_num, "", icon, x + butw * a, y + buth, butw, buth); if (subtype == PROP_LAYER_MEMBER) - uiButSetFunc(but, ui_layer_but_cb, but, SET_INT_IN_POINTER(a + b * colbuts)); + uiButSetFunc(but, ui_layer_but_cb, but, SET_INT_IN_POINTER(layer_num)); } for (a = 0; a < colbuts; a++) { - if (layer_used & (1 << (a + len / 2 + b * colbuts))) icon = ICON_LAYER_USED; - else icon = ICON_BLANK1; + int layer_num = a + len / 2 + b * colbuts; + int layer_flag = 1 << layer_num; + + if (layer_used & layer_flag) { + if (layer_active & layer_flag) + icon = ICON_LAYER_ACTIVE; + else + icon = ICON_LAYER_USED; + } + else { + icon = ICON_BLANK1; + } - but = uiDefAutoButR(block, ptr, prop, a + len / 2 + b * colbuts, "", icon, x + butw * a, y, butw, buth); + but = uiDefAutoButR(block, ptr, prop, layer_num, "", icon, x + butw * a, y, butw, buth); if (subtype == PROP_LAYER_MEMBER) - uiButSetFunc(but, ui_layer_but_cb, but, SET_INT_IN_POINTER(a + len / 2 + b * colbuts)); + uiButSetFunc(but, ui_layer_but_cb, but, SET_INT_IN_POINTER(layer_num)); } uiBlockEndAlign(block); @@ -549,7 +584,7 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt } if (ui_layout_local_dir(layout) != UI_LAYOUT_HORIZONTAL) - but->flag |= UI_TEXT_LEFT; + but->drawflag |= UI_BUT_TEXT_LEFT; } uiBlockSetCurLayout(block, layout); @@ -731,7 +766,7 @@ PointerRNA uiItemFullO_ptr(uiLayout *layout, wmOperatorType *ot, const char *nam /* text alignment for toolbar buttons */ if ((layout->root->type == UI_LAYOUT_TOOLBAR) && !icon) - but->flag |= UI_TEXT_LEFT; + but->drawflag |= UI_BUT_TEXT_LEFT; if (flag & UI_ITEM_R_NO_BG) uiBlockSetEmboss(block, UI_EMBOSS); @@ -881,7 +916,7 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname uiItemL(column, item->name, ICON_NONE); but = block->buttons.last; - but->flag = UI_TEXT_LEFT; + but->drawflag = UI_BUT_TEXT_LEFT; ui_but_tip_from_enum_item(but, item); } else { /* XXX bug here, colums draw bottom item badly */ @@ -1305,7 +1340,7 @@ void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname uiItemL(column, item[i].name, ICON_NONE); bt = block->buttons.last; - bt->flag = UI_TEXT_LEFT; + bt->drawflag = UI_BUT_TEXT_LEFT; ui_but_tip_from_enum_item(bt, &item[i]); } @@ -1455,7 +1490,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN but->hardmax = MAX2(but->hardmax, 256.0f); but->rnasearchpoin = *searchptr; but->rnasearchprop = searchprop; - but->flag |= UI_ICON_LEFT | UI_TEXT_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT; if (RNA_property_type(prop) == PROP_ENUM) { /* XXX, this will have a menu string, @@ -1598,7 +1633,7 @@ static void ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCre (force_menu && layout->root->type != UI_LAYOUT_MENU)) /* We never want a dropdown in menu! */ { but->type = MENU; - but->flag |= UI_TEXT_LEFT; + but->drawflag |= UI_BUT_TEXT_LEFT; } } @@ -1650,13 +1685,13 @@ static uiBut *uiItemL_(uiLayout *layout, const char *name, int icon) * make text aligned right if the layout is aligned right. */ if (uiLayoutGetAlignment(layout) == UI_LAYOUT_ALIGN_RIGHT) { - but->flag &= ~UI_TEXT_LEFT; /* default, needs to be unset */ - but->flag |= UI_TEXT_RIGHT; + but->drawflag &= ~UI_BUT_TEXT_LEFT; /* default, needs to be unset */ + but->drawflag |= UI_BUT_TEXT_RIGHT; } /* Mark as a label inside a listbox. */ if (block->flag & UI_BLOCK_LIST_ITEM) { - but->type = LISTLABEL; + but->flag |= UI_BUT_LIST_ITEM; } return but; @@ -2423,7 +2458,10 @@ void ui_layout_list_set_labels_active(uiLayout *layout) { uiButtonItem *bitem; for (bitem = layout->items.first; bitem; bitem = bitem->item.next) { - if (bitem->item.type == ITEM_BUTTON && bitem->but->type == LISTLABEL) { + if (bitem->item.type != ITEM_BUTTON) { + ui_layout_list_set_labels_active((uiLayout *)(&bitem->item)); + } + else if (bitem->but->flag & UI_BUT_LIST_ITEM) { uiButSetFlag(bitem->but, UI_SELECT); } } @@ -2931,7 +2969,7 @@ static void ui_intro_button(DynStr *ds, uiButtonItem *bitem) BLI_dynstr_appendf(ds, "'tip':'''%s''', ", but->tip ? but->tip : ""); /* not exactly needed, rna has this */ if (but->optype) { - char *opstr = WM_operator_pystring(but->block->evil_C, but->optype, but->opptr, 0); + char *opstr = WM_operator_pystring_ex(but->block->evil_C, NULL, false, but->optype, but->opptr); BLI_dynstr_appendf(ds, "'operator':'''%s''', ", opstr ? opstr : ""); MEM_freeN(opstr); } diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 15fbd51c6fc..f869c5de8e6 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -443,7 +443,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) uiStringInfo rna_struct = {BUT_GET_RNASTRUCT_IDENTIFIER, NULL}; uiStringInfo rna_prop = {BUT_GET_RNAPROP_IDENTIFIER, NULL}; - if (but->flag & UI_BUT_NO_TOOLTIP) + if (but->drawflag & UI_BUT_NO_TOOLTIP) return NULL; /* create tooltip data */ @@ -539,7 +539,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) /* so the context is passed to itemf functions (some py itemf functions use it) */ WM_operator_properties_sanitize(opptr, false); - str = WM_operator_pystring(C, but->optype, opptr, 0); + str = WM_operator_pystring_ex(C, NULL, false, but->optype, opptr); /* operator info */ if ((U.flag & USER_TOOLTIPS_PYTHON) == 0) { @@ -1054,17 +1054,17 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, const bool reset) bool ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str) { uiSearchboxData *data = ar->regiondata; - bool changed = false; + int match = AUTOCOMPLETE_NO_MATCH; if (str[0]) { data->items.autocpl = autocomplete_begin(str, ui_get_but_string_max_length(but)); but->search_func(C, but->search_arg, but->editstr, &data->items); - changed = autocomplete_end(data->items.autocpl, str); + match = autocomplete_end(data->items.autocpl, str); data->items.autocpl = NULL; } - return changed; + return match != AUTOCOMPLETE_NO_MATCH; } static void ui_searchbox_region_draw_cb(const bContext *UNUSED(C), ARegion *ar) @@ -1389,9 +1389,9 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, /* widget_roundbox_set has this correction too, keep in sync */ if (but->type != PULLDOWN) { - if (but->flag & UI_BUT_ALIGN_TOP) + if (but->drawflag & UI_BUT_ALIGN_TOP) butrct.ymax += U.pixelsize; - if (but->flag & UI_BUT_ALIGN_LEFT) + if (but->drawflag & UI_BUT_ALIGN_LEFT) butrct.xmin -= U.pixelsize; } @@ -1840,7 +1840,7 @@ static void ui_block_func_MENUSTR(bContext *UNUSED(C), uiLayout *layout, void *a else { uiItemL(layout, md->title, ICON_NONE); bt = block->buttons.last; - bt->flag = UI_TEXT_LEFT; + bt->drawflag = UI_BUT_TEXT_LEFT; } } @@ -1876,7 +1876,7 @@ static void ui_block_func_MENUSTR(bContext *UNUSED(C), uiLayout *layout, void *a if (entry->str[0]) { uiItemL(column, entry->str, entry->icon); bt = block->buttons.last; - bt->flag = UI_TEXT_LEFT; + bt->drawflag = UI_BUT_TEXT_LEFT; } else { uiItemS(column); @@ -2560,7 +2560,7 @@ uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon) } else { but = uiDefBut(pup->block, LABEL, 0, title, 0, 0, 200, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); - but->flag = UI_TEXT_LEFT; + but->drawflag = UI_BUT_TEXT_LEFT; } } diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 6b6b7114c84..1d1b7dbb835 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -443,7 +443,8 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str but->icon = RNA_struct_ui_icon(type); /* default dragging of icon for id browse buttons */ uiButSetDragID(but, id); - uiButSetFlag(but, UI_HAS_ICON | UI_ICON_LEFT); + uiButSetFlag(but, UI_HAS_ICON); + uiButSetDrawFlag(but, UI_BUT_ICON_LEFT); } if ((idfrom && idfrom->lib) || !editable) @@ -967,11 +968,11 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob, if (md->type == eModifierType_ParticleSystem) { ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys; - if (!(ob->mode & OB_MODE_PARTICLE_EDIT) && psys->pathcache) { + if (!(ob->mode & OB_MODE_PARTICLE_EDIT)) { if (ELEM(psys->part->ren_as, PART_DRAW_GR, PART_DRAW_OB)) uiItemO(row, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Convert"), ICON_NONE, "OBJECT_OT_duplicates_make_real"); - else if (psys->part->ren_as == PART_DRAW_PATH) + else if (psys->part->ren_as == PART_DRAW_PATH && psys->pathcache) uiItemO(row, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Convert"), ICON_NONE, "OBJECT_OT_modifier_convert"); } @@ -1921,7 +1922,7 @@ static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event) case UICURVE_FUNC_RESET_NEG: case UICURVE_FUNC_RESET_POS: /* reset */ curvemap_reset(cuma, &cumap->clipr, cumap->preset, - (event == -1) ? CURVEMAP_SLOPE_NEGATIVE : CURVEMAP_SLOPE_POSITIVE); + (event == UICURVE_FUNC_RESET_NEG) ? CURVEMAP_SLOPE_NEGATIVE : CURVEMAP_SLOPE_POSITIVE); curvemapping_changed(cumap, FALSE); break; case UICURVE_FUNC_RESET_VIEW: @@ -2855,6 +2856,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co items_shown = dyn_data->items_shown; if (items_shown >= 0) { + bool activei_mapping_pending = true; items_ptr = MEM_mallocN(sizeof(_uilist_item) * items_shown, AT); //printf("%s: items shown: %d.\n", __func__, items_shown); RNA_PROP_BEGIN (dataptr, itemptr, prop) @@ -2875,8 +2877,10 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co items_ptr[ii].org_idx = i; items_ptr[ii].flt_flag = dyn_data->items_filter_flags ? dyn_data->items_filter_flags[i] : 0; - if (activei == i) { + if (activei_mapping_pending && activei == i) { activei = ii; + /* So that we do not map again activei! */ + activei_mapping_pending = false; } # if 0 /* For now, do not alter active element, even if it will be hidden... */ else if (activei < i) { @@ -2936,7 +2940,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co but = uiDefButR_prop(subblock, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, active_dataptr, activeprop, 0, 0, org_i, 0, 0, NULL); - uiButSetFlag(but, UI_BUT_NO_TOOLTIP); + uiButSetDrawFlag(but, UI_BUT_NO_TOOLTIP); sub = uiLayoutRow(overlap, FALSE); @@ -3023,7 +3027,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co but = uiDefButR_prop(subblock, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, active_dataptr, activeprop, 0, 0, org_i, 0, 0, NULL); - uiButSetFlag(but, UI_BUT_NO_TOOLTIP); + uiButSetDrawFlag(but, UI_BUT_NO_TOOLTIP); sub = uiLayoutRow(overlap, FALSE); @@ -3065,11 +3069,11 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co if (ui_list->filter_flag & UILST_FLT_SHOW) { but = uiDefIconButBitI(subblock, TOG, UILST_FLT_SHOW, 0, ICON_DISCLOSURE_TRI_DOWN, 0, 0, - UI_UNIT_X, UI_UNIT_Y * 0.6f, &(ui_list->filter_flag), 0, 0, 0, 0, + UI_UNIT_X, UI_UNIT_Y * 0.8f, &(ui_list->filter_flag), 0, 0, 0, 0, TIP_("Hide filtering options")); uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ - but = uiDefIconBut(subblock, BUT, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10.0f, UI_UNIT_Y * 0.6f, ui_list, + but = uiDefIconBut(subblock, BUT, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10.0f, UI_UNIT_Y * 0.8f, ui_list, 0.0, 0.0, 0, -1, ""); uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ @@ -3083,11 +3087,11 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co } else { but = uiDefIconButBitI(subblock, TOG, UILST_FLT_SHOW, 0, ICON_DISCLOSURE_TRI_RIGHT, 0, 0, - UI_UNIT_X, UI_UNIT_Y * 0.6f, &(ui_list->filter_flag), 0, 0, 0, 0, + UI_UNIT_X, UI_UNIT_Y * 0.8f, &(ui_list->filter_flag), 0, 0, 0, 0, TIP_("Show filtering options")); uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ - but = uiDefIconBut(subblock, BUT, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10.0f, UI_UNIT_Y * 0.6f, ui_list, + but = uiDefIconBut(subblock, BUT, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10.0f, UI_UNIT_Y * 0.8f, ui_list, 0.0, 0.0, 0, -1, ""); uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ @@ -3236,6 +3240,16 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C) handle_event = B_STOPCOMPO; break; } + else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE)) { + /* Skip bake jobs in compositor to avoid compo header displaying + * progress bar which is not being updated (bake jobs only need + * to update NC_IMAGE context. + */ + if (sa->spacetype != SPACE_NODE) { + handle_event = B_STOPOTHER; + break; + } + } else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_ANY)) { handle_event = B_STOPOTHER; break; diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 4be8812d68c..3058888c012 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -882,7 +882,7 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, const rcti } /* extra feature allows more alpha blending */ - if (ELEM(but->type, LABEL, LISTLABEL) && but->a1 == 1.0f) + if ((but->type == LABEL) && but->a1 == 1.0f) alpha *= but->a2; glEnable(GL_BLEND); @@ -890,7 +890,7 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, const rcti if (icon && icon != ICON_BLANK1) { float ofs = 1.0f / aspect; - if (but->flag & UI_ICON_LEFT) { + if (but->drawflag & UI_BUT_ICON_LEFT) { if (but->block->flag & UI_BLOCK_LOOP) { if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) xs = rect->xmin + 4.0f * ofs; @@ -956,12 +956,12 @@ static void ui_text_clip_give_next_off(uiBut *but) */ static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, const rcti *rect) { - int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10; + int border = (but->drawflag & UI_BUT_ALIGN_RIGHT) ? 8 : 10; int okwidth = BLI_rcti_size_x(rect) - border; if (but->flag & UI_HAS_ICON) okwidth -= UI_DPI_ICON_SIZE; - if (but->type == SEARCH_MENU_UNLINK && !but->editstr) + if ((but->type == SEARCH_MENU_UNLINK) && ui_is_but_search_unlink_visible(but)) okwidth -= BLI_rcti_size_y(rect); okwidth = max_ii(okwidth, 0); @@ -991,7 +991,7 @@ static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, const rcti *rect) */ static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, const rcti *rect) { - int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10; + int border = (but->drawflag & UI_BUT_ALIGN_RIGHT) ? 8 : 10; int okwidth = max_ii(BLI_rcti_size_x(rect) - border, 0); if (but->flag & UI_HAS_ICON) okwidth -= UI_DPI_ICON_SIZE; @@ -1055,7 +1055,7 @@ static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, const rcti *rec */ static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti *rect) { - int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10; + int border = (but->drawflag & UI_BUT_ALIGN_RIGHT) ? 8 : 10; int okwidth = max_ii(BLI_rcti_size_x(rect) - border, 0); char *cpoin = NULL; int drawstr_len = strlen(but->drawstr); @@ -1140,9 +1140,9 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b uiStyleFontSet(fstyle); - if (but->editstr || (but->flag & UI_TEXT_LEFT)) + if (but->editstr || (but->drawflag & UI_BUT_TEXT_LEFT)) fstyle->align = UI_STYLE_TEXT_LEFT; - else if (but->flag & UI_TEXT_RIGHT) + else if (but->drawflag & UI_BUT_TEXT_RIGHT) fstyle->align = UI_STYLE_TEXT_RIGHT; else fstyle->align = UI_STYLE_TEXT_CENTER; @@ -1310,22 +1310,22 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB /* icons default draw 0.8f x height */ rect->xmin += (int)(0.8f * BLI_rcti_size_y(rect)); - if (but->editstr || (but->flag & UI_TEXT_LEFT)) { + if (but->editstr || (but->drawflag & UI_BUT_TEXT_LEFT)) { rect->xmin += (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect; } - else if ((but->flag & UI_TEXT_RIGHT)) { + else if ((but->drawflag & UI_BUT_TEXT_RIGHT)) { rect->xmax -= (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect; } } - else if ((but->flag & UI_TEXT_LEFT)) { + else if ((but->drawflag & UI_BUT_TEXT_LEFT)) { rect->xmin += (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect; } - else if ((but->flag & UI_TEXT_RIGHT)) { + else if ((but->drawflag & UI_BUT_TEXT_RIGHT)) { rect->xmax -= (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect; } /* unlink icon for this button type */ - if (but->type == SEARCH_MENU_UNLINK && !but->editstr && but->drawstr[0]) { + if ((but->type == SEARCH_MENU_UNLINK) && ui_is_but_search_unlink_visible(but)) { rcti temp = *rect; temp.xmin = temp.xmax - (BLI_rcti_size_y(rect) * 1.08f); @@ -2004,10 +2004,11 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti * /* ************ custom buttons, old stuff ************** */ -/* draws in resolution of 20x4 colors */ +/* draws in resolution of 48x4 colors */ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha) { - const float color_step = (type == UI_GRAD_H) ? 0.02f : 0.05f; + /* allows for 4 steps (red->yellow) */ + const float color_step = (1.0 / 48.0); int a; float h = hsv[0], s = hsv[1], v = hsv[2]; float dx, dy, sx1, sx2, sy; @@ -2066,6 +2067,8 @@ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, cons /* old below */ for (dx = 0.0f; dx < 0.999f; dx += color_step) { /* 0.999 = prevent float inaccuracy for steps */ + const float dx_next = dx + color_step; + /* previous color */ copy_v3_v3(col0[0], col1[0]); copy_v3_v3(col0[1], col1[1]); @@ -2081,22 +2084,22 @@ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, cons hsv_to_rgb(h, 1.0, dx, &col1[3][0], &col1[3][1], &col1[3][2]); break; case UI_GRAD_HV: - hsv_to_rgb(dx, s, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]); - hsv_to_rgb(dx, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]); - hsv_to_rgb(dx, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]); - hsv_to_rgb(dx, s, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]); + hsv_to_rgb(dx_next, s, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]); + hsv_to_rgb(dx_next, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]); + hsv_to_rgb(dx_next, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]); + hsv_to_rgb(dx_next, s, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]); break; case UI_GRAD_HS: - hsv_to_rgb(dx, 0.0, v, &col1[0][0], &col1[0][1], &col1[0][2]); - hsv_to_rgb(dx, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]); - hsv_to_rgb(dx, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]); - hsv_to_rgb(dx, 1.0, v, &col1[3][0], &col1[3][1], &col1[3][2]); + hsv_to_rgb(dx_next, 0.0, v, &col1[0][0], &col1[0][1], &col1[0][2]); + hsv_to_rgb(dx_next, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]); + hsv_to_rgb(dx_next, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]); + hsv_to_rgb(dx_next, 1.0, v, &col1[3][0], &col1[3][1], &col1[3][2]); break; case UI_GRAD_H: { /* annoying but without this the color shifts - could be solved some other way * - campbell */ - hsv_to_rgb(dx + color_step, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]); + hsv_to_rgb(dx_next, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]); copy_v3_v3(col1[1], col1[0]); copy_v3_v3(col1[2], col1[0]); copy_v3_v3(col1[3], col1[0]); @@ -2117,8 +2120,8 @@ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, cons } /* rect */ - sx1 = rect->xmin + dx * BLI_rcti_size_x(rect); - sx2 = rect->xmin + (dx + color_step) * BLI_rcti_size_x(rect); + sx1 = rect->xmin + dx * BLI_rcti_size_x(rect); + sx2 = rect->xmin + dx_next * BLI_rcti_size_x(rect); sy = rect->ymin; dy = (float)BLI_rcti_size_y(rect) / 3.0f; @@ -2143,6 +2146,19 @@ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, cons } +bool ui_hsvcube_use_display_colorspace(uiBut *but) +{ + bool color_profile = but->block->color_profile; + + if (but->rnaprop) { + if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) + color_profile = FALSE; + } + + /* SV+H gradient does not use display colorspace */ + return color_profile && !ELEM((int)but->a1, UI_GRAD_SV, UI_GRAD_H); +} + void ui_hsvcube_pos_from_vals(uiBut *but, const rcti *rect, float *hsv, float *xp, float *yp) { float x, y; @@ -2179,16 +2195,13 @@ static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect) float x = 0.0f, y = 0.0f; float *hsv = ui_block_hsv_get(but->block); float hsv_n[3]; - int color_profile = but->block->color_profile; - - if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) - color_profile = FALSE; + bool use_display_colorspace = ui_hsvcube_use_display_colorspace(but); copy_v3_v3(hsv_n, hsv); ui_get_but_vectorf(but, rgb); - if (color_profile && (int)but->a1 != UI_GRAD_SV) + if (use_display_colorspace) ui_block_to_display_space_v3(but->block, rgb); rgb_to_hsv_compat_v(rgb, hsv_n); @@ -2853,12 +2866,21 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN /* labels use Editor theme colors for text */ static void widget_state_label(uiWidgetType *wt, int state) { - /* call this for option button */ - widget_state(wt, state); - if (state & UI_SELECT) - UI_GetThemeColor3ubv(TH_TEXT_HI, (unsigned char *)wt->wcol.text); - else - UI_GetThemeColor3ubv(TH_TEXT, (unsigned char *)wt->wcol.text); + if (state & UI_BUT_LIST_ITEM) { + /* Override default label theme's colors. */ + bTheme *btheme = UI_GetTheme(); + wt->wcol_theme = &btheme->tui.wcol_list_item; + /* call this for option button */ + widget_state(wt, state); + } + else { + /* call this for option button */ + widget_state(wt, state); + if (state & UI_SELECT) + UI_GetThemeColor3ubv(TH_TEXT_HI, (unsigned char *)wt->wcol.text); + else + UI_GetThemeColor3ubv(TH_TEXT, (unsigned char *)wt->wcol.text); + } } static void widget_radiobut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) @@ -2978,11 +3000,6 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type) case UI_WTYPE_REGULAR: break; - case UI_WTYPE_LISTLABEL: - wt.wcol_theme = &btheme->tui.wcol_list_item; - wt.draw = NULL; - /* Can't use usual label code. */ - break; case UI_WTYPE_LABEL: wt.draw = NULL; wt.state = widget_state_label; @@ -3126,15 +3143,15 @@ static int widget_roundbox_set(uiBut *but, rcti *rect) int roundbox = UI_CNR_ALL; /* alignment */ - if ((but->flag & UI_BUT_ALIGN) && but->type != PULLDOWN) { + if ((but->drawflag & UI_BUT_ALIGN) && but->type != PULLDOWN) { /* ui_block_position has this correction too, keep in sync */ - if (but->flag & UI_BUT_ALIGN_TOP) + if (but->drawflag & UI_BUT_ALIGN_TOP) rect->ymax += U.pixelsize; - if (but->flag & UI_BUT_ALIGN_LEFT) + if (but->drawflag & UI_BUT_ALIGN_LEFT) rect->xmin -= U.pixelsize; - switch (but->flag & UI_BUT_ALIGN) { + switch (but->drawflag & UI_BUT_ALIGN) { case UI_BUT_ALIGN_TOP: roundbox = UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT; break; @@ -3232,11 +3249,6 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct fstyle = &style->widgetlabel; } break; - - case LISTLABEL: - wt = widget_type(UI_WTYPE_LISTLABEL); - fstyle = &style->widgetlabel; - break; case SEPR: break; @@ -3282,7 +3294,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct case OPTIONN: if (!(but->flag & UI_HAS_ICON)) { wt = widget_type(UI_WTYPE_OPTION); - but->flag |= UI_TEXT_LEFT; + but->drawflag |= UI_BUT_TEXT_LEFT; } else wt = widget_type(UI_WTYPE_TOGGLE); diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index ace35f0276e..55b353b1031 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1406,6 +1406,7 @@ void init_userdef_do_versions(void) } if (U.pad_rot_angle == 0) U.pad_rot_angle = 15; + /* graph editor - unselected F-Curve visibility */ if (U.fcu_inactive_alpha == 0) { U.fcu_inactive_alpha = 0.25f; @@ -2224,7 +2225,14 @@ void init_userdef_do_versions(void) rgba_char_args_test_set(btheme->tima.uv_shadow, 112, 112, 112, 255); } } - + + if (U.versionfile < 270) { + /* grease pencil - new layer color */ + if (U.gpencil_new_layer_col[3] < 0.1f) { + /* defaults to black, but must at least be visible! */ + U.gpencil_new_layer_col[3] = 0.9f; + } + } if (U.pixelsize == 0.0f) U.pixelsize = 1.0f; diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 00113666872..c5c9b1c8ce4 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -284,10 +284,9 @@ static int view_pan_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static int view_pan_cancel(bContext *UNUSED(C), wmOperator *op) +static void view_pan_cancel(bContext *UNUSED(C), wmOperator *op) { view_pan_exit(op); - return OPERATOR_CANCELLED; } static void VIEW2D_OT_pan(wmOperatorType *ot) @@ -906,11 +905,9 @@ static void view_zoomdrag_exit(bContext *C, wmOperator *op) } } -static int view_zoomdrag_cancel(bContext *C, wmOperator *op) +static void view_zoomdrag_cancel(bContext *C, wmOperator *op) { view_zoomdrag_exit(C, op); - - return OPERATOR_CANCELLED; } /* for 'redo' only, with no user input */ @@ -1579,11 +1576,9 @@ static void scroller_activate_exit(bContext *C, wmOperator *op) } } -static int scroller_activate_cancel(bContext *C, wmOperator *op) +static void scroller_activate_cancel(bContext *C, wmOperator *op) { scroller_activate_exit(C, op); - - return OPERATOR_CANCELLED; } /* apply transform to view (i.e. adjust 'cur' rect) */ diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c index 4cc9d3b59b1..7a78d60e11e 100644 --- a/source/blender/editors/mask/mask_add.c +++ b/source/blender/editors/mask/mask_add.c @@ -385,7 +385,7 @@ static int add_vertex_subdivide(const bContext *C, Mask *mask, const float co[2] setup_vertex_point(mask, spline, new_point, co, tangent, u, NULL, TRUE, 1.0f); /* 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); + BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index + 1, true, true); masklay->act_spline = spline; masklay->act_point = new_point; @@ -486,7 +486,7 @@ static int add_vertex_extrude(const bContext *C, Mask *mask, MaskLayer *masklay, 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); + BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index, true, true); } if (do_recalc_src) { @@ -548,7 +548,7 @@ static int add_vertex_new(const bContext *C, Mask *mask, MaskLayer *masklay, con { 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); + 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); diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c index d5fbdca5b0a..78dba382520 100644 --- a/source/blender/editors/mask/mask_shapekey.c +++ b/source/blender/editors/mask/mask_shapekey.c @@ -69,7 +69,7 @@ static int mask_shape_key_insert_exec(bContext *C, wmOperator *UNUSED(op)) continue; } - masklay_shape = BKE_mask_layer_shape_varify_frame(masklay, frame); + masklay_shape = BKE_mask_layer_shape_verify_frame(masklay, frame); BKE_mask_layer_shape_from_mask(masklay, masklay_shape); change = TRUE; } @@ -319,8 +319,8 @@ static int mask_shape_key_rekey_exec(bContext *C, wmOperator *op) masklay_shape_tmp; masklay_shape_tmp = masklay_shape_tmp->next) { - BKE_mask_layer_evaluate(masklay, masklay_shape_tmp->frame, TRUE); - masklay_shape_tmp_rekey = BKE_mask_layer_shape_varify_frame(masklay, masklay_shape_tmp->frame); + BKE_mask_layer_evaluate(masklay, masklay_shape_tmp->frame, true); + masklay_shape_tmp_rekey = BKE_mask_layer_shape_verify_frame(masklay, masklay_shape_tmp->frame); BKE_mask_layer_shape_from_mask(masklay, masklay_shape_tmp_rekey); masklay_shape_tmp_rekey->flag = masklay_shape_tmp->flag & MASK_SHAPE_SELECT; } @@ -376,7 +376,7 @@ static int mask_shape_key_rekey_exec(bContext *C, wmOperator *op) } /* re-evaluate */ - BKE_mask_layer_evaluate(masklay, frame, TRUE); + BKE_mask_layer_evaluate(masklay, frame, true); } } @@ -417,7 +417,7 @@ 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); + masklay_shape = BKE_mask_layer_shape_verify_frame(masklay, frame); BKE_mask_layer_shape_from_mask(masklay, masklay_shape); } diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 7944c2f0cca..9e1785e27d1 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -797,7 +797,7 @@ void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_to if (em) { if (skip_em_vert_array_init == false) { - EDBM_index_arrays_ensure(em, BM_VERT); + BM_mesh_elem_table_ensure(em->bm, BM_VERT); } } @@ -822,8 +822,8 @@ void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_to if ((a == totvert) || (topo_pairs[a - 1].hash != topo_pairs[a].hash)) { if (a - last == 2) { if (em) { - index_lookup[topo_pairs[a - 1].v_index] = (intptr_t)EDBM_vert_at_index(em, topo_pairs[a - 2].v_index); - index_lookup[topo_pairs[a - 2].v_index] = (intptr_t)EDBM_vert_at_index(em, topo_pairs[a - 1].v_index); + index_lookup[topo_pairs[a - 1].v_index] = (intptr_t)BM_vert_at_index(em->bm, topo_pairs[a - 2].v_index); + index_lookup[topo_pairs[a - 2].v_index] = (intptr_t)BM_vert_at_index(em->bm, topo_pairs[a - 1].v_index); } else { index_lookup[topo_pairs[a - 1].v_index] = topo_pairs[a - 2].v_index; diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index 97da0047793..ddb58cd6c7b 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -131,6 +131,7 @@ static bool edbm_bevel_calc(wmOperator *op) BMEditMesh *em = opdata->em; BMOperator bmop; const float offset = RNA_float_get(op->ptr, "offset"); + const int offset_type = RNA_enum_get(op->ptr, "offset_type"); const int segments = RNA_int_get(op->ptr, "segments"); const bool vertex_only = RNA_boolean_get(op->ptr, "vertex_only"); @@ -140,8 +141,8 @@ static bool edbm_bevel_calc(wmOperator *op) } EDBM_op_init(em, &bmop, op, - "bevel geom=%hev offset=%f segments=%i vertex_only=%b", - BM_ELEM_SELECT, offset, segments, vertex_only); + "bevel geom=%hev offset=%f segments=%i vertex_only=%b offset_type=%i", + BM_ELEM_SELECT, offset, segments, vertex_only, offset_type); BMO_op_exec(em->bm, &bmop); @@ -185,7 +186,7 @@ static void edbm_bevel_exit(bContext *C, wmOperator *op) op->customdata = NULL; } -static int edbm_bevel_cancel(bContext *C, wmOperator *op) +static void edbm_bevel_cancel(bContext *C, wmOperator *op) { BevelData *opdata = op->customdata; if (opdata->is_modal) { @@ -197,7 +198,6 @@ static int edbm_bevel_cancel(bContext *C, wmOperator *op) /* need to force redisplay or we may still view the modified result */ ED_region_tag_redraw(CTX_wm_region(C)); - return OPERATOR_CANCELLED; } /* bevel! yay!!*/ @@ -257,12 +257,14 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event) static float edbm_bevel_mval_factor(wmOperator *op, const wmEvent *event) { BevelData *opdata = op->customdata; - int use_dist = true; + bool use_dist = true; + bool is_percent = false; float mdiff[2]; float factor; mdiff[0] = opdata->mcenter[0] - event->mval[0]; mdiff[1] = opdata->mcenter[1] - event->mval[1]; + is_percent = (RNA_enum_get(op->ptr, "offset_type") == BEVEL_AMT_PERCENT); if (use_dist) { factor = ((len_v2(mdiff) - MVAL_PIXEL_MARGIN) - opdata->initial_length) * opdata->pixel_size; @@ -287,7 +289,13 @@ static float edbm_bevel_mval_factor(wmOperator *op, const wmEvent *event) if (factor < 0.0f) factor = 0.0f; } else { - CLAMP(factor, 0.0f, 1.0f); + if (is_percent) { + factor *= 100.0f; + CLAMP(factor, 0.0f, 100.0f); + } + else { + CLAMP(factor, 0.0f, 1.0f); + } } return factor; @@ -362,6 +370,14 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event) void MESH_OT_bevel(wmOperatorType *ot) { + static EnumPropertyItem offset_type_items[] = { + {BEVEL_AMT_OFFSET, "OFFSET", 0, "Offset", "Amount is offset of new edges from original"}, + {BEVEL_AMT_WIDTH, "WIDTH", 0, "Width", "Amount is width of new face"}, + {BEVEL_AMT_DEPTH, "DEPTH", 0, "Depth", "Amount is perpendicular distance from original edge to bevel face"}, + {BEVEL_AMT_PERCENT, "PERCENT", 0, "Percent", "Amount is percent of adjacent edge length"}, + {0, NULL, 0, NULL, NULL}, + }; + /* identifiers */ ot->name = "Bevel"; ot->description = "Edge Bevel"; @@ -377,7 +393,8 @@ void MESH_OT_bevel(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_POINTER | OPTYPE_BLOCKING; - RNA_def_float(ot->srna, "offset", 0.0f, -FLT_MAX, FLT_MAX, "Offset", "", 0.0f, 1.0f); + RNA_def_enum(ot->srna, "offset_type", offset_type_items, 0, "Amount Type", "What distance Amount measures"); + RNA_def_float(ot->srna, "offset", 0.0f, -FLT_MAX, FLT_MAX, "Amount", "", 0.0f, 1.0f); RNA_def_int(ot->srna, "segments", 1, 1, 50, "Segments", "Segments for curved edge", 1, 8); RNA_def_boolean(ot->srna, "vertex_only", false, "Vertex only", "Bevel only vertices"); } diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c index 5431b1deb1c..7bc3ff3ab77 100644 --- a/source/blender/editors/mesh/editmesh_bisect.c +++ b/source/blender/editors/mesh/editmesh_bisect.c @@ -203,7 +203,7 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op) RNA_property_float_get_array(op->ptr, prop_plane_co, plane_co); } else { - copy_v3_v3(plane_co, give_cursor(scene, v3d)); + copy_v3_v3(plane_co, ED_view3d_cursor3d_get(scene, v3d)); RNA_property_float_set_array(op->ptr, prop_plane_co, plane_co); } @@ -300,7 +300,7 @@ void MESH_OT_bisect(struct wmOperatorType *ot) /* identifiers */ ot->name = "Bisect"; - ot->description = "Cut geometry along a plane"; + ot->description = "Cut geometry along a plane (click-drag to define plane)"; ot->idname = "MESH_OT_bisect"; /* api callbacks */ diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c index 3df4ad738ae..ef300fa9db6 100644 --- a/source/blender/editors/mesh/editmesh_extrude.c +++ b/source/blender/editors/mesh/editmesh_extrude.c @@ -377,7 +377,6 @@ static int edbm_extrude_mesh(Scene *scene, Object *obedit, BMEditMesh *em, wmOpe BKE_object_handle_update(scene, obedit); /* individual faces? */ -// BIF_TransformSetUndo("Extrude"); if (nr == 2) { // initTransform(TFM_SHRINKFATTEN, CTX_NO_PET|CTX_NO_MIRROR); // Transform(); @@ -654,7 +653,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w BM_ELEM_SELECT, min); } else { - const float *curs = give_cursor(vc.scene, vc.v3d); + const float *curs = ED_view3d_cursor3d_get(vc.scene, vc.v3d); BMOperator bmop; BMOIter oiter; @@ -752,7 +751,7 @@ static int edbm_spin_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = ED_view3d_context_rv3d(C); - RNA_float_set_array(op->ptr, "center", give_cursor(scene, v3d)); + RNA_float_set_array(op->ptr, "center", ED_view3d_cursor3d_get(scene, v3d)); RNA_float_set_array(op->ptr, "axis", rv3d->viewinv[2]); return edbm_spin_exec(C, op); @@ -872,7 +871,7 @@ static int edbm_screw_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED( View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = ED_view3d_context_rv3d(C); - RNA_float_set_array(op->ptr, "center", give_cursor(scene, v3d)); + RNA_float_set_array(op->ptr, "center", ED_view3d_cursor3d_get(scene, v3d)); RNA_float_set_array(op->ptr, "axis", rv3d->viewinv[1]); return edbm_screw_exec(C, op); diff --git a/source/blender/editors/mesh/editmesh_inset.c b/source/blender/editors/mesh/editmesh_inset.c index eb66cf50a1e..137554459ce 100644 --- a/source/blender/editors/mesh/editmesh_inset.c +++ b/source/blender/editors/mesh/editmesh_inset.c @@ -166,7 +166,7 @@ static void edbm_inset_exit(bContext *C, wmOperator *op) MEM_freeN(op->customdata); } -static int edbm_inset_cancel(bContext *C, wmOperator *op) +static void edbm_inset_cancel(bContext *C, wmOperator *op) { InsetData *opdata; @@ -180,7 +180,6 @@ static int edbm_inset_cancel(bContext *C, wmOperator *op) /* need to force redisplay or we may still view the modified result */ ED_region_tag_redraw(CTX_wm_region(C)); - return OPERATOR_CANCELLED; } static bool edbm_inset_calc(wmOperator *op) diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index b0dc30d73f7..6b99f53a5b8 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -76,6 +76,7 @@ #define KNIFE_FLT_EPS 0.00001f #define KNIFE_FLT_EPS_SQUARED (KNIFE_FLT_EPS * KNIFE_FLT_EPS) +#define KNIFE_FLT_EPSBIG 0.001f typedef struct KnifeColors { unsigned char line[3]; @@ -111,16 +112,20 @@ typedef struct KnifeEdge { bool draw; } KnifeEdge; -typedef struct BMEdgeHit { - KnifeEdge *kfe; +typedef struct KnifeLineHit { float hit[3], cagehit[3]; - float realhit[3]; /* used in midpoint mode */ float schit[2]; float l; /* lambda along cut line */ float perc; /* lambda along hit line */ - KnifeVert *v; /* set if snapped to a vert */ + float m; /* depth front-to-back */ + + /* Exactly one of kfe, v, or f should be non-NULL, + * saying whether cut line crosses and edge, + * is snapped to a vert, or is in the middle of some face. */ + KnifeEdge *kfe; + KnifeVert *v; BMFace *f; -} BMEdgeHit; +} KnifeLineHit; typedef struct KnifePosData { float co[3]; @@ -152,8 +157,8 @@ typedef struct KnifeTool_OpData { GHash *origvertmap; GHash *origedgemap; - GHash *kedgefacemap; + GHash *facetrimap; BMBVHTree *bmbvh; @@ -164,7 +169,7 @@ typedef struct KnifeTool_OpData { float ethresh; /* used for drag-cutting */ - BMEdgeHit *linehits; + KnifeLineHit *linehits; int totlinehit; /* Data for mouse-position-derived data (cur) and previous click (prev) */ @@ -198,7 +203,7 @@ typedef struct KnifeTool_OpData { } mode; int prevmode; - bool snap_midpoints, extend; + bool snap_midpoints; bool ignore_edge_snapping; bool ignore_vert_snapping; @@ -215,13 +220,11 @@ typedef struct KnifeTool_OpData { static ListBase *knife_get_face_kedges(KnifeTool_OpData *kcd, BMFace *f); -#if 0 -static void knife_input_ray_cast(KnifeTool_OpData *kcd, const float mval[2], - float r_origin[3], float r_ray[3]); -#endif static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2], const float ofs, float r_origin[3], float r_dest[3]); +static bool knife_verts_edge_in_face(KnifeVert *v1, KnifeVert *v2, BMFace *f); + static void knife_update_header(bContext *C, KnifeTool_OpData *kcd) { #define HEADER_LENGTH 256 @@ -238,13 +241,6 @@ static void knife_update_header(bContext *C, KnifeTool_OpData *kcd) ED_area_headerprint(CTX_wm_area(C), header); } -#if 0 -BLI_INLINE int round_ftoi(float x) -{ - return x > 0.0f ? (int)(x + 0.5f) : (int)(x - 0.5f); -} -#endif - static void knife_project_v2(const KnifeTool_OpData *kcd, const float co[3], float sco[2]) { ED_view3d_project_float_v2_m4(kcd->ar, co, sco, (float (*)[4])kcd->projmat); @@ -290,6 +286,12 @@ static Ref *find_ref(ListBase *lb, void *ref) return NULL; } +static void knife_append_list_no_dup(KnifeTool_OpData *kcd, ListBase *lst, void *elem) +{ + if (!find_ref(lst, elem)) + knife_append_list(kcd, lst, elem); +} + static KnifeEdge *new_knife_edge(KnifeTool_OpData *kcd) { kcd->totkedge++; @@ -346,12 +348,17 @@ static KnifeVert *new_knife_vert(KnifeTool_OpData *kcd, const float co[3], const static KnifeVert *get_bm_knife_vert(KnifeTool_OpData *kcd, BMVert *v) { KnifeVert *kfv = BLI_ghash_lookup(kcd->origvertmap, v); + const float *cageco; if (!kfv) { BMIter bmiter; BMFace *f; - kfv = new_knife_vert(kcd, v->co, kcd->cagecos[BM_elem_index_get(v)]); + if (BM_elem_index_get(v) >= 0) + cageco = kcd->cagecos[BM_elem_index_get(v)]; + else + cageco = v->co; + kfv = new_knife_vert(kcd, v->co, cageco); kfv->v = v; BLI_ghash_insert(kcd->origvertmap, v, kfv); BM_ITER_ELEM (f, &bmiter, v, BM_FACES_OF_VERT) { @@ -387,6 +394,45 @@ static KnifeEdge *get_bm_knife_edge(KnifeTool_OpData *kcd, BMEdge *e) return kfe; } +/* Record the index in kcd->em->looptris of first looptri triple for a given face, + * given an index for some triple in that array. + * This assumes that all of the triangles for a given face are contiguous + * in that array (as they are by the current tesselation routines). + * Actually store index + 1 in the hash, because 0 looks like "no entry" + * to hash lookup routine; will reverse this in the get routine. + * Doing this lazily rather than all at once for all faces. + */ +static void set_lowest_face_tri(KnifeTool_OpData *kcd, BMFace *f, int index) +{ + int i; + + if (BLI_ghash_lookup(kcd->facetrimap, f)) + return; + + BLI_assert(index >= 0 && index < kcd->em->tottri); + BLI_assert(kcd->em->looptris[index][0]->f == f); + for (i = index - 1; i >= 0; i--) { + if (kcd->em->looptris[i][0]->f != f) { + i++; + break; + } + } + if (i == -1) + i++; + + BLI_ghash_insert(kcd->facetrimap, f, SET_INT_IN_POINTER(i + 1)); +} + +/* This should only be called for faces that have had a lowest face tri set by previous function */ +static int get_lowest_face_tri(KnifeTool_OpData *kcd, BMFace *f) +{ + int ans; + + ans = GET_INT_FROM_POINTER(BLI_ghash_lookup(kcd->facetrimap, f)); + BLI_assert(ans != 0); + return ans - 1; +} + /* User has just clicked for first time or first time after a restart (E key). * Copy the current position data into prev. */ static void knife_start_cut(KnifeTool_OpData *kcd) @@ -400,7 +446,7 @@ static void knife_start_cut(KnifeTool_OpData *kcd) BMVert *v0; knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, origin, origin_ofs); - v0 = BM_vert_at_index(kcd->em->bm, 0); + v0 = BM_vert_at_index_find(kcd->em->bm, 0); if (v0) { closest_to_line_v3(kcd->prev.cage, v0->co, origin_ofs, origin); copy_v3_v3(kcd->prev.co, kcd->prev.cage); /*TODO: do we need this? */ @@ -430,12 +476,6 @@ static ListBase *knife_get_face_kedges(KnifeTool_OpData *kcd, BMFace *f) return lst; } -/* finds the proper face to restrict face fill to */ -static void knife_find_basef(KnifeEdge *kfe) -{ - kfe->basef = knife_find_common_face(&kfe->v1->faces, &kfe->v2->faces); -} - static void knife_edge_append_face(KnifeTool_OpData *kcd, KnifeEdge *kfe, BMFace *f) { knife_append_list(kcd, knife_get_face_kedges(kcd, f), kfe); @@ -493,471 +533,272 @@ static KnifeVert *knife_split_edge(KnifeTool_OpData *kcd, KnifeEdge *kfe, float return newkfe->v2; } -/* Make a single KnifeEdge for cut from kcd->prev to kcd->curr. - * and move cur data to prev. */ -static void knife_add_single_cut(KnifeTool_OpData *kcd) +/* primary key: lambda along cut + * secondary key: lambda along depth + * tertiary key: pointer comparisons of verts if both snapped to verts + */ +static int linehit_compare(const void *vlh1, const void *vlh2) { - KnifeEdge *kfe, *kfe2 = NULL, *kfe3 = NULL; + const KnifeLineHit *lh1 = vlh1; + const KnifeLineHit *lh2 = vlh2; - if ((kcd->prev.vert && kcd->prev.vert == kcd->curr.vert) || - (kcd->prev.edge && kcd->prev.edge == kcd->curr.edge)) - { - kcd->prev = kcd->curr; - return; - } - - kfe = new_knife_edge(kcd); - kfe->draw = true; - - if (kcd->prev.vert) { - kfe->v1 = kcd->prev.vert; - } - else if (kcd->prev.edge) { - kfe->v1 = knife_split_edge(kcd, kcd->prev.edge, kcd->prev.co, &kfe2); - } + if (lh1->l < lh2->l) return -1; + else if (lh1->l > lh2->l) return 1; else { - kfe->v1 = new_knife_vert(kcd, kcd->prev.co, kcd->prev.co); - kfe->v1->draw = kfe->draw = !kcd->prev.is_space; - kfe->v1->in_space = kcd->prev.is_space; - kfe->draw = !kcd->prev.is_space; - kfe->v1->is_face = true; - if (kfe->v1->draw && kcd->prev.bmface) - knife_append_list(kcd, &kfe->v1->faces, kcd->prev.bmface); + if (lh1->m < lh2->m) return -1; + else if (lh1->m > lh2->m) return 1; + else { + if (lh1->v < lh2->v) return -1; + else if (lh1->v > lh2->v) return 1; + else return 0; + } } +} - if (kcd->curr.vert) { - kfe->v2 = kcd->curr.vert; - } - else if (kcd->curr.edge) { - kfe->v2 = knife_split_edge(kcd, kcd->curr.edge, kcd->curr.co, &kfe3); - kcd->curr.vert = kfe->v2; - } - else { - kfe->v2 = new_knife_vert(kcd, kcd->curr.co, kcd->curr.co); - kfe->v2->draw = !kcd->curr.is_space; - kfe->v2->is_face = true; - kfe->v2->in_space = kcd->curr.is_space; - if (kfe->v2->draw && kcd->curr.bmface) - knife_append_list(kcd, &kfe->v2->faces, kcd->curr.bmface); +/* + * Sort linehits by distance along cut line, and secondarily from + * front to back (from eye), and tertiarily by snap vertex, + * and remove any duplicates. + */ +static void prepare_linehits_for_cut(KnifeTool_OpData *kcd) +{ + KnifeLineHit *linehits, *lhi, *lhj; + int i, j, n; - if (kcd->curr.is_space) - kfe->draw = false; + n = kcd->totlinehit; + linehits = kcd->linehits; + if (n == 0) + return; - kcd->curr.vert = kfe->v2; + qsort(linehits, n, sizeof(KnifeLineHit), linehit_compare); + + /* Remove any edge hits that are preceded or followed + * by a vertex hit that is very near. Mark such edge hits using + * l == -1 and then do another pass to actually remove. + * Also remove all but one of a series of vertex hits for the same vertex. */ + for (i = 0; i < n; i++) { + lhi = &linehits[i]; + if (lhi->v) { + for (j = i - 1; j >= 0; j--) { + lhj = &linehits[j]; + if (!lhj->kfe || + fabsf(lhi->l - lhj->l) > KNIFE_FLT_EPSBIG || + fabsf(lhi->m - lhj->m) > KNIFE_FLT_EPSBIG) + { + break; + } + lhj->l = -1.0f; + } + for (j = i + 1; j < n; j++) { + lhj = &linehits[j]; + if (fabsf(lhi->l - lhj->l) > KNIFE_FLT_EPSBIG || + fabsf(lhi->m - lhj->m) > KNIFE_FLT_EPSBIG) + { + break; + } + if (lhj->kfe || lhi->v == lhj->v) { + lhj->l = -1.0f; + } + } + } } - knife_find_basef(kfe); - - knife_add_to_vert_edges(kcd, kfe); - - if (kfe->basef && !find_ref(&kfe->faces, kfe->basef)) - knife_edge_append_face(kcd, kfe, kfe->basef); - - /* sanity check to make sure we're in the right edge/face lists */ - if (kcd->curr.bmface) { - if (!find_ref(&kfe->faces, kcd->curr.bmface)) { - knife_edge_append_face(kcd, kfe, kcd->curr.bmface); + /* delete-in-place loop: copying from pos j to pos i+1 */ + i = 0; + j = 1; + while (j < n) { + lhi = &linehits[i]; + lhj = &linehits[j]; + if (lhj->l == -1.0f) { + j++; /* skip copying this one */ } - - if (kcd->prev.bmface && kcd->prev.bmface != kcd->curr.bmface) { - if (!find_ref(&kfe->faces, kcd->prev.bmface)) { - knife_edge_append_face(kcd, kfe, kcd->prev.bmface); + else { + /* copy unless a no-op */ + if (lhi->l == -1.0f) { + /* could happen if linehits[0] is being deleted */ + memcpy(&linehits[i], &linehits[j], sizeof(KnifeLineHit)); } + else { + if (i + 1 != j) + memcpy(&linehits[i + 1], &linehits[j], sizeof(KnifeLineHit)); + i++; + } + j++; } } - - /* set up for next cut */ - kcd->prev = kcd->curr; + kcd->totlinehit = i + 1; } -static int verge_linehit(const void *vlh1, const void *vlh2) +/* Add hit to list of hits in facehits[f], where facehits is a map, if not already there */ +static void add_hit_to_facehits(KnifeTool_OpData *kcd, GHash *facehits, BMFace *f, KnifeLineHit *hit) { - const BMEdgeHit *lh1 = vlh1, *lh2 = vlh2; + ListBase *lst = BLI_ghash_lookup(facehits, f); - if (lh1->l < lh2->l) return -1; - else if (lh1->l > lh2->l) return 1; - else if (lh1->v && lh2->v) { - /* want like verts to sort together; just compare pointers */ - if (lh1->v < lh2->v) return -1; - else if (lh1->v > lh2->v) return 1; - else return 0; + if (!lst) { + lst = knife_empty_list(kcd); + BLI_ghash_insert(facehits, f, lst); } - else return 0; + knife_append_list_no_dup(kcd, lst, hit); } -/* If there's a linehit connected (same face) as testi in range [firsti, lasti], return the first such, else -1. - * It also counts as connected if both linehits are snapped to the same vertex. - * If testi is out of range, look for connection to f instead, if f is non-NULL */ -static int find_connected_linehit(KnifeTool_OpData *kcd, int testi, BMFace *f, int firsti, int lasti) +static void knife_add_single_cut(KnifeTool_OpData *kcd, KnifeLineHit *lh1, KnifeLineHit *lh2, BMFace *f) { - int i; - ListBase *testfaces, *ifaces; - BMFace *testface, *iface; - BMEdgeHit *lh; - bool shareface; - - if (testi >= 0 && testi < kcd->totlinehit) { - testface = NULL; - testfaces = NULL; - lh = &kcd->linehits[testi]; - if (lh->v) - testfaces = &lh->v->faces; - else if (lh->kfe) - testfaces = &lh->kfe->faces; - else if (lh->f) { - testfaces = NULL; - testface = lh->f; - } - } - else { - testface = f; - testfaces = NULL; - } - for (i = firsti; i <= lasti; i++) { - shareface = false; - lh = &kcd->linehits[i]; - iface = NULL; - ifaces = NULL; - if (lh->v) - ifaces = &lh->v->faces; - else if (lh->kfe) - ifaces = &lh->kfe->faces; - else if (lh->f) { - ifaces = NULL; - iface = lh->f; - } - if (testfaces) { - if (ifaces) - shareface = (knife_find_common_face(testfaces, ifaces) != NULL); - else if (iface) - shareface = (find_ref(testfaces, iface) != NULL); - } - else if (ifaces) { - if (testface) - shareface = (find_ref(ifaces, testface) != NULL); - } - else if (testface && iface) { - shareface = (testface == iface); - } - if (shareface) - return i; - } - return -1; -} - -/* Sort in order of distance along cut line. - * Remove any successive linehits that are snapped to the same vertex. - * If joinfaces, treat hits at same distance as follows: try to find - * ordering so that preceding and succeeding hits will share a face. - */ -static void knife_sort_linehits(KnifeTool_OpData *kcd, bool joinfaces) -{ - int i, j, k, nexti, nsame; + KnifeEdge *kfe, *kfe2; - qsort(kcd->linehits, kcd->totlinehit, sizeof(BMEdgeHit), verge_linehit); + if ((lh1->v && lh1->v == lh2->v) || + (lh1->kfe && lh1->kfe == lh2->kfe)) + { + return; + } - /* Remove duplicated linehits snapped to same vertex */ - i = j = 0; /* loop copies from j to i */ - while (j < kcd->totlinehit) { - nsame = 0; - if (kcd->linehits[j].v) { - for (k = j + 1; k < kcd->totlinehit; k++) { - if (kcd->linehits[k].v != kcd->linehits[j].v) - break; - nsame++; - } + /* Check if edge actually lies within face (might not, if this face is concave) */ + if (lh1->v && lh2->v) { + if (!knife_verts_edge_in_face(lh1->v, lh2->v, f)) { + return; } - if (i != j) - kcd->linehits[i] = kcd->linehits[j]; - i++; - j += 1 + nsame; } - kcd->totlinehit = i; - if (!joinfaces) - return; + kfe = new_knife_edge(kcd); + kfe->draw = true; + kfe->basef = f; - /* for ranges of equal "l", swap if neccesary to make predecessor and - * successor faces connected to the linehits at either end of the range */ - for (i = 0; i < kcd->totlinehit - 1; i = nexti) { - for (j = i + 1; j < kcd->totlinehit; j++) { - if (fabsf(kcd->linehits[j].l - kcd->linehits[i].l) > KNIFE_FLT_EPS) - break; - } - nexti = j; - j--; - nsame = j - i; - if (nsame > 0) { - /* find something connected to predecessor of equal range */ - k = find_connected_linehit(kcd, i - 1, kcd->prev.bmface, i, j); - if (k != -1) { - if (k != i) { - SWAP(BMEdgeHit, kcd->linehits[i], kcd->linehits[k]); - } - i++; - nsame--; - } - if (nsame > 0) { - /* find something connected to successor of equal range */ - k = find_connected_linehit(kcd, j + 1, kcd->curr.bmface, i, j); - if (k != -1 && k != j) { - SWAP(BMEdgeHit, kcd->linehits[j], kcd->linehits[k]); - } - } - /* rest of same range doesn't matter because we won't connect them */ - } + if (lh1->v) { + kfe->v1 = lh1->v; + } + else if (lh1->kfe) { + kfe->v1 = knife_split_edge(kcd, lh1->kfe, lh1->cagehit, &kfe2); + lh1->v = kfe->v1; /* record the KnifeVert for this hit */ + } + else { + BLI_assert(lh1->f); + kfe->v1 = new_knife_vert(kcd, lh1->hit, lh1->cagehit); + kfe->v1->draw = true; + kfe->v1->is_face = true; + knife_append_list(kcd, &kfe->v1->faces, lh1->f); + lh1->v = kfe->v1; /* record the KnifeVert for this hit */ } -} -static void knife_add_single_cut_through(KnifeTool_OpData *kcd, KnifeVert *v1, KnifeVert *v2, BMFace *f) -{ - KnifeEdge *kfenew; + if (lh2->v) { + kfe->v2 = lh2->v; + } + else if (lh2->kfe) { + kfe->v2 = knife_split_edge(kcd, lh2->kfe, lh2->cagehit, &kfe2); + lh2->v = kfe->v2; /* future uses of lh2 won't split again */ + } + else { + BLI_assert(lh2->f); + kfe->v2 = new_knife_vert(kcd, lh2->hit, lh2->cagehit); + kfe->v2->draw = true; + kfe->v2->is_face = true; + knife_append_list(kcd, &kfe->v2->faces, lh2->f); + lh2->v = kfe->v2; /* record the KnifeVert for this hit */ + } - kfenew = new_knife_edge(kcd); - kfenew->basef = f; - kfenew->v1 = v1; - kfenew->v2 = v2; - kfenew->draw = true; + knife_add_to_vert_edges(kcd, kfe); - knife_add_to_vert_edges(kcd, kfenew); + /* TODO: check if this is ever needed */ + if (kfe->basef && !find_ref(&kfe->faces, kfe->basef)) + knife_edge_append_face(kcd, kfe, kfe->basef); - if (!find_ref(&kfenew->faces, f)) - knife_edge_append_face(kcd, kfenew, f); } -#if 0 -static void knife_get_vert_faces(KnifeTool_OpData *kcd, KnifeVert *kfv, BMFace *facef, ListBase *lst) +/* Given a list of KnifeLineHits for one face, sorted by l + * and then by m, make the required KnifeVerts and + * KnifeEdges. + */ +static void knife_cut_face(KnifeTool_OpData *kcd, BMFace *f, ListBase *hits) { - BMIter bmiter; - BMFace *f; Ref *r; + KnifeLineHit *lh, *prevlh; + int n; - if (kfv->is_face && facef) { - knife_append_list(kcd, lst, facef); - } - else if (kfv->v) { - BM_ITER_ELEM (f, &bmiter, kfv->v, BM_FACES_OF_VERT) { - knife_append_list(kcd, lst, f); - } - } - else { - for (r = kfv->faces.first; r; r = r->next) { - knife_append_list(kcd, lst, r->ref); - } - } -} + (void) kcd; -static void knife_get_edge_faces(KnifeTool_OpData *kcd, KnifeEdge *kfe, ListBase *lst) -{ - BMIter bmiter; - BMFace *f; + n = BLI_countlist(hits); + if (n < 2) + return; - if (kfe->e) { - BM_ITER_ELEM (f, &bmiter, kfe->e, BM_FACES_OF_EDGE) { - knife_append_list(kcd, lst, f); - } + prevlh = NULL; + for (r = hits->first; r; r = r->next) { + lh = (KnifeLineHit *)r->ref; + if (prevlh) + knife_add_single_cut(kcd, prevlh, lh, f); + prevlh = lh; } -} -#endif -static void copy_hit_from_posdata(BMEdgeHit *lh, KnifePosData *pos, float lambda) -{ - lh->kfe = pos->edge; - lh->v = pos->vert; - lh->f = pos->bmface; - copy_v3_v3(lh->hit, pos->co); - copy_v3_v3(lh->cagehit, pos->cage); - copy_v3_v3(lh->realhit, pos->co); - lh->l = lambda; - /* perc and schit not used by callers of this function */ } -/* BMESH_TODO: add more functionality to cut-through: - * - cutting "in face" (e.g., holes) should cut in all faces, not just visible one - * - perhaps improve O(n^2) algorithm used here */ -static void knife_cut_through(KnifeTool_OpData *kcd) +/* User has just left-clicked after the first time. + * Add all knife cuts implied by line from prev to curr. + * If that line crossed edges then kcd->linehits will be non-NULL. + * Make all of the KnifeVerts and KnifeEdges implied by this cut. + */ +static void knife_add_cut(KnifeTool_OpData *kcd) { - BMEdgeHit *lh, *lh2, *linehits; + int i; + KnifeLineHit *lh; + GHash *facehits; BMFace *f; - KnifeEdge *kfe, *kfe2; - KnifeVert *v1, *v2, *lastv; - ListBase *faces1, *faces2; - KnifeEdge **splitkfe; - bool needprev, needcurr; - int i, j, n; + Ref *r; + GHashIterator giter; + ListBase *lst; - if (!kcd->totlinehit) { - /* if no linehits then no interesting back face stuff to do */ - knife_add_single_cut(kcd); + prepare_linehits_for_cut(kcd); + if (kcd->totlinehit == 0) { + kcd->prev = kcd->curr; return; } - /* sort eliminates hits on same vertices */ - knife_sort_linehits(kcd, false); - - /* code is cleaner if make prev and curr into hits (if they are on edges or verts) */ - n = kcd->totlinehit; - needprev = ((kcd->prev.vert && kcd->prev.vert != kcd->linehits[0].v) || kcd->prev.edge); - needcurr = ((kcd->curr.vert && kcd->curr.vert != kcd->linehits[n - 1].v) || kcd->curr.edge); - n += needprev + needcurr; - linehits = MEM_callocN(n * sizeof(BMEdgeHit), "knife_cut_through"); - i = 0; - if (needprev) { - copy_hit_from_posdata(&linehits[0], &kcd->prev, 0.0f); - i++; - } - memcpy(linehits + i, kcd->linehits, kcd->totlinehit * sizeof(BMEdgeHit)); - i += kcd->totlinehit; - if (needcurr) - copy_hit_from_posdata(&linehits[i], &kcd->curr, 1.0f); - - - splitkfe = MEM_callocN(n * sizeof(KnifeEdge *), "knife_cut_through"); - - lastv = NULL; - for (i = 0, lh = linehits; i < n; i++, lh++) { - kfe = lh->kfe; - v1 = NULL; - - /* get faces incident on hit lh */ + /* make facehits: map face -> list of linehits touching it */ + facehits = BLI_ghash_ptr_new("knife facehits"); + for (i = 0; i < kcd->totlinehit; i++) { + lh = &kcd->linehits[i]; + if (lh->f) { + add_hit_to_facehits(kcd, facehits, lh->f, lh); + } if (lh->v) { - v1 = lh->v; - faces1 = &v1->faces; + for (r = lh->v->faces.first; r; r = r->next) { + add_hit_to_facehits(kcd, facehits, r->ref, lh); + } } - else if (kfe) { - faces1 = &kfe->faces; + if (lh->kfe) { + for (r = lh->kfe->faces.first; r; r = r->next) { + add_hit_to_facehits(kcd, facehits, r->ref, lh); + } } + } - /* For each following hit, connect if lh1 an lh2 share a face */ - for (j = i + 1, lh2 = lh + 1; j < n; j++, lh2++) { - kfe2 = lh2->kfe; - v2 = NULL; - if (lh2->v) { - v2 = lh2->v; - faces2 = &v2->faces; - } - else if (kfe2) { - faces2 = &kfe2->faces; - } + /* Note: as following loop progresses, the 'v' fields of + * the linehits will be filled in (as edges are split or + * in-face verts are made), so it may be true that both + * the v and the kfe or f fields will be non-NULL. */ + GHASH_ITER (giter, facehits) { + f = (BMFace *)BLI_ghashIterator_getKey(&giter); + lst = (ListBase *)BLI_ghashIterator_getValue(&giter); + knife_cut_face(kcd, f, lst); + } - f = knife_find_common_face(faces1, faces2); - if (f) { - if (!v1) - v1 = splitkfe[i] ? kfe->v1 : knife_split_edge(kcd, kfe, lh->hit, &splitkfe[i]); - if (!v2) - v2 = splitkfe[j] ? kfe2->v1 : knife_split_edge(kcd, kfe2, lh2->hit, &splitkfe[j]); - knife_add_single_cut_through(kcd, v1, v2, f); - lastv = v2; - } - } + /* set up for next cut */ + kcd->prev = kcd->curr; + if (kcd->prev.bmface) { + /* was "in face" but now we have a KnifeVert it is snapped to */ + kcd->prev.bmface = NULL; + kcd->prev.vert = kcd->linehits[kcd->totlinehit - 1].v; } - MEM_freeN(splitkfe); - MEM_freeN(linehits); + BLI_ghash_free(facehits, NULL, NULL); MEM_freeN(kcd->linehits); kcd->linehits = NULL; kcd->totlinehit = 0; - - /* set up for next cut */ - kcd->curr.vert = lastv; - kcd->prev = kcd->curr; } -/* User has just left-clicked after the first time. - * Add all knife cuts implied by line from prev to curr. - * If that line crossed edges then kcd->linehits will be non-NULL. */ -static void knife_add_cut(KnifeTool_OpData *kcd) +static void knife_finish_cut(KnifeTool_OpData *kcd) { - KnifePosData savcur = kcd->curr; - - if (kcd->cut_through) { - knife_cut_through(kcd); - } - else if (kcd->linehits) { - BMEdgeHit *lh, *lastlh, *firstlh; - int i; - - knife_sort_linehits(kcd, true); - - lh = kcd->linehits; - lastlh = firstlh = NULL; - for (i = 0; i < kcd->totlinehit; i++, (lastlh = lh), lh++) { - BMFace *f = lastlh ? lastlh->f : lh->f; - - if (lastlh && len_squared_v3v3(lastlh->hit, lh->hit) == 0.0f) { - if (!firstlh) - firstlh = lastlh; - continue; - } - else if (lastlh && firstlh) { - if (firstlh->v || lastlh->v) { - KnifeVert *kfv = firstlh->v ? firstlh->v : lastlh->v; - - kcd->prev.vert = kfv; - copy_v3_v3(kcd->prev.co, firstlh->hit); - copy_v3_v3(kcd->prev.cage, firstlh->cagehit); - kcd->prev.edge = NULL; - kcd->prev.bmface = f; - /* TODO: should we set prev.in_space = 0 ? */ - } - lastlh = firstlh = NULL; - } - - if (len_squared_v3v3(kcd->prev.cage, lh->realhit) < KNIFE_FLT_EPS_SQUARED) - continue; - if (len_squared_v3v3(kcd->curr.cage, lh->realhit) < KNIFE_FLT_EPS_SQUARED) - continue; - - /* first linehit may be down face parallel to view */ - if (!lastlh && !lh->v && fabsf(lh->l) < KNIFE_FLT_EPS) - continue; - - if (kcd->prev.is_space) { - kcd->prev.is_space = 0; - copy_v3_v3(kcd->prev.co, lh->hit); - copy_v3_v3(kcd->prev.cage, lh->cagehit); - kcd->prev.vert = lh->v; - kcd->prev.edge = lh->kfe; - kcd->prev.bmface = lh->f; - continue; - } - - kcd->curr.is_space = 0; - kcd->curr.edge = lh->kfe; - kcd->curr.bmface = lh->f; - kcd->curr.vert = lh->v; - copy_v3_v3(kcd->curr.co, lh->hit); - copy_v3_v3(kcd->curr.cage, lh->cagehit); - - /* don't draw edges down faces parallel to view */ - if (lastlh && fabsf(lastlh->l - lh->l) < KNIFE_FLT_EPS) { - kcd->prev = kcd->curr; - continue; - } - - knife_add_single_cut(kcd); - } - - if (savcur.is_space) { - kcd->prev = savcur; - } - else { - kcd->curr = savcur; - knife_add_single_cut(kcd); - } - + if (kcd->linehits) { MEM_freeN(kcd->linehits); kcd->linehits = NULL; kcd->totlinehit = 0; } - else { - knife_add_single_cut(kcd); - } -} - -static void knife_finish_cut(KnifeTool_OpData *UNUSED(kcd)) -{ - } static void knifetool_draw_angle_snapping(const KnifeTool_OpData *kcd) @@ -1101,6 +942,24 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) glLineWidth(1.0); } + if (kcd->prev.vert) { + glColor3ubv(kcd->colors.point); + glPointSize(11); + + glBegin(GL_POINTS); + glVertex3fv(kcd->prev.cage); + glEnd(); + } + + if (kcd->prev.bmface) { + glColor3ubv(kcd->colors.curpoint); + glPointSize(9); + + glBegin(GL_POINTS); + glVertex3fv(kcd->prev.cage); + glEnd(); + } + if (kcd->curr.edge) { glColor3ubv(kcd->colors.edge); glLineWidth(2.0); @@ -1131,10 +990,7 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) } if (kcd->totlinehit > 0) { - const float vthresh4 = kcd->vthresh / 4.0f; - const float vthresh4_sq = vthresh4 * vthresh4; - - BMEdgeHit *lh; + KnifeLineHit *lh; int i; glEnable(GL_BLEND); @@ -1146,22 +1002,8 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) glBegin(GL_POINTS); lh = kcd->linehits; for (i = 0; i < kcd->totlinehit; i++, lh++) { - float sv1[2], sv2[2]; - - knife_project_v2(kcd, lh->kfe->v1->cageco, sv1); - knife_project_v2(kcd, lh->kfe->v2->cageco, sv2); - knife_project_v2(kcd, lh->cagehit, lh->schit); - - if (len_squared_v2v2(lh->schit, sv1) < vthresh4_sq) { - copy_v3_v3(lh->cagehit, lh->kfe->v1->cageco); - glVertex3fv(lh->cagehit); - lh->v = lh->kfe->v1; - } - else if (len_squared_v2v2(lh->schit, sv2) < vthresh4_sq) { - copy_v3_v3(lh->cagehit, lh->kfe->v2->cageco); + if (lh->v) glVertex3fv(lh->cagehit); - lh->v = lh->kfe->v2; - } } glEnd(); @@ -1171,7 +1013,8 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) glBegin(GL_POINTS); lh = kcd->linehits; for (i = 0; i < kcd->totlinehit; i++, lh++) { - glVertex3fv(lh->cagehit); + if (!lh->v) + glVertex3fv(lh->cagehit); } glEnd(); glDisable(GL_BLEND); @@ -1224,274 +1067,72 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) if (v3d->zbuf) glEnable(GL_DEPTH_TEST); } -static float len_v3_tri_side_max(const float v1[3], const float v2[3], const float v3[3]) -{ - const float s1 = len_squared_v3v3(v1, v2); - const float s2 = len_squared_v3v3(v2, v3); - const float s3 = len_squared_v3v3(v3, v1); - - return sqrtf(max_fff(s1, s2, s3)); -} - -/** - * given a tri, return 3 planes aligned with the tri's normal. - * - * If the triangle were extruded along its normal, - * the planes calculated would be the 3 sides around the extrusion. - */ -static void plane_from_tri_clip3_v3( - float tri_plane_clip[3][4], - const float v0[3], const float v1[3], const float v2[3]) -{ - float tri_norm[3]; - float tvec[3], cross[3]; - - normal_tri_v3(tri_norm, v0, v1, v2); - - sub_v3_v3v3(tvec, v0, v1); - cross_v3_v3v3(cross, tvec, tri_norm); - plane_from_point_normal_v3(tri_plane_clip[0], v0, cross); - - sub_v3_v3v3(tvec, v1, v2); - cross_v3_v3v3(cross, tvec, tri_norm); - plane_from_point_normal_v3(tri_plane_clip[1], v1, cross); - - sub_v3_v3v3(tvec, v2, v0); - cross_v3_v3v3(cross, tvec, tri_norm); - plane_from_point_normal_v3(tri_plane_clip[2], v2, cross); -} - -/** - * Given a line that is planar with a tri, clip the segment by that tri. - * - * This is needed so we end up with both points in the triangle. - */ -static bool isect_line_tri_coplanar_v3( - const float p1[3], const float p2[3], - const float v0[3], const float v1[3], const float v2[3], - float r_isects[2][3], - - /* avoid re-calculating every time */ - float tri_plane[4], float tri_plane_clip[3][4]) -{ - float p1_tmp[3] = {UNPACK3(p1)}; - float p2_tmp[3] = {UNPACK3(p2)}; - - (void)v0, (void)v1, (void)v2; - - /* first check if the points are planar with the tri */ - if ((fabsf(dist_squared_to_plane_v3(p1, tri_plane)) < KNIFE_FLT_EPS_SQUARED) && - (fabsf(dist_squared_to_plane_v3(p2, tri_plane)) < KNIFE_FLT_EPS_SQUARED) && - /* clip the segment by planes around the triangle so we can be sure the points - * aren't outside the triangle */ - (clip_segment_v3_plane_n(p1_tmp, p2_tmp, tri_plane_clip, 3))) - { - copy_v3_v3(r_isects[0], p1_tmp); - copy_v3_v3(r_isects[1], p2_tmp); - - return true; - } - else { - return false; - } -} - -static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree, - const float v1[3], const float v2[3], const float v3[3], - SmallHash *ehash, bglMats *mats, int *count) -{ - BVHTree *tree2 = BLI_bvhtree_new(3, FLT_EPSILON * 4, 8, 8), *tree = BKE_bmbvh_tree_get(bmtree); - BMEdgeHit *edges = NULL; - BLI_array_declare(edges); - BVHTreeOverlap *results, *result; - BMLoop **ls; - float cos[9], tri_norm[3], tri_plane[4], isects[2][3], lambda; - float tri_plane_clip[3][4]; - unsigned int tot = 0; - int i, j, n_isects; - - - /* for comparing distances, error of intersection depends on triangle scale. - * need to scale down before squaring for accurate comparison */ - const float depsilon = (FLT_EPSILON / 2.0f) * len_v3_tri_side_max(v1, v2, v3); - const float depsilon_sq = depsilon * depsilon; - - copy_v3_v3(cos + 0, v1); - copy_v3_v3(cos + 3, v2); - copy_v3_v3(cos + 6, v3); - - /* avoid re-calculation in #isect_line_tri_coplanar_v3 */ - normal_tri_v3(tri_norm, v1, v2, v3); - plane_from_point_normal_v3(tri_plane, v1, tri_norm); - plane_from_tri_clip3_v3(tri_plane_clip, v1, v2, v3); - - BLI_bvhtree_insert(tree2, 0, cos, 3); - BLI_bvhtree_balance(tree2); - - result = results = BLI_bvhtree_overlap(tree, tree2, &tot); - - for (i = 0; i < tot; i++, result++) { - BMLoop *l1; - BMFace *f_hit; - ListBase *lst; - Ref *ref; - - ls = (BMLoop **)kcd->em->looptris[result->indexA]; - - l1 = ls[0]; - lst = knife_get_face_kedges(kcd, l1->f); - - for (ref = lst->first; ref; ref = ref->next) { - KnifeEdge *kfe = ref->ref; - - if (BLI_smallhash_haskey(ehash, (uintptr_t)kfe)) { - continue; /* We already found a hit on this knife edge */ - } +/* Find intersection of v1-v2 with face f. + * Only take intersections that are at least face_tol (in screen space) away + * from other intersection elements. + * If v1-v2 is coplanar with f, call that "no intersection though + * it really means "infinite number of intersections". + * In such a case we should have gotten hits on edges or verts of the face. */ +static bool knife_ray_intersect_face(KnifeTool_OpData *kcd, + const float s[2], + const float v1[2], const float v2[2], + BMFace *f, + const float face_tol, + float intersectp[3]) +{ + int tottri, tri_i; + float lv1[3], lv2[3], lv3[3], raydir[3]; + float tri_norm[3], tri_plane[4]; + float se1[2], se2[2]; + float d, lambda; + BMLoop **tri; + ListBase *lst; + Ref *ref; + KnifeEdge *kfe; - n_isects = 0; + sub_v3_v3v3(raydir, v2, v1); + normalize_v3(raydir); + tri_i = get_lowest_face_tri(kcd, f); + tottri = kcd->em->tottri; + BLI_assert(tri_i >= 0 && tri_i < tottri); - if (isect_line_tri_coplanar_v3(kfe->v1->cageco, kfe->v2->cageco, v1, v2, v3, - isects, - /* cached values */ - tri_plane, tri_plane_clip)) - { - /* both kfe ends are in cutting triangle */ - n_isects = 2; - } - else if (isect_line_tri_epsilon_v3(kfe->v1->cageco, kfe->v2->cageco, v1, v2, v3, - &lambda, NULL, depsilon)) + for (; tri_i < tottri; tri_i++) { + tri = kcd->em->looptris[tri_i]; + if (tri[0]->f != f) + break; + copy_v3_v3(lv1, kcd->cagecos[BM_elem_index_get(tri[0]->v)]); + copy_v3_v3(lv2, kcd->cagecos[BM_elem_index_get(tri[1]->v)]); + copy_v3_v3(lv3, kcd->cagecos[BM_elem_index_get(tri[2]->v)]); + /* using epsilon test in case ray is directly through an internal + * tesselation edge and might not hit either tesselation tri with + * an exact test; + * we will exclude hits near real edges by a later test */ + if (isect_ray_tri_epsilon_v3(v1, raydir, lv1, lv2, lv3, &lambda, NULL, KNIFE_FLT_EPS)) { + /* check if line coplanar with tri */ + normal_tri_v3(tri_norm, lv1, lv2, lv3); + plane_from_point_normal_v3(tri_plane, lv1, tri_norm); + if ((fabsf(dist_squared_to_plane_v3(v1, tri_plane)) < KNIFE_FLT_EPS) && + (fabsf(dist_squared_to_plane_v3(v2, tri_plane)) < KNIFE_FLT_EPS)) { - /* kfe intersects cutting triangle lambda of the way along kfe */ - interp_v3_v3v3(isects[0], kfe->v1->cageco, kfe->v2->cageco, lambda); - n_isects = 1; + return false; } - - for (j = 0; j < n_isects; j++) { - float p[3]; - - copy_v3_v3(p, isects[j]); - if (kcd->curr.vert && len_squared_v3v3(kcd->curr.vert->cageco, p) < depsilon_sq) { - continue; - } - if (kcd->prev.vert && len_squared_v3v3(kcd->prev.vert->cageco, p) < depsilon_sq) { - continue; - } - if (len_squared_v3v3(kcd->prev.cage, p) < depsilon_sq || - len_squared_v3v3(kcd->curr.cage, p) < depsilon_sq) - { - continue; - } - if ((kcd->vc.rv3d->rflag & RV3D_CLIPPING) && - ED_view3d_clipping_test(kcd->vc.rv3d, p, true)) - { - continue; - } - - if (kcd->cut_through) { - f_hit = NULL; - } - else { - /* check if this point is visible in the viewport */ - float p1[3], no[3], view[3], sp[2]; - float lambda1; - - /* screen projection */ - knife_project_v2(kcd, p, sp); - ED_view3d_unproject(mats, view, sp[0], sp[1], 0.0f); - mul_m4_v3(kcd->ob->imat, view); - - /* if face isn't planer, p may be behind the current tesselated tri, - * so move it onto that and then a little towards eye */ - if (isect_line_tri_v3(p, view, ls[0]->v->co, ls[1]->v->co, ls[2]->v->co, &lambda1, NULL)) { - interp_v3_v3v3(p1, p, view, lambda1); - } - else { - copy_v3_v3(p1, p); - } - sub_v3_v3(view, p1); - normalize_v3(view); - - copy_v3_v3(no, view); - mul_v3_fl(no, 0.003); - - /* go towards view a bit */ - add_v3_v3(p1, no); - - /* ray cast */ - f_hit = BKE_bmbvh_ray_cast(bmtree, p1, no, KNIFE_FLT_EPS, NULL, NULL, NULL); - } - - /* ok, if visible add the new point */ - if (!f_hit && !BLI_smallhash_haskey(ehash, (uintptr_t)kfe)) { - BMEdgeHit hit; - - if (len_squared_v3v3(p, kcd->curr.co) < depsilon_sq || - len_squared_v3v3(p, kcd->prev.co) < depsilon_sq) - { - continue; - } - - hit.kfe = kfe; - hit.v = NULL; - hit.l = 0.0f; - - knife_find_basef(kfe); - hit.f = kfe->basef; - hit.perc = len_v3v3(p, kfe->v1->cageco) / len_v3v3(kfe->v1->cageco, kfe->v2->cageco); - copy_v3_v3(hit.cagehit, p); - - interp_v3_v3v3(p, kfe->v1->co, kfe->v2->co, hit.perc); - copy_v3_v3(hit.realhit, p); - - if (kcd->snap_midpoints) { - float perc = hit.perc; - - /* select the closest from the edge endpoints or the midpoint */ - if (perc < 0.25f) { - perc = 0.0f; - } - else if (perc < 0.75f) { - perc = 0.5f; - } - else { - perc = 1.0f; - } - - interp_v3_v3v3(hit.hit, kfe->v1->co, kfe->v2->co, perc); - interp_v3_v3v3(hit.cagehit, kfe->v1->cageco, kfe->v2->cageco, perc); - } - else if (hit.perc < KNIFE_FLT_EPS || hit.perc > 1.0f - KNIFE_FLT_EPS) { - /* snap to vert */ - hit.v = (hit.perc < KNIFE_FLT_EPS) ? kfe->v1 : kfe->v2; - copy_v3_v3(hit.hit, hit.v->co); - copy_v3_v3(hit.cagehit, hit.v->co); - } - else { - copy_v3_v3(hit.hit, p); - } - knife_project_v2(kcd, hit.cagehit, hit.schit); - - BLI_array_append(edges, hit); - BLI_smallhash_insert(ehash, (uintptr_t)kfe, NULL); + copy_v3_v3(intersectp, v1); + madd_v3_v3fl(intersectp, raydir, lambda); + /* Now check that far enough away from verts and edges */ + lst = knife_get_face_kedges(kcd, f); + for (ref = lst->first; ref; ref = ref->next) { + kfe = ref->ref; + knife_project_v2(kcd, kfe->v1->cageco, se1); + knife_project_v2(kcd, kfe->v2->cageco, se2); + d = dist_to_line_segment_v2(s, se1, se2); + if (d < face_tol) { + return false; } } + return true; } } - - if (results) - MEM_freeN(results); - - BLI_bvhtree_free(tree2); - *count = BLI_array_count(edges); - - return edges; -} - -static void knife_bgl_get_mats(KnifeTool_OpData *UNUSED(kcd), bglMats *mats) -{ - bgl_get_mats(mats); - //copy_m4_m4(mats->modelview, kcd->vc.rv3d->viewmat); - //copy_m4_m4(mats->projection, kcd->vc.rv3d->winmat); + return false; } /* Calculate maximum excursion from (0,0,0) of mesh */ @@ -1510,6 +1151,43 @@ static void calc_ortho_extent(KnifeTool_OpData *kcd) kcd->ortho_extent = max_xyz; } +/* Check if p is visible (not clipped, not occluded by another face). + * s in screen projection of p. */ +static bool point_is_visible(KnifeTool_OpData *kcd, const float p[3], const float s[2], bglMats *mats) +{ + float p1[3], no[3], view[3]; + BMFace *f_hit; + + /* If not cutting through, make sure no face is in front of p */ + if (!kcd->cut_through) { + /* TODO: I think there's a simpler way to get the required raycast ray */ + ED_view3d_unproject(mats, view, s[0], s[1], 0.0f); + mul_m4_v3(kcd->ob->imat, view); + + /* make p1 a little towards view, so ray doesn't hit p's face. */ + copy_v3_v3(p1, p); + sub_v3_v3(view, p1); + normalize_v3(view); + copy_v3_v3(no, view); + mul_v3_fl(no, 3.0f * KNIFE_FLT_EPSBIG); + add_v3_v3(p1, no); + + /* see if there's a face hit between p1 and the view */ + f_hit = BKE_bmbvh_ray_cast(kcd->bmbvh, p1, no, KNIFE_FLT_EPS, NULL, NULL, NULL); + if (f_hit) + return false; + } + + /* If box clipping on, make sure p is not clipped */ + if (kcd->vc.rv3d->rflag & RV3D_CLIPPING && + ED_view3d_clipping_test(kcd->vc.rv3d, p, true)) + { + return false; + } + + return true; +} + /* Clip the line (v1, v2) to planes perpendicular to it and distances d from * the closest point on the line to the origin */ static void clip_to_ortho_planes(float v1[3], float v2[3], float d) @@ -1522,16 +1200,49 @@ static void clip_to_ortho_planes(float v1[3], float v2[3], float d) dist_ensure_v3_v3fl(v2, closest, d); } +static void set_linehit_depth(KnifeTool_OpData *kcd, KnifeLineHit *lh) +{ + float vnear[3], vfar[3]; + + ED_view3d_win_to_segment(kcd->ar, kcd->vc.v3d, lh->schit, vnear, vfar, true); + mul_m4_v3(kcd->ob->imat, vnear); + if (kcd->is_ortho) { + if (kcd->ortho_extent == 0.0f) + calc_ortho_extent(kcd); + clip_to_ortho_planes(vnear, vfar, kcd->ortho_extent + 10.0f); + } + lh->m = len_v3v3(vnear, lh->cagehit); +} + /* Finds visible (or all, if cutting through) edges that intersects the current screen drag line */ static void knife_find_line_hits(KnifeTool_OpData *kcd) { bglMats mats; - BMEdgeHit *e1, *e2; - SmallHash hash, *ehash = &hash; - float v1[3], v2[3], v3[3], v4[4], s1[2], s2[2]; - int i, c1, c2; + SmallHash faces, kfes, kfvs; + float v1[3], v2[3], v3[3], v4[3], s1[2], s2[2]; + BVHTree *planetree, *tree; + BVHTreeOverlap *results, *result; + BMLoop **ls; + BMFace *f; + KnifeEdge *kfe; + KnifeVert *v; + ListBase *lst; + Ref *ref; + KnifeLineHit *linehits = NULL; + BLI_array_declare(linehits); + SmallHashIter hiter; + KnifeLineHit hit; + void *val; + float plane_cos[12]; + float s[2], se1[2], se2[2], sint[2]; + float p[3], p2[3], r1[3], r2[3]; + float d, d1, d2, lambda; + float vert_tol, vert_tol_sq, line_tol, face_tol; + int isect_kind; + unsigned int tot; + int i; - knife_bgl_get_mats(kcd, &mats); + bgl_get_mats(&mats); if (kcd->linehits) { MEM_freeN(kcd->linehits); @@ -1568,7 +1279,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd) /* numeric error, 'v1' -> 'v2', 'v2' -> 'v4' can end up being ~2000 units apart in otho mode * (from ED_view3d_win_to_segment_clip() above) - * this gives precision error in 'knife_edge_tri_isect', rather then solving properly + * this gives precision error; rather then solving properly * (which may involve using doubles everywhere!), * limit the distance between these points */ if (kcd->is_ortho) { @@ -1578,70 +1289,176 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd) clip_to_ortho_planes(v2, v4, kcd->ortho_extent + 10.0f); } - BLI_smallhash_init(ehash); + /* First use bvh tree to find faces, knife edges, and knife verts that might + * intersect the cut plane with rays v1-v3 and v2-v4. + * This deduplicates the candidates before doing more expensive intersection tests. */ + BLI_smallhash_init(&faces); + BLI_smallhash_init(&kfes); + BLI_smallhash_init(&kfvs); + + tree = BKE_bmbvh_tree_get(kcd->bmbvh); + planetree = BLI_bvhtree_new(4, FLT_EPSILON * 4, 8, 8); + copy_v3_v3(plane_cos + 0, v1); + copy_v3_v3(plane_cos + 3, v2); + copy_v3_v3(plane_cos + 6, v3); + copy_v3_v3(plane_cos + 9, v4); + BLI_bvhtree_insert(planetree, 0, plane_cos, 4); + BLI_bvhtree_balance(planetree); + + results = BLI_bvhtree_overlap(tree, planetree, &tot); + if (!results) { + BLI_smallhash_release(&faces); + BLI_smallhash_release(&kfes); + BLI_smallhash_release(&kfvs); + BLI_bvhtree_free(planetree); + return; + } - /* test two triangles of sceen line's plane */ - e1 = knife_edge_tri_isect(kcd, kcd->bmbvh, v1, v2, v3, ehash, &mats, &c1); - e2 = knife_edge_tri_isect(kcd, kcd->bmbvh, v2, v3, v4, ehash, &mats, &c2); - if (c1 && c2) { - e1 = MEM_reallocN(e1, sizeof(BMEdgeHit) * (c1 + c2)); - memcpy(e1 + c1, e2, sizeof(BMEdgeHit) * c2); - MEM_freeN(e2); + for (i = 0, result = results; i < tot; i++, result++) { + ls = (BMLoop **)kcd->em->looptris[result->indexA]; + f = ls[0]->f; + set_lowest_face_tri(kcd, f, result->indexA); + /* for faces, store index of lowest hit looptri in hash */ + if (BLI_smallhash_haskey(&faces, (uintptr_t)f)) { + continue; + } + /* don't care what the value is except that it is non-NULL, for iterator */ + BLI_smallhash_insert(&faces, (uintptr_t)f, f); + + lst = knife_get_face_kedges(kcd, f); + for (ref = lst->first; ref; ref = ref->next) { + kfe = ref->ref; + if (BLI_smallhash_haskey(&kfes, (uintptr_t)kfe)) + continue; + BLI_smallhash_insert(&kfes, (uintptr_t)kfe, kfe); + v = kfe->v1; + if (!BLI_smallhash_haskey(&kfvs, (uintptr_t)v)) + BLI_smallhash_insert(&kfvs, (uintptr_t)v, v); + v = kfe->v2; + if (!BLI_smallhash_haskey(&kfvs, (uintptr_t)v)) + BLI_smallhash_insert(&kfvs, (uintptr_t)v, v); + } + } + + /* Now go through the candidates and find intersections */ + /* These tolerances, in screen space, are for intermediate hits, as ends are already snapped to screen */ + vert_tol = KNIFE_FLT_EPS * 2000.0f; + line_tol = KNIFE_FLT_EPS * 2000.0f; + vert_tol_sq = vert_tol * vert_tol; + face_tol = max_ff(vert_tol, line_tol); + /* Assume these tolerances swamp floating point rounding errors in calculations below */ + + /* first look for vertex hits */ + for (val = BLI_smallhash_iternew(&kfvs, &hiter, (uintptr_t *)&v); val; + val = BLI_smallhash_iternext(&hiter, (uintptr_t *)&v)) + { + knife_project_v2(kcd, v->cageco, s); + d = dist_squared_to_line_segment_v2(s, s1, s2); + if (d <= vert_tol_sq) { + if (point_is_visible(kcd, v->cageco, s, &mats)) { + memset(&hit, 0, sizeof(hit)); + hit.v = v; + copy_v3_v3(hit.hit, v->cageco); + copy_v3_v3(hit.cagehit, v->cageco); + copy_v2_v2(hit.schit, s); + set_linehit_depth(kcd, &hit); + BLI_array_append(linehits, hit); + } + } + } + /* now edge hits; don't add if a vertex at end of edge should have hit */ + for (val = BLI_smallhash_iternew(&kfes, &hiter, (uintptr_t *)&kfe); val; + val = BLI_smallhash_iternext(&hiter, (uintptr_t *)&kfe)) + { + knife_project_v2(kcd, kfe->v1->cageco, se1); + knife_project_v2(kcd, kfe->v2->cageco, se2); + isect_kind = isect_seg_seg_v2_point(s1, s2, se1, se2, sint); + if (isect_kind == -1) { + /* isect_seg_seg_v2 doesn't do tolerance test around ends of s1-s2 */ + closest_to_line_segment_v2(sint, s1, se1, se2); + if (len_squared_v2v2(sint, s1) <= vert_tol_sq) + isect_kind = 1; + else { + closest_to_line_segment_v2(sint, s2, se1, se2); + if (len_squared_v2v2(sint, s2) <= vert_tol_sq) + isect_kind = 1; + } + } + if (isect_kind == 1) { + d1 = len_v2v2(sint, se1); + d2 = len_v2v2(se2, se1); + if (!(d1 <= vert_tol || d2 <= vert_tol || fabsf(d1 - d2) <= vert_tol)) { + lambda = d1 / d2; + /* Can't just interpolate between ends of kfe because + * that doesn't work with perspective transformation. + * Need to find 3d intersection of ray through sint */ + knife_input_ray_segment(kcd, sint, 1.0f, r1, r2); + isect_kind = isect_line_line_v3(kfe->v1->cageco, kfe->v2->cageco, r1, r2, p, p2); + if (isect_kind >= 1 && point_is_visible(kcd, p, sint, &mats)) { + memset(&hit, 0, sizeof(hit)); + hit.kfe = kfe; + copy_v3_v3(hit.hit, p); + copy_v3_v3(hit.cagehit, p); + copy_v2_v2(hit.schit, sint); + hit.perc = lambda; + set_linehit_depth(kcd, &hit); + BLI_array_append(linehits, hit); + } + } + } } - else if (c2) { - e1 = e2; + /* now face hits; don't add if a vertex or edge in face should have hit */ + for (val = BLI_smallhash_iternew(&faces, &hiter, (uintptr_t *)&f); val; + val = BLI_smallhash_iternext(&hiter, (uintptr_t *)&f)) + { + if (knife_ray_intersect_face(kcd, s1, v1, v3, f, face_tol, p)) { + if (point_is_visible(kcd, p, s1, &mats)) { + memset(&hit, 0, sizeof(hit)); + hit.f = f; + copy_v3_v3(hit.hit, p); + copy_v3_v3(hit.cagehit, p); + copy_v2_v2(hit.schit, s1); + set_linehit_depth(kcd, &hit); + BLI_array_append(linehits, hit); + } + } + if (knife_ray_intersect_face(kcd, s2, v2, v4, f, face_tol, p)) { + if (point_is_visible(kcd, p, s2, &mats)) { + memset(&hit, 0, sizeof(hit)); + hit.f = f; + copy_v3_v3(hit.hit, p); + copy_v3_v3(hit.cagehit, p); + copy_v2_v2(hit.schit, s2); + set_linehit_depth(kcd, &hit); + BLI_array_append(linehits, hit); + } + } } - kcd->linehits = e1; - kcd->totlinehit = c1 + c2; + kcd->linehits = linehits; + kcd->totlinehit = BLI_array_count(linehits); /* find position along screen line, used for sorting */ for (i = 0; i < kcd->totlinehit; i++) { - BMEdgeHit *lh = e1 + i; + KnifeLineHit *lh = kcd->linehits + i; lh->l = len_v2v2(lh->schit, s1) / len_v2v2(s2, s1); } - BLI_smallhash_release(ehash); -} - -/* this works but gives numeric problems [#33400] */ -#if 0 -static void knife_input_ray_cast(KnifeTool_OpData *kcd, const float mval[2], - float r_origin[3], float r_ray[3]) -{ - bglMats mats; - float imat[3][3]; - - knife_bgl_get_mats(kcd, &mats); - - /* unproject to find view ray */ - ED_view3d_unproject(&mats, r_origin, mval[0], mval[1], 0.0f); - - if (kcd->is_ortho) { - negate_v3_v3(r_ray, kcd->vc.rv3d->viewinv[2]); - } - else { - sub_v3_v3v3(r_ray, r_origin, kcd->vc.rv3d->viewinv[3]); - } - normalize_v3(r_ray); - - /* transform into object space */ - invert_m4_m4(kcd->ob->imat, kcd->ob->obmat); - copy_m3_m4(imat, kcd->ob->obmat); - invert_m3(imat); - - mul_m4_v3(kcd->ob->imat, r_origin); - mul_m3_v3(imat, r_ray); + BLI_smallhash_release(&faces); + BLI_smallhash_release(&kfes); + BLI_smallhash_release(&kfvs); + BLI_bvhtree_free(planetree); + if (results) + MEM_freeN(results); } -#endif static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2], const float ofs, float r_origin[3], float r_origin_ofs[3]) { bglMats mats; - knife_bgl_get_mats(kcd, &mats); + bgl_get_mats(&mats); /* unproject to find view ray */ ED_view3d_unproject(&mats, r_origin, mval[0], mval[1], 0.0f); @@ -1757,7 +1574,8 @@ static float knife_snap_size(KnifeTool_OpData *kcd, float maxsize) } /* p is closest point on edge to the mouse cursor */ -static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], float cagep[3], BMFace **fptr, bool *is_space) +static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], float cagep[3], + BMFace **fptr, bool *is_space) { BMFace *f; float co[3], cageco[3], sco[2]; @@ -1867,7 +1685,7 @@ static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], flo /* set p to co, in case we don't find anything, means a face cut */ copy_v3_v3(p, co); - copy_v3_v3(cagep, p); + copy_v3_v3(cagep, cageco); kcd->curr.bmface = f; if (f) { @@ -1989,20 +1807,22 @@ static int knife_update_active(KnifeTool_OpData *kcd) kcd->curr.vert = knife_find_closest_vert(kcd, kcd->curr.co, kcd->curr.cage, &kcd->curr.bmface, &kcd->curr.is_space); if (!kcd->curr.vert) { - kcd->curr.edge = knife_find_closest_edge(kcd, kcd->curr.co, kcd->curr.cage, &kcd->curr.bmface, &kcd->curr.is_space); + kcd->curr.edge = knife_find_closest_edge(kcd, kcd->curr.co, kcd->curr.cage, + &kcd->curr.bmface, &kcd->curr.is_space); } /* if no hits are found this would normally default to (0, 0, 0) so instead * get a point at the mouse ray closest to the previous point. * Note that drawing lines in `free-space` isn't properly supported * but theres no guarantee (0, 0, 0) has any geometry either - campbell */ - if (kcd->curr.vert == NULL && kcd->curr.edge == NULL) { + if (kcd->curr.vert == NULL && kcd->curr.edge == NULL && kcd->curr.bmface == NULL) { float origin[3]; float origin_ofs[3]; knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, origin, origin_ofs); closest_to_line_v3(kcd->curr.cage, kcd->prev.cage, origin_ofs, origin); + copy_v3_v3(kcd->curr.co, kcd->curr.cage); } if (kcd->mode == MODE_DRAGGING) { @@ -2011,380 +1831,11 @@ static int knife_update_active(KnifeTool_OpData *kcd) return 1; } -#define SCANFILL_CUTS 0 -#if SCANFILL_CUTS - -#define MARK 4 -#define DEL 8 -#define VERT_ON_EDGE 16 -#define VERT_ORIG 32 -#define FACE_FLIP 64 -#define BOUNDARY 128 -#define FACE_NEW 256 - -typedef struct facenet_entry { - struct facenet_entry *next, *prev; - KnifeEdge *kfe; -} facenet_entry; - -static void rnd_offset_co(RNG *rng, float co[3], float scale) -{ - int i; - - for (i = 0; i < 3; i++) { - co[i] += (BLI_rng_get_float(rng) - 0.5) * scale; - } -} - -static void remerge_faces(KnifeTool_OpData *kcd) -{ - BMesh *bm = kcd->em->bm; - SmallHash svisit, *visit = &svisit; - BMIter iter; - BMFace *f; - BMFace **stack = NULL; - BLI_array_declare(stack); - BMFace **faces = NULL; - BLI_array_declare(faces); - BMOperator bmop; - int idx; - - BMO_op_initf(bm, &bmop, "beautify_fill faces=%ff edges=%Fe", FACE_NEW, BOUNDARY); - - BMO_op_exec(bm, &bmop); - BMO_slot_buffer_flag_enable(bm, &bmop, "geom.out", BM_FACE, FACE_NEW); - - BMO_op_finish(bm, &bmop); - - BLI_smallhash_init(visit); - BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { - BMIter eiter; - BMEdge *e; - BMFace *f2; - - if (!BMO_elem_flag_test(bm, f, FACE_NEW)) - continue; - - if (BLI_smallhash_haskey(visit, (uintptr_t)f)) - continue; - - BLI_array_empty(stack); - BLI_array_empty(faces); - BLI_array_append(stack, f); - BLI_smallhash_insert(visit, (uintptr_t)f, NULL); - - do { - f2 = BLI_array_pop(stack); - - BLI_array_append(faces, f2); - - BM_ITER_ELEM (e, &eiter, f2, BM_EDGES_OF_FACE) { - BMIter fiter; - BMFace *f3; - - if (BMO_elem_flag_test(bm, e, BOUNDARY)) - continue; - - BM_ITER_ELEM (f3, &fiter, e, BM_FACES_OF_EDGE) { - if (!BMO_elem_flag_test(bm, f3, FACE_NEW)) - continue; - if (BLI_smallhash_haskey(visit, (uintptr_t)f3)) - continue; - - BLI_smallhash_insert(visit, (uintptr_t)f3, NULL); - BLI_array_append(stack, f3); - } - } - } while (BLI_array_count(stack) > 0); - - if (BLI_array_count(faces) > 0) { - idx = BM_elem_index_get(faces[0]); - - f2 = BM_faces_join(bm, faces, BLI_array_count(faces), true); - if (f2) { - BMO_elem_flag_enable(bm, f2, FACE_NEW); - BM_elem_index_set(f2, idx); /* set_dirty! *//* BMESH_TODO, check if this is valid or not */ - } - } - } - /* BMESH_TODO, check if the code above validates the indices */ - /* bm->elem_index_dirty &= ~BM_FACE; */ - bm->elem_index_dirty |= BM_FACE; - - BLI_smallhash_release(visit); - - BLI_array_free(stack); - BLI_array_free(faces); -} - -/* use edgenet to fill faces. this is a bit annoying and convoluted.*/ -static void knifenet_fill_faces(KnifeTool_OpData *kcd) -{ - ScanFillContext sf_ctx; - BMesh *bm = kcd->em->bm; - BMIter bmiter; - BLI_mempool_iter iter; - BMFace *f; - BMEdge *e; - KnifeVert *kfv; - KnifeEdge *kfe; - facenet_entry *entry; - ListBase *face_nets = MEM_callocN(sizeof(ListBase) * bm->totface, "face_nets"); - BMFace **faces = MEM_callocN(sizeof(BMFace *) * bm->totface, "faces knife"); - MemArena *arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "knifenet_fill_faces"); - SmallHash shash; - RNG *rng; - int i, j, k = 0, totface = bm->totface; - - BMO_push(bm, NULL); - bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH); - - /* BMESH_TODO this should be valid now, leaving here until we can ensure this - campbell */ - i = 0; - BM_ITER_MESH (f, &bmiter, bm, BM_FACES_OF_MESH) { - BM_elem_index_set(f, i); /* set_inline */ - faces[i] = f; - i++; - } - bm->elem_index_dirty &= ~BM_FACE; - - BM_ITER_MESH (e, &bmiter, bm, BM_EDGES_OF_MESH) { - BMO_elem_flag_enable(bm, e, BOUNDARY); - } - - /* turn knife verts into real verts, as necessary */ - BLI_mempool_iternew(kcd->kverts, &iter); - for (kfv = BLI_mempool_iterstep(&iter); kfv; kfv = BLI_mempool_iterstep(&iter)) { - if (!kfv->v) { - /* shouldn't we be at least copying the normal? - if not some comment here should explain why - campbell */ - kfv->v = BM_vert_create(bm, kfv->co, NULL, BM_CREATE_NOP); - kfv->flag = 1; - BMO_elem_flag_enable(bm, kfv->v, DEL); - } - else { - kfv->flag = 0; - BMO_elem_flag_enable(bm, kfv->v, VERT_ORIG); - } - - BMO_elem_flag_enable(bm, kfv->v, MARK); - } - - /* we want to only do changed faces. first, go over new edges and add to - * face net lists.*/ - i = j = k = 0; - BLI_mempool_iternew(kcd->kedges, &iter); - for (kfe = BLI_mempool_iterstep(&iter); kfe; kfe = BLI_mempool_iterstep(&iter)) { - Ref *ref; - if (!kfe->v1 || !kfe->v2 || kfe->v1->inspace || kfe->v2->inspace) - continue; - - i++; - - if (kfe->e && kfe->v1->v == kfe->e->v1 && kfe->v2->v == kfe->e->v2) { - kfe->e_old = kfe->e; - continue; - } - - j++; - - if (kfe->e) { - kfe->e_old = kfe->e; - - BMO_elem_flag_enable(bm, kfe->e, DEL); - BMO_elem_flag_disable(bm, kfe->e, BOUNDARY); - kfe->e = NULL; - } - - kfe->e = BM_edge_create(bm, kfe->v1->v, kfe->v2->v, NULL, BM_CREATE_NO_DOUBLE); - BMO_elem_flag_enable(bm, kfe->e, BOUNDARY); - - for (ref = kfe->faces.first; ref; ref = ref->next) { - f = ref->ref; - - entry = BLI_memarena_alloc(arena, sizeof(*entry)); - entry->kfe = kfe; - BLI_addtail(face_nets + BM_elem_index_get(f), entry); - } - } - - /* go over original edges, and add to faces with new geometry */ - BLI_mempool_iternew(kcd->kedges, &iter); - for (kfe = BLI_mempool_iterstep(&iter); kfe; kfe = BLI_mempool_iterstep(&iter)) { - Ref *ref; - - if (!kfe->v1 || !kfe->v2 || kfe->v1->inspace || kfe->v2->inspace) - continue; - if (!(kfe->e_old && kfe->v1->v == kfe->e_old->v1 && kfe->v2->v == kfe->e_old->v2)) - continue; - - k++; - - BMO_elem_flag_enable(bm, kfe->e, BOUNDARY); - kfe->e_old = kfe->e; - - for (ref = kfe->faces.first; ref; ref = ref->next) { - f = ref->ref; - - if (face_nets[BM_elem_index_get(f)].first) { - entry = BLI_memarena_alloc(arena, sizeof(*entry)); - entry->kfe = kfe; - BLI_addtail(face_nets + BM_elem_index_get(f), entry); - } - } - } - - rng = BLI_rng_new(0); - - for (i = 0; i < totface; i++) { - SmallHash *hash = &shash; - ScanFillFace *sf_tri; - ScanFillVert *sf_vert, *sf_vert_last; - int j; - float rndscale = (KNIFE_FLT_EPS / 4.0f); - - f = faces[i]; - BLI_smallhash_init(hash); - - if (face_nets[i].first) - BMO_elem_flag_enable(bm, f, DEL); - - BLI_scanfill_begin(&sf_ctx); - - for (entry = face_nets[i].first; entry; entry = entry->next) { - if (!BLI_smallhash_haskey(hash, (uintptr_t)entry->kfe->v1)) { - sf_vert = BLI_scanfill_vert_add(&sf_ctx, entry->kfe->v1->v->co); - sf_vert->poly_nr = 0; - rnd_offset_co(rng, sf_vert->co, rndscale); - sf_vert->tmp.p = entry->kfe->v1->v; - BLI_smallhash_insert(hash, (uintptr_t)entry->kfe->v1, sf_vert); - } - - if (!BLI_smallhash_haskey(hash, (uintptr_t)entry->kfe->v2)) { - sf_vert = BLI_scanfill_vert_add(&sf_ctx, entry->kfe->v2->v->co); - sf_vert->poly_nr = 0; - rnd_offset_co(rng, sf_vert->co, rndscale); - sf_vert->tmp.p = entry->kfe->v2->v; - BLI_smallhash_insert(hash, (uintptr_t)entry->kfe->v2, sf_vert); - } - } - - for (j = 0, entry = face_nets[i].first; entry; entry = entry->next, j++) { - sf_vert_last = BLI_smallhash_lookup(hash, (uintptr_t)entry->kfe->v1); - sf_vert = BLI_smallhash_lookup(hash, (uintptr_t)entry->kfe->v2); - - sf_vert->poly_nr++; - sf_vert_last->poly_nr++; - } - - for (j = 0, entry = face_nets[i].first; entry; entry = entry->next, j++) { - sf_vert_last = BLI_smallhash_lookup(hash, (uintptr_t)entry->kfe->v1); - sf_vert = BLI_smallhash_lookup(hash, (uintptr_t)entry->kfe->v2); - - if (sf_vert->poly_nr > 1 && sf_vert_last->poly_nr > 1) { - ScanFillEdge *sf_edge; - sf_edge = BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert); - if (entry->kfe->e_old) - sf_edge->f = SF_EDGE_BOUNDARY; /* mark as original boundary edge */ - - BMO_elem_flag_disable(bm, entry->kfe->e->v1, DEL); - BMO_elem_flag_disable(bm, entry->kfe->e->v2, DEL); - } - else { - if (sf_vert_last->poly_nr < 2) - BLI_remlink(&sf_ctx.fillvertbase, sf_vert_last); - if (sf_vert->poly_nr < 2) - BLI_remlink(&sf_ctx.fillvertbase, sf_vert); - } - } - - BLI_scanfill_calc(&sf_ctx, 0); - - for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) { - BMVert *v1 = sf_tri->v3->tmp.p, *v2 = sf_tri->v2->tmp.p, *v3 = sf_tri->v1->tmp.p; - BMFace *f2; - BMLoop *l_iter; - BMVert *verts[3] = {v1, v2, v3}; - - if (v1 == v2 || v2 == v3 || v1 == v3) - continue; - if (BM_face_exists(bm, verts, 3, &f2)) - continue; - - f2 = BM_face_create_quad_tri(bm, - v1, v2, v3, NULL, - NULL, false); - - BMO_elem_flag_enable(bm, f2, FACE_NEW); - - l_iter = BM_FACE_FIRST_LOOP(f2); - do { - BMO_elem_flag_disable(bm, l_iter->e, DEL); - } while ((l_iter = l_iter->next) != BM_FACE_FIRST_LOOP(f2)); - - BMO_elem_flag_disable(bm, f2, DEL); - BM_elem_index_set(f2, i); /* set_dirty! *//* note, not 100% sure this is dirty? need to check */ - - BM_face_normal_update(f2); - if (dot_v3v3(f->no, f2->no) < 0.0f) { - BM_face_normal_flip(bm, f2); - } - } - - BLI_scanfill_end(&sf_ctx); - BLI_smallhash_release(hash); - } - bm->elem_index_dirty |= BM_FACE; - - /* interpolate customdata */ - BM_ITER_MESH (f, &bmiter, bm, BM_FACES_OF_MESH) { - BMLoop *l1; - BMFace *f2; - BMIter liter1; - - if (!BMO_elem_flag_test(bm, f, FACE_NEW)) - continue; - - f2 = faces[BM_elem_index_get(f)]; - if (BM_elem_index_get(f) < 0 || BM_elem_index_get(f) >= totface) { - fprintf(stderr, "%s: face index out of range! (bmesh internal error)\n", __func__); - } - - BM_elem_attrs_copy(bm, bm, f2, f); - - BM_ITER_ELEM (l1, &liter1, f, BM_LOOPS_OF_FACE) { - BM_loop_interp_from_face(bm, l1, f2, true, true); - } - } - - /* merge triangles back into faces */ - remerge_faces(kcd); - - /* delete left over faces */ - BMO_op_callf(bm, BMO_FLAG_DEFAULTS, "delete geom=%ff context=%i", DEL, DEL_ONLYFACES); - BMO_op_callf(bm, BMO_FLAG_DEFAULTS, "delete geom=%fe context=%i", DEL, DEL_EDGES); - BMO_op_callf(bm, BMO_FLAG_DEFAULTS, "delete geom=%fv context=%i", DEL, DEL_VERTS); - - if (face_nets) - MEM_freeN(face_nets); - if (faces) - MEM_freeN(faces); - BLI_memarena_free(arena); - BLI_rng_free(rng); - - BMO_error_clear(bm); /* remerge_faces sometimes raises errors, so make sure to clear them */ - - bmesh_edit_end(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH); - BMO_pop(bm); -} - -#else /* use direct (non-scanfill) method for cuts */ - /* sort list of kverts by fraction along edge e */ static void sort_by_frac_along(ListBase *lst, BMEdge *e) { /* note, since we know the point is along the edge, sort from distance to v1co */ const float *v1co = e->v1->co; -// const float *v2co = e->v2->co; Ref *cur = NULL, *prev = NULL, *next = NULL; if (lst->first == lst->last) @@ -2392,11 +1843,7 @@ static void sort_by_frac_along(ListBase *lst, BMEdge *e) for (cur = ((Ref *)lst->first)->next; cur; cur = next) { KnifeVert *vcur = cur->ref; -#if 0 - const float vcur_fac = line_point_factor_v3(vcur->co, v1co, v2co); -#else const float vcur_fac = len_squared_v3v3(v1co, vcur->co); -#endif next = cur->next; prev = cur->prev; @@ -2405,13 +1852,8 @@ static void sort_by_frac_along(ListBase *lst, BMEdge *e) while (prev) { KnifeVert *vprev = prev->ref; -#if 0 - if (line_point_factor_v3(vprev->co, v1co, v2co) <= vcur_fac) - break; -#else if (len_squared_v3v3(v1co, vprev->co) <= vcur_fac) break; -#endif prev = prev->prev; } @@ -2745,34 +2187,30 @@ static bool find_hole_chains(KnifeTool_OpData *kcd, ListBase *hole, BMFace *f, L } } -static bool knife_edge_in_face(KnifeTool_OpData *UNUSED(kcd), KnifeEdge *kfe, BMFace *f) +static bool knife_verts_edge_in_face(KnifeVert *v1, KnifeVert *v2, BMFace *f) { - /* BMesh *bm = kcd->em->bm; */ /* UNUSED */ - BMVert *v1, *v2; BMLoop *l1, *l2, *l; float mid[3]; BMIter iter; int v1inside, v2inside; - if (!f) + if (!f || !v1 || !v2) return false; - v1 = kfe->v1->v; - v2 = kfe->v2->v; l1 = NULL; l2 = NULL; /* find out if v1 and v2, if set, are part of the face */ BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) { - if (v1 && l->v == v1) + if (v1->v && l->v == v1->v) l1 = l; - if (v2 && l->v == v2) + if (v2->v && l->v == v2->v) l2 = l; } /* BM_face_point_inside_test uses best-axis projection so this isn't most accurate test... */ - v1inside = l1 ? 0 : BM_face_point_inside_test(f, kfe->v1->co); - v2inside = l2 ? 0 : BM_face_point_inside_test(f, kfe->v2->co); + v1inside = l1 ? 0 : BM_face_point_inside_test(f, v1->co); + v2inside = l2 ? 0 : BM_face_point_inside_test(f, v2->co); if ((l1 && v2inside) || (l2 && v1inside) || (v1inside && v2inside)) return true; if (l1 && l2) { @@ -2780,12 +2218,17 @@ static bool knife_edge_in_face(KnifeTool_OpData *UNUSED(kcd), KnifeEdge *kfe, BM * BM_face_legal_splits does visibility and self-intersection tests, * but it is expensive and maybe a bit buggy, so use a simple * "is the midpoint in the face" test */ - mid_v3_v3v3(mid, kfe->v1->co, kfe->v2->co); + mid_v3_v3v3(mid, v1->co, v2->co); return BM_face_point_inside_test(f, mid); } return false; } +static bool knife_edge_in_face(KnifeEdge *kfe, BMFace *f) +{ + return knife_verts_edge_in_face(kfe->v1, kfe->v2, f); +} + /* Split face f with KnifeEdges on chain. f remains as one side, the face formed is put in *newface. * The new face will be on the left side of the chain as viewed from the normal-out side of f. */ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *chain, BMFace **r_f_new) @@ -2877,7 +2320,7 @@ static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfe for (ref = kfedges->first; ref; ref = refnext) { kfe = ref->ref; refnext = ref->next; - if (knife_edge_in_face(kcd, kfe, fnew)) { + if (knife_edge_in_face(kfe, fnew)) { BLI_remlink(kfedges, ref); kfe->basef = fnew; knife_append_list(kcd, fnew_kfedges, kfe); @@ -2907,14 +2350,14 @@ static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfe return; } kfe = ((Ref *)sidechain->first)->ref; - if (knife_edge_in_face(kcd, kfe, f)) { + if (knife_edge_in_face(kfe, f)) { knife_make_chain_cut(kcd, f, sidechain, &fnew2); if (fnew2 == NULL) { return; } fhole = f; } - else if (knife_edge_in_face(kcd, kfe, fnew)) { + else if (knife_edge_in_face(kfe, fnew)) { knife_make_chain_cut(kcd, fnew, sidechain, &fnew2); if (fnew2 == NULL) { return; @@ -2933,12 +2376,12 @@ static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfe for (ref = kfedges->first; ref; ref = refnext) { kfe = ref->ref; refnext = ref->next; - if (knife_edge_in_face(kcd, kfe, fnew)) { + if (knife_edge_in_face(kfe, fnew)) { BLI_remlink(kfedges, ref); kfe->basef = fnew; knife_append_list(kcd, fnew_kfedges, kfe); } - else if (knife_edge_in_face(kcd, kfe, fnew2)) { + else if (knife_edge_in_face(kfe, fnew2)) { BLI_remlink(kfedges, ref); kfe->basef = fnew2; knife_append_list(kcd, fnew2_kfedges, kfe); @@ -3044,16 +2487,11 @@ static void knife_make_cuts(KnifeTool_OpData *kcd) BLI_smallhash_release(fhash); BLI_smallhash_release(ehash); } -#endif /* called on tool confirmation */ static void knifetool_finish_ex(KnifeTool_OpData *kcd) { -#if SCANFILL_CUTS - knifenet_fill_faces(kcd); -#else knife_make_cuts(kcd); -#endif EDBM_selectmode_flush(kcd->em); EDBM_mesh_normals_update(kcd->em); @@ -3096,6 +2534,7 @@ static void knifetool_exit_ex(bContext *C, KnifeTool_OpData *kcd) BLI_ghash_free(kcd->origedgemap, NULL, NULL); BLI_ghash_free(kcd->origvertmap, NULL, NULL); BLI_ghash_free(kcd->kedgefacemap, NULL, NULL); + BLI_ghash_free(kcd->facetrimap, NULL, NULL); BKE_bmbvh_free(kcd->bmbvh); BLI_memarena_free(kcd->arena); @@ -3154,17 +2593,15 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd, kcd->cagecos = (const float (*)[3])BKE_editmesh_vertexCos_get(kcd->em, scene, NULL); - kcd->bmbvh = BKE_bmbvh_new(kcd->em, - BMBVH_RETURN_ORIG | - (only_select ? BMBVH_RESPECT_SELECT : BMBVH_RESPECT_HIDDEN), - kcd->cagecos, false); + kcd->bmbvh = BKE_bmbvh_new_from_editmesh(kcd->em, + BMBVH_RETURN_ORIG | + (only_select ? BMBVH_RESPECT_SELECT : BMBVH_RESPECT_HIDDEN), + kcd->cagecos, false); kcd->arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 15), "knife"); kcd->vthresh = KMAXDIST - 1; kcd->ethresh = KMAXDIST; - kcd->extend = true; - knife_recalc_projmat(kcd); ED_region_tag_redraw(kcd->ar); @@ -3175,7 +2612,8 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd, kcd->origedgemap = BLI_ghash_ptr_new("knife origedgemap"); kcd->origvertmap = BLI_ghash_ptr_new("knife origvertmap"); - kcd->kedgefacemap = BLI_ghash_ptr_new("knife origvertmap"); + kcd->kedgefacemap = BLI_ghash_ptr_new("knife kedgefacemap"); + kcd->facetrimap = BLI_ghash_ptr_new("knife facetrimap"); /* cut all the way through the mesh if use_occlude_geometry button not pushed */ kcd->is_interactive = is_interactive; @@ -3195,11 +2633,10 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd, } } -static int knifetool_cancel(bContext *C, wmOperator *op) +static void knifetool_cancel(bContext *C, wmOperator *op) { /* this is just a wrapper around exit() */ knifetool_exit(C, op); - return OPERATOR_CANCELLED; } static int knifetool_invoke(bContext *C, wmOperator *op, const wmEvent *event) @@ -3382,10 +2819,6 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event) if (kcd->mode == MODE_DRAGGING) { knife_add_cut(kcd); - if (!kcd->extend) { - knife_finish_cut(kcd); - kcd->mode = MODE_IDLE; - } } else if (kcd->mode != MODE_PANNING) { knife_start_cut(kcd); @@ -3476,7 +2909,7 @@ static void edvm_mesh_knife_face_point(BMFace *f, float r_cent[3]) int j; float const *best_co[3] = {NULL}; - float best_area = -1.0f; + float best_area = -1.0f; bool ok = false; tottri = BM_face_calc_tessellation(f, loops, index); @@ -3540,7 +2973,7 @@ static bool edbm_mesh_knife_face_isect(ARegion *ar, LinkNode *polys, BMFace *f, /** * \param use_tag When set, tag all faces inside the polylines. */ -void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag) +void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_through) { KnifeTool_OpData *kcd; @@ -3549,7 +2982,6 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag) /* init */ { const bool only_select = false; - const bool cut_through = false; const bool is_interactive = false; /* can enable for testing */ kcd = MEM_callocN(sizeof(KnifeTool_OpData), __func__); diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c index f473939d0aa..57a85f1162d 100644 --- a/source/blender/editors/mesh/editmesh_knife_project.c +++ b/source/blender/editors/mesh/editmesh_knife_project.c @@ -42,6 +42,9 @@ #include "BKE_editmesh.h" #include "BKE_report.h" +#include "RNA_define.h" +#include "RNA_access.h" + #include "MEM_guardedalloc.h" #include "WM_types.h" @@ -117,6 +120,7 @@ static int knifeproject_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); + const bool cut_through = RNA_boolean_get(op->ptr, "cut_through"); LinkNode *polys = NULL; @@ -129,7 +133,7 @@ static int knifeproject_exec(bContext *C, wmOperator *op) CTX_DATA_END; if (polys) { - EDBM_mesh_knife(C, polys, true); + EDBM_mesh_knife(C, polys, true, cut_through); /* select only tagged faces */ BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false); @@ -166,4 +170,7 @@ void MESH_OT_knife_project(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; + + /* parameters */ + RNA_def_boolean(ot->srna, "cut_through", false, "Cut through", "Cut through all faces, not just visible ones"); } diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index ae1007cb98a..9223f6d9450 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -219,7 +219,7 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, bool select) } if (dm) { - EDBM_index_arrays_ensure(lcd->em, BM_VERT); + BM_mesh_elem_table_ensure(lcd->em->bm, BM_VERT); } BMW_init(&walker, em->bm, BMW_EDGERING, @@ -418,11 +418,10 @@ static int ringsel_init(bContext *C, wmOperator *op, bool do_cut) return 1; } -static int ringcut_cancel(bContext *C, wmOperator *op) +static void ringcut_cancel(bContext *C, wmOperator *op) { /* this is just a wrapper around exit() */ ringsel_exit(C, op); - return OPERATOR_CANCELLED; } static void loopcut_update_edge(RingSelOpData *lcd, BMEdge *e, const int previewlines) @@ -478,8 +477,8 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event) else { const int e_index = RNA_int_get(op->ptr, "edge_index"); BMEdge *e; - EDBM_index_arrays_ensure(lcd->em, BM_EDGE); - e = EDBM_edge_at_index(lcd->em, e_index); + BM_mesh_elem_table_ensure(lcd->em->bm, BM_EDGE); + e = BM_edge_at_index(lcd->em->bm, e_index); loopcut_update_edge(lcd, e, 0); } @@ -549,7 +548,8 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event) ringsel_exit(C, op); } else { - return ringcut_cancel(C, op); + ringcut_cancel(C, op); + return OPERATOR_CANCELLED; } return OPERATOR_FINISHED; @@ -569,7 +569,8 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event) ED_region_tag_redraw(lcd->ar); ED_area_headerprint(CTX_wm_area(C), NULL); - return ringcut_cancel(C, op); + ringcut_cancel(C, op); + return OPERATOR_CANCELLED; } ED_region_tag_redraw(lcd->ar); diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index f975d801d10..92bd71e128a 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -392,7 +392,7 @@ static void findnearestvert__doClosest(void *userData, BMVert *eve, const float static bool findnearestvert__backbufIndextest(void *handle, unsigned int index) { BMEditMesh *em = (BMEditMesh *)handle; - BMVert *eve = BM_vert_at_index(em->bm, index - 1); + BMVert *eve = BM_vert_at_index_find(em->bm, index - 1); return !(eve && BM_elem_flag_test(eve, BM_ELEM_SELECT)); } /** @@ -420,7 +420,7 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, float *r_dist, const bool sel, c 0, NULL, NULL); } - eve = index ? BM_vert_at_index(vc->em->bm, index - 1) : NULL; + eve = index ? BM_vert_at_index_find(vc->em->bm, index - 1) : NULL; if (eve && distance < *r_dist) { *r_dist = distance; @@ -436,7 +436,7 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, float *r_dist, const bool sel, c static int lastSelectedIndex = 0; static BMVert *lastSelected = NULL; - if (lastSelected && BM_vert_at_index(vc->em->bm, lastSelectedIndex) != lastSelected) { + if (lastSelected && BM_vert_at_index_find(vc->em->bm, lastSelectedIndex) != lastSelected) { lastSelectedIndex = 0; lastSelected = NULL; } @@ -512,7 +512,7 @@ BMEdge *EDBM_edge_find_nearest(ViewContext *vc, float *r_dist) view3d_validate_backbuf(vc); index = view3d_sample_backbuf_rect(vc, vc->mval, 50, bm_solidoffs, bm_wireoffs, &distance, 0, NULL, NULL); - eed = index ? BM_edge_at_index(vc->em->bm, index - 1) : NULL; + eed = index ? BM_edge_at_index_find(vc->em->bm, index - 1) : NULL; if (eed && distance < *r_dist) { *r_dist = distance; @@ -585,7 +585,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist) view3d_validate_backbuf(vc); index = view3d_sample_backbuf(vc, vc->mval[0], vc->mval[1]); - efa = index ? BM_face_at_index(vc->em->bm, index - 1) : NULL; + efa = index ? BM_face_at_index_find(vc->em->bm, index - 1) : NULL; if (efa) { struct { float mval_fl[2]; float dist; BMFace *toFace; } data; @@ -612,7 +612,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist) static int lastSelectedIndex = 0; static BMFace *lastSelected = NULL; - if (lastSelected && BM_face_at_index(vc->em->bm, lastSelectedIndex) != lastSelected) { + if (lastSelected && BM_face_at_index_find(vc->em->bm, lastSelectedIndex) != lastSelected) { lastSelectedIndex = 0; lastSelected = NULL; } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 9e5782c12f2..203907226e3 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -1615,7 +1615,7 @@ static bool merge_target(BMEditMesh *em, Scene *scene, View3D *v3d, Object *ob, const float *vco = NULL; if (use_cursor) { - vco = give_cursor(scene, v3d); + vco = ED_view3d_cursor3d_get(scene, v3d); copy_v3_v3(co, vco); mul_m4_v3(ob->imat, co); } @@ -3100,7 +3100,7 @@ void MESH_OT_fill_holes(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_int(ot->srna, "sides", 4, 0, INT_MAX, "Sides", "Number of sides (zero disables)", 0, 100); + RNA_def_int(ot->srna, "sides", 4, 0, INT_MAX, "Sides", "Number of sides in hole required to fill (zero fills all holes)", 0, 100); } static int edbm_beautify_fill_exec(bContext *C, wmOperator *op) @@ -3124,7 +3124,7 @@ static int edbm_beautify_fill_exec(bContext *C, wmOperator *op) void MESH_OT_beautify_fill(wmOperatorType *ot) { /* identifiers */ - ot->name = "Beautify Fill"; + ot->name = "Beautify Faces"; ot->idname = "MESH_OT_beautify_fill"; ot->description = "Rearrange some faces to try to get less degenerated geometry"; @@ -3204,21 +3204,12 @@ static int edbm_quads_convert_to_tris_exec(bContext *C, wmOperator *op) Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); BMOperator bmop; - const bool use_beauty = RNA_boolean_get(op->ptr, "use_beauty"); + const int quad_method = RNA_enum_get(op->ptr, "quad_method"); + const int ngon_method = RNA_enum_get(op->ptr, "ngon_method"); - EDBM_op_init(em, &bmop, op, "triangulate faces=%hf use_beauty=%b", BM_ELEM_SELECT, use_beauty); + EDBM_op_init(em, &bmop, op, "triangulate faces=%hf quad_method=%i ngon_method=%i", BM_ELEM_SELECT, quad_method, ngon_method); BMO_op_exec(em->bm, &bmop); - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true); - - /* now call beauty fill */ - if (use_beauty) { - EDBM_op_call_and_selectf( - em, op, "geom.out", true, - "beautify_fill faces=%S edges=%S", - &bmop, "faces.out", &bmop, "edges.out"); - } - if (!EDBM_op_finish(em, &bmop, op, true)) { return OPERATOR_CANCELLED; } @@ -3243,7 +3234,10 @@ void MESH_OT_quads_convert_to_tris(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_boolean(ot->srna, "use_beauty", 1, "Beauty", "Use best triangulation division"); + RNA_def_enum(ot->srna, "quad_method", modifier_triangulate_quad_method_items, MOD_TRIANGULATE_QUAD_BEAUTY, + "Quad Method", "Method for splitting the quads into triangles"); + RNA_def_enum(ot->srna, "ngon_method", modifier_triangulate_ngon_method_items, MOD_TRIANGULATE_NGON_BEAUTY, + "Polygon Method", "Method for splitting the polygons into triangles"); } static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op) @@ -4712,7 +4706,7 @@ static int mesh_symmetry_snap_exec(bContext *C, wmOperator *op) EDBM_verts_mirror_cache_begin_ex(em, axis, true, true, use_topology, thresh, index); - EDBM_index_arrays_ensure(em, BM_VERT); + BM_mesh_elem_table_ensure(bm, BM_VERT); BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false); @@ -4724,7 +4718,7 @@ static int mesh_symmetry_snap_exec(bContext *C, wmOperator *op) int i_mirr = index[i]; if (i_mirr != -1) { - BMVert *v_mirr = EDBM_vert_at_index(em, index[i]); + BMVert *v_mirr = BM_vert_at_index(bm, index[i]); if (v != v_mirr) { float co[3], co_mirr[3]; diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index e457f7c45af..697876a3877 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -410,134 +410,6 @@ void EDBM_mesh_free(BMEditMesh *em) BKE_editmesh_free(em); } - -void EDBM_index_arrays_ensure(BMEditMesh *em, const char htype) -{ - /* assume if the array is non-null then its valid and no need to recalc */ - const char htype_needed = ((em->vert_index ? 0 : BM_VERT) | - (em->edge_index ? 0 : BM_EDGE) | - (em->face_index ? 0 : BM_FACE)) & htype; - - BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); - - /* in debug mode double check we didn't need to recalculate */ - BLI_assert(EDBM_index_arrays_check(em) == true); - - if (htype_needed & BM_VERT) { - em->vert_index = MEM_mallocN(sizeof(void **) * em->bm->totvert, "em->vert_index"); - } - if (htype_needed & BM_EDGE) { - em->edge_index = MEM_mallocN(sizeof(void **) * em->bm->totedge, "em->edge_index"); - } - if (htype_needed & BM_FACE) { - em->face_index = MEM_mallocN(sizeof(void **) * em->bm->totface, "em->face_index"); - } - -#pragma omp parallel sections if (em->bm->totvert + em->bm->totedge + em->bm->totface >= BM_OMP_LIMIT) - { -#pragma omp section - { - if (htype_needed & BM_VERT) { - BM_iter_as_array(em->bm, BM_VERTS_OF_MESH, NULL, (void **)em->vert_index, em->bm->totvert); - } - } -#pragma omp section - { - if (htype_needed & BM_EDGE) { - BM_iter_as_array(em->bm, BM_EDGES_OF_MESH, NULL, (void **)em->edge_index, em->bm->totedge); - } - } -#pragma omp section - { - if (htype_needed & BM_FACE) { - BM_iter_as_array(em->bm, BM_FACES_OF_MESH, NULL, (void **)em->face_index, em->bm->totface); - } - } - } -} - -/* use EDBM_index_arrays_ensure where possible to avoid full rebuild */ -void EDBM_index_arrays_init(BMEditMesh *em, const char htype) -{ - BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); - - /* force recalc */ - EDBM_index_arrays_free(em); - EDBM_index_arrays_ensure(em, htype); -} - -void EDBM_index_arrays_free(BMEditMesh *em) -{ - if (em->vert_index) { - MEM_freeN(em->vert_index); - em->vert_index = NULL; - } - - if (em->edge_index) { - MEM_freeN(em->edge_index); - em->edge_index = NULL; - } - - if (em->face_index) { - MEM_freeN(em->face_index); - em->face_index = NULL; - } -} - -/* debug check only - no need to optimize */ -#ifndef NDEBUG -bool EDBM_index_arrays_check(BMEditMesh *em) -{ - BMIter iter; - BMElem *ele; - int i; - - if (em->vert_index) { - BM_ITER_MESH_INDEX (ele, &iter, em->bm, BM_VERTS_OF_MESH, i) { - if (ele != (BMElem *)em->vert_index[i]) { - return false; - } - } - } - - if (em->edge_index) { - BM_ITER_MESH_INDEX (ele, &iter, em->bm, BM_EDGES_OF_MESH, i) { - if (ele != (BMElem *)em->edge_index[i]) { - return false; - } - } - } - - if (em->face_index) { - BM_ITER_MESH_INDEX (ele, &iter, em->bm, BM_FACES_OF_MESH, i) { - if (ele != (BMElem *)em->face_index[i]) { - return false; - } - } - } - - return true; -} -#endif - -BMVert *EDBM_vert_at_index(BMEditMesh *em, int index) -{ - BLI_assert((index >= 0) && (index < em->bm->totvert)); - return em->vert_index[index]; -} - -BMEdge *EDBM_edge_at_index(BMEditMesh *em, int index) -{ - BLI_assert((index >= 0) && (index < em->bm->totedge)); - return em->edge_index[index]; -} - -BMFace *EDBM_face_at_index(BMEditMesh *em, int index) -{ - BLI_assert((index >= 0) && (index < em->bm->totface)); - return em->face_index[index]; -} - void EDBM_selectmode_flush_ex(BMEditMesh *em, const short selectmode) { BM_mesh_select_mode_flush_ex(em->bm, selectmode); @@ -710,7 +582,7 @@ void undo_push_mesh(bContext *C, const char *name) /** * Return a new UVVertMap from the editmesh */ -UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, bool use_select, const float limit[2]) +UvVertMap *BM_uv_vert_map_create(BMesh *bm, bool use_select, const float limit[2]) { BMVert *ev; BMFace *efa; @@ -723,15 +595,15 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, bool use_select, const float MLoopUV *luv; unsigned int a; int totverts, i, totuv; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE); + BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE); - totverts = em->bm->totvert; + totverts = bm->totvert; totuv = 0; /* generate UvMapVert array */ - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if ((use_select == false) || BM_elem_flag_test(efa, BM_ELEM_SELECT)) { totuv += efa->len; } @@ -754,7 +626,7 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, bool use_select, const float } a = 0; - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if ((use_select == false) || BM_elem_flag_test(efa, BM_ELEM_SELECT)) { i = 0; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -775,7 +647,7 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, bool use_select, const float /* sort individual uvs for each vert */ a = 0; - BM_ITER_MESH (ev, &iter, em->bm, BM_VERTS_OF_MESH) { + BM_ITER_MESH (ev, &iter, bm, BM_VERTS_OF_MESH) { UvMapVert *newvlist = NULL, *vlist = vmap->vert[a]; UvMapVert *iterv, *v, *lastv, *next; float *uv, *uv2, uvdiff[2]; @@ -786,10 +658,10 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, bool use_select, const float v->next = newvlist; newvlist = v; - efa = EDBM_face_at_index(em, v->f); - /* tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */ + efa = BM_face_at_index(bm, v->f); + /* tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */ - l = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa, v->tfindex); + l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, v->tfindex); luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); uv = luv->uv; @@ -798,10 +670,10 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, bool use_select, const float while (iterv) { next = iterv->next; - efa = EDBM_face_at_index(em, iterv->f); - /* tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */ + efa = BM_face_at_index(bm, iterv->f); + /* tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */ - l = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa, iterv->tfindex); + l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, iterv->tfindex); luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); uv2 = luv->uv; @@ -831,7 +703,7 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, bool use_select, const float } -UvMapVert *EDBM_uv_vert_map_at_index(UvVertMap *vmap, unsigned int v) +UvMapVert *BM_uv_vert_map_at_index(UvVertMap *vmap, unsigned int v) { return vmap->vert[v]; } @@ -840,7 +712,7 @@ UvMapVert *EDBM_uv_vert_map_at_index(UvVertMap *vmap, unsigned int v) /* A specialized vert map used by stitch operator */ -UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, const bool selected, const bool do_islands) +UvElementMap *BM_uv_element_map_create(BMesh *bm, const bool selected, const bool do_islands) { BMVert *ev; BMFace *efa; @@ -860,20 +732,20 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, const bool selected, co BMFace **stack; int stacksize = 0; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE); + BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE); - totverts = em->bm->totvert; + totverts = bm->totvert; totuv = 0; - island_number = MEM_mallocN(sizeof(*stack) * em->bm->totface, "uv_island_number_face"); + island_number = MEM_mallocN(sizeof(*stack) * bm->totface, "uv_island_number_face"); if (!island_number) { return NULL; } /* generate UvElement array */ - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (!selected || BM_elem_flag_test(efa, BM_ELEM_SELECT)) { totuv += efa->len; } @@ -893,13 +765,13 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, const bool selected, co buf = element_map->buf = (UvElement *)MEM_callocN(sizeof(*element_map->buf) * totuv, "UvElement"); if (!element_map->vert || !element_map->buf) { - EDBM_uv_element_map_free(element_map); + BM_uv_element_map_free(element_map); MEM_freeN(island_number); return NULL; } j = 0; - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { island_number[j++] = INVALID_ISLAND; if (!selected || BM_elem_flag_test(efa, BM_ELEM_SELECT)) { BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { @@ -918,7 +790,7 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, const bool selected, co /* sort individual uvs for each vert */ i = 0; - BM_ITER_MESH (ev, &iter, em->bm, BM_VERTS_OF_MESH) { + BM_ITER_MESH (ev, &iter, bm, BM_VERTS_OF_MESH) { UvElement *newvlist = NULL, *vlist = element_map->vert[i]; UvElement *iterv, *v, *lastv, *next; float *uv, *uv2, uvdiff[2]; @@ -968,7 +840,7 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, const bool selected, co if (do_islands) { /* map holds the map from current vmap->buf to the new, sorted map */ map = MEM_mallocN(sizeof(*map) * totuv, "uvelement_remap"); - stack = MEM_mallocN(sizeof(*stack) * em->bm->totface, "uv_island_face_stack"); + stack = MEM_mallocN(sizeof(*stack) * bm->totface, "uv_island_face_stack"); islandbuf = MEM_callocN(sizeof(*islandbuf) * totuv, "uvelement_island_buffer"); /* at this point, every UvElement in vert points to a UvElement sharing the same vertex. Now we should sort uv's in islands. */ @@ -1019,7 +891,7 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, const bool selected, co } /* remap */ - for (i = 0; i < em->bm->totvert; i++) { + for (i = 0; i < bm->totvert; i++) { /* important since we may do selection only. Some of these may be NULL */ if (element_map->vert[i]) element_map->vert[i] = &islandbuf[map[element_map->vert[i] - element_map->buf]]; @@ -1030,7 +902,7 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, const bool selected, co MEM_freeN(islandbuf); MEM_freeN(stack); MEM_freeN(map); - EDBM_uv_element_map_free(element_map); + BM_uv_element_map_free(element_map); MEM_freeN(island_number); } @@ -1060,7 +932,7 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, const bool selected, co return element_map; } -void EDBM_uv_vert_map_free(UvVertMap *vmap) +void BM_uv_vert_map_free(UvVertMap *vmap) { if (vmap) { if (vmap->vert) MEM_freeN(vmap->vert); @@ -1069,7 +941,7 @@ void EDBM_uv_vert_map_free(UvVertMap *vmap) } } -void EDBM_uv_element_map_free(UvElementMap *element_map) +void BM_uv_element_map_free(UvElementMap *element_map) { if (element_map) { if (element_map->vert) MEM_freeN(element_map->vert); @@ -1079,7 +951,7 @@ void EDBM_uv_element_map_free(UvElementMap *element_map) } } -UvElement *ED_uv_element_get(UvElementMap *map, BMFace *efa, BMLoop *l) +UvElement *BM_uv_element_get(UvElementMap *map, BMFace *efa, BMLoop *l) { UvElement *element; @@ -1182,7 +1054,7 @@ void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, const int axis, const bool struct BMBVHTree *tree = NULL; MirrTopoStore_t mesh_topo_store = {NULL, -1, -1, -1}; - EDBM_index_arrays_ensure(em, BM_VERT); + BM_mesh_elem_table_ensure(bm, BM_VERT); if (r_index == NULL) { const char *layer_id = BM_CD_LAYER_ID; @@ -1204,7 +1076,7 @@ void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, const int axis, const bool ED_mesh_mirrtopo_init(me, -1, &mesh_topo_store, true); } else { - tree = BKE_bmbvh_new(em, 0, NULL, false); + tree = BKE_bmbvh_new_from_editmesh(em, 0, NULL, false); } #define VERT_INTPTR(_v, _i) r_index ? &r_index[_i] : BM_ELEM_CD_GET_VOID_P(_v, cd_vmirr_offset); @@ -1270,13 +1142,13 @@ BMVert *EDBM_verts_mirror_get(BMEditMesh *em, BMVert *v) BLI_assert(em->mirror_cdlayer != -1); /* invalid use */ if (mirr && *mirr >= 0 && *mirr < em->bm->totvert) { - if (!em->vert_index) { + if (!em->bm->vtable) { printf("err: should only be called between " "EDBM_verts_mirror_cache_begin and EDBM_verts_mirror_cache_end"); return NULL; } - return em->vert_index[*mirr]; + return em->bm->vtable[*mirr]; } return NULL; @@ -1335,7 +1207,7 @@ void EDBM_verts_mirror_apply(BMEditMesh *em, const int sel_from, const int sel_t BMIter iter; BMVert *v; - BLI_assert(em->vert_index != NULL); + BLI_assert((em->bm->vtable != NULL) && ((em->bm->elem_table_dirty & BM_VERT) == 0)); BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_SELECT) == sel_from) { @@ -1447,11 +1319,12 @@ void EDBM_update_generic(BMEditMesh *em, const bool do_tessface, const bool is_d } if (is_destructive) { - EDBM_index_arrays_free(em); + /* TODO. we may be able to remove this now! - Campbell */ + // BM_mesh_elem_table_free(em->bm, BM_ALL_NOLOOP); } else { /* in debug mode double check we didn't need to recalculate */ - BLI_assert(EDBM_index_arrays_check(em) == true); + BLI_assert(BM_mesh_elem_table_check(em->bm) == true); } } diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index e8cbf0926d4..f35a46b50d3 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -417,7 +417,7 @@ int ED_mesh_color_add(Mesh *me, const char *name, const bool active_set) } else { layernum = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); - if (layernum >= CD_MLOOPCOL) { + if (layernum >= MAX_MCOL) { return -1; } diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index ed026258e4b..98c145c9ce7 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -116,7 +116,8 @@ void MESH_OT_inset(struct wmOperatorType *ot); /* *** editmesh_knife.c *** */ void MESH_OT_knife_tool(struct wmOperatorType *ot); void MESH_OT_knife_project(struct wmOperatorType *ot); -void EDBM_mesh_knife(struct bContext *C, struct LinkNode *polys, bool use_tag); +void EDBM_mesh_knife(struct bContext *C, struct LinkNode *polys, + bool use_tag, bool cut_through); struct wmKeyMap *knifetool_modal_keymap(struct wmKeyConfig *keyconf); diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c index 83feed6756f..433fd176217 100644 --- a/source/blender/editors/mesh/mesh_navmesh.c +++ b/source/blender/editors/mesh/mesh_navmesh.c @@ -389,7 +389,7 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh, } /* need to rebuild entirely because array size changes */ - EDBM_index_arrays_init(em, BM_VERT); + BM_mesh_elem_table_init(em->bm, BM_VERT); /* create faces */ for (j = 0; j < trinum; j++) { @@ -404,9 +404,9 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh, face[k] = uniquevbase + tri[k] - nv; /* unique vertex */ } newFace = BM_face_create_quad_tri(em->bm, - EDBM_vert_at_index(em, face[0]), - EDBM_vert_at_index(em, face[2]), - EDBM_vert_at_index(em, face[1]), NULL, + BM_vert_at_index(em->bm, face[0]), + BM_vert_at_index(em->bm, face[2]), + BM_vert_at_index(em->bm, face[1]), NULL, NULL, false); /* set navigation polygon idx to the custom layer */ diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index c98ad13acf6..3c42beb8b12 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -29,6 +29,7 @@ */ #include "DNA_scene_types.h" +#include "DNA_modifier_types.h" #include "BLI_math.h" @@ -244,6 +245,13 @@ void ED_operatormacros_mesh(void) RNA_enum_set(otmacro->ptr, "proportional", 0); RNA_boolean_set(otmacro->ptr, "mirror", false); + ot = WM_operatortype_append_macro("MESH_OT_extrude_region_shrink_fatten", "Extrude Region and Shrink/Fatten", + "Extrude region and move result", OPTYPE_UNDO | OPTYPE_REGISTER); + otmacro = WM_operatortype_macro_define(ot, "MESH_OT_extrude_region"); + otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_shrink_fatten"); + RNA_enum_set(otmacro->ptr, "proportional", 0); + RNA_boolean_set(otmacro->ptr, "mirror", false); + ot = WM_operatortype_append_macro("MESH_OT_extrude_faces_move", "Extrude Individual Faces and Move", "Extrude faces and move result", OPTYPE_UNDO | OPTYPE_REGISTER); otmacro = WM_operatortype_macro_define(ot, "MESH_OT_extrude_faces_indiv"); @@ -352,9 +360,11 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MESH_OT_beautify_fill", FKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0); kmi = WM_keymap_add_item(keymap, "MESH_OT_quads_convert_to_tris", TKEY, KM_PRESS, KM_CTRL, 0); - RNA_boolean_set(kmi->ptr, "use_beauty", true); + RNA_enum_set(kmi->ptr, "quad_method", MOD_TRIANGULATE_QUAD_BEAUTY); + RNA_enum_set(kmi->ptr, "ngon_method", MOD_TRIANGULATE_NGON_BEAUTY); kmi = WM_keymap_add_item(keymap, "MESH_OT_quads_convert_to_tris", TKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "use_beauty", false); + RNA_enum_set(kmi->ptr, "quad_method", MOD_TRIANGULATE_QUAD_FIXED); + RNA_enum_set(kmi->ptr, "ngon_method", MOD_TRIANGULATE_NGON_SCANFILL); WM_keymap_add_item(keymap, "MESH_OT_tris_convert_to_quads", JKEY, KM_PRESS, KM_ALT, 0); diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 5ee980ef5cb..1d47d4c49df 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -1014,7 +1014,7 @@ BMVert *editbmesh_get_x_mirror_vert(Object *ob, struct BMEditMesh *em, BMVert *e /** * Wrapper for objectmode/editmode. * - * call #EDBM_index_arrays_ensure first for editmesh. + * call #BM_mesh_elem_table_ensure first for editmesh. */ int ED_mesh_mirror_get_vert(Object *ob, int index) { @@ -1025,7 +1025,7 @@ int ED_mesh_mirror_get_vert(Object *ob, int index) if (em) { BMVert *eve, *eve_mirr; - eve = EDBM_vert_at_index(em, index); + eve = BM_vert_at_index(em->bm, index); eve_mirr = editbmesh_get_x_mirror_vert(ob, em, eve, eve->co, index, use_topology); index_mirr = eve_mirr ? BM_elem_index_get(eve_mirr) : -1; } @@ -1231,6 +1231,29 @@ bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int return true; } +static void ed_mesh_pick_face_vert__mpoly_find( + /* context */ + struct ARegion *ar, const float mval[2], + /* mesh data */ + DerivedMesh *dm, MPoly *mp, MLoop *mloop, + /* return values */ + float *r_len_best, int *r_v_idx_best) +{ + const MLoop *ml; + int j = mp->totloop; + for (ml = &mloop[mp->loopstart]; j--; ml++) { + float co[3], sco[2], len; + const int v_idx = ml->v; + dm->getVertCo(dm, v_idx, co); + if (ED_view3d_project_float_object(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { + len = len_manhattan_v2v2(mval, sco); + if (len < *r_len_best) { + *r_len_best = len; + *r_v_idx_best = v_idx; + } + } + } +} /** * Use when the back buffer stores face index values. but we want a vert. * This gets the face then finds the closest vertex to mval. @@ -1247,39 +1270,61 @@ bool ED_mesh_pick_face_vert(bContext *C, Object *ob, const int mval[2], unsigned struct ARegion *ar = CTX_wm_region(C); /* derived mesh to find deformed locations */ - DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); - int v_idx_best = -1; - - if (dm->getVertCo) { - RegionView3D *rv3d = ar->regiondata; - - /* find the vert closest to 'mval' */ - const float mval_f[2] = {(float)mval[0], - (float)mval[1]}; - MPoly *mp = &me->mpoly[poly_index]; - int fidx; - float len_best = FLT_MAX; - - ED_view3d_init_mats_rv3d(ob, rv3d); - - fidx = mp->totloop - 1; - do { - float co[3], sco[2], len; - const int v_idx = me->mloop[mp->loopstart + fidx].v; - dm->getVertCo(dm, v_idx, co); - if (ED_view3d_project_float_object(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { - len = len_manhattan_v2v2(mval_f, sco); - if (len < len_best) { - len_best = len; - v_idx_best = v_idx; - } + DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); + + int v_idx_best = ORIGINDEX_NONE; + + /* find the vert closest to 'mval' */ + const float mval_f[2] = {UNPACK2(mval)}; + float len_best = FLT_MAX; + + MPoly *dm_mpoly; + MLoop *dm_mloop; + unsigned int dm_mpoly_tot; + const int *index_mp_to_orig; + + dm_mpoly = dm->getPolyArray(dm); + dm_mloop = dm->getLoopArray(dm); + + dm_mpoly_tot = dm->getNumPolys(dm); + + index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + + /* tag all verts using this face */ + if (index_mp_to_orig) { + unsigned int i; + + for (i = 0; i < dm_mpoly_tot; i++) { + if (index_mp_to_orig[i] == poly_index) { + ed_mesh_pick_face_vert__mpoly_find( + ar, mval_f, + dm, &dm_mpoly[i], dm_mloop, + &len_best, &v_idx_best); } - } while (fidx--); + } + } + else { + if (poly_index < dm_mpoly_tot) { + ed_mesh_pick_face_vert__mpoly_find( + ar, mval_f, + dm, &dm_mpoly[poly_index], dm_mloop, + &len_best, &v_idx_best); + } + } + + /* map 'dm -> me' index if possible */ + if (v_idx_best != ORIGINDEX_NONE) { + const int *index_mv_to_orig; + + index_mv_to_orig = dm->getVertDataArray(dm, CD_ORIGINDEX); + if (index_mv_to_orig) { + v_idx_best = index_mv_to_orig[v_idx_best]; + } } dm->release(dm); - if (v_idx_best != -1) { + if ((v_idx_best != ORIGINDEX_NONE) && (v_idx_best < me->totvert)) { *index = v_idx_best; return true; } diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index 68ca55651a8..deae9f17992 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -178,6 +178,193 @@ void MBALL_OT_select_all(wmOperatorType *ot) WM_operator_properties_select_all(ot); } + +/* -------------------------------------------------------------------- */ +/* Select Similar */ + +enum { + SIMMBALL_TYPE = 1, + SIMMBALL_RADIUS, + SIMMBALL_STIFFNESS, + SIMMBALL_ROTATION +}; + +static EnumPropertyItem prop_similar_types[] = { + {SIMMBALL_TYPE, "TYPE", 0, "Type", ""}, + {SIMMBALL_RADIUS, "RADIUS", 0, "Radius", ""}, + {SIMMBALL_STIFFNESS, "STIFFNESS", 0, "Stiffness", ""}, + {SIMMBALL_ROTATION, "ROTATION", 0, "Rotation", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static bool mball_select_similar_type(MetaBall *mb) +{ + MetaElem *ml; + bool change = false; + + for (ml = mb->editelems->first; ml; ml = ml->next) { + if (ml->flag & SELECT) { + MetaElem *ml_iter; + + for (ml_iter = mb->editelems->first; ml_iter; ml_iter = ml_iter->next) { + if ((ml_iter->flag & SELECT) == 0) { + if (ml->type == ml_iter->type) { + ml_iter->flag |= SELECT; + change = true; + } + } + } + } + } + + return change; +} + +static bool mball_select_similar_radius(MetaBall *mb, const float thresh) +{ + MetaElem *ml; + bool change = false; + + for (ml = mb->editelems->first; ml; ml = ml->next) { + if (ml->flag & SELECT) { + MetaElem *ml_iter; + + for (ml_iter = mb->editelems->first; ml_iter; ml_iter = ml_iter->next) { + if ((ml_iter->flag & SELECT) == 0) { + if (fabsf(ml_iter->rad - ml->rad) <= (thresh * ml->rad)) { + ml_iter->flag |= SELECT; + change = true; + } + } + } + } + } + + return change; +} + +static bool mball_select_similar_stiffness(MetaBall *mb, const float thresh) +{ + MetaElem *ml; + bool change = false; + + for (ml = mb->editelems->first; ml; ml = ml->next) { + if (ml->flag & SELECT) { + MetaElem *ml_iter; + + for (ml_iter = mb->editelems->first; ml_iter; ml_iter = ml_iter->next) { + if ((ml_iter->flag & SELECT) == 0) { + if (fabsf(ml_iter->s - ml->s) <= thresh) { + ml_iter->flag |= SELECT; + change = true; + } + } + } + } + } + + return change; +} + +static bool mball_select_similar_rotation(MetaBall *mb, const float thresh) +{ + const float thresh_rad = thresh * (float)M_PI_2; + MetaElem *ml; + bool change = false; + + for (ml = mb->editelems->first; ml; ml = ml->next) { + if (ml->flag & SELECT) { + MetaElem *ml_iter; + + float ml_mat[3][3]; + + unit_m3(ml_mat); + mul_qt_v3(ml->quat, ml_mat[0]); + mul_qt_v3(ml->quat, ml_mat[1]); + mul_qt_v3(ml->quat, ml_mat[2]); + normalize_m3(ml_mat); + + for (ml_iter = mb->editelems->first; ml_iter; ml_iter = ml_iter->next) { + if ((ml_iter->flag & SELECT) == 0) { + float ml_iter_mat[3][3]; + + unit_m3(ml_iter_mat); + mul_qt_v3(ml_iter->quat, ml_iter_mat[0]); + mul_qt_v3(ml_iter->quat, ml_iter_mat[1]); + mul_qt_v3(ml_iter->quat, ml_iter_mat[2]); + normalize_m3(ml_iter_mat); + + if ((angle_normalized_v3v3(ml_mat[0], ml_iter_mat[0]) + + angle_normalized_v3v3(ml_mat[1], ml_iter_mat[1]) + + angle_normalized_v3v3(ml_mat[2], ml_iter_mat[2])) < thresh_rad) + { + ml_iter->flag |= SELECT; + change = true; + } + } + } + } + } + + return change; +} + +static int mball_select_similar_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + MetaBall *mb = (MetaBall *)obedit->data; + + int type = RNA_enum_get(op->ptr, "type"); + float thresh = RNA_float_get(op->ptr, "threshold"); + bool change = false; + + switch (type) { + case SIMMBALL_TYPE: + change = mball_select_similar_type(mb); + break; + case SIMMBALL_RADIUS: + change = mball_select_similar_radius(mb, thresh); + break; + case SIMMBALL_STIFFNESS: + change = mball_select_similar_stiffness(mb, thresh); + break; + case SIMMBALL_ROTATION: + change = mball_select_similar_rotation(mb, thresh); + break; + default: + BLI_assert(0); + break; + } + + if (change) { + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb); + } + + return OPERATOR_FINISHED; +} + +void MBALL_OT_select_similar(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Similar"; + ot->idname = "MBALL_OT_select_similar"; + + /* callback functions */ + ot->invoke = WM_menu_invoke; + ot->exec = mball_select_similar_exec; + ot->poll = ED_operator_editmball; + ot->description = "Select similar metaballs by property types"; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "type", prop_similar_types, 0, "Type", ""); + + RNA_def_float(ot->srna, "threshold", 0.1, 0.0, 1.0, "Threshold", "", 0.01, 1.0); +} + + /***************************** Select random operator *****************************/ /* Random metaball selection */ @@ -255,19 +442,6 @@ static int duplicate_metaelems_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } -static int duplicate_metaelems_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - int retv = duplicate_metaelems_exec(C, op); - - if (retv == OPERATOR_FINISHED) { - RNA_enum_set(op->ptr, "mode", TFM_TRANSLATION); - WM_operator_name_call(C, "TRANSFORM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr); - } - - return retv; -} - - void MBALL_OT_duplicate_metaelems(wmOperatorType *ot) { /* identifiers */ @@ -277,14 +451,10 @@ void MBALL_OT_duplicate_metaelems(wmOperatorType *ot) /* callback functions */ ot->exec = duplicate_metaelems_exec; - ot->invoke = duplicate_metaelems_invoke; ot->poll = ED_operator_editmball; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* to give to transform */ - RNA_def_enum(ot->srna, "mode", transform_mode_types, TFM_TRANSLATION, "Mode", ""); } /***************************** Delete operator *****************************/ diff --git a/source/blender/editors/metaball/mball_intern.h b/source/blender/editors/metaball/mball_intern.h index 0329f8e5bfa..24a4ea86d87 100644 --- a/source/blender/editors/metaball/mball_intern.h +++ b/source/blender/editors/metaball/mball_intern.h @@ -43,6 +43,7 @@ void MBALL_OT_delete_metaelems(struct wmOperatorType *ot); void MBALL_OT_duplicate_metaelems(struct wmOperatorType *ot); void MBALL_OT_select_all(struct wmOperatorType *ot); +void MBALL_OT_select_similar(struct wmOperatorType *ot); void MBALL_OT_select_random_metaelems(struct wmOperatorType *ot); #endif diff --git a/source/blender/editors/metaball/mball_ops.c b/source/blender/editors/metaball/mball_ops.c index bba0dc5000b..249e7361cc0 100644 --- a/source/blender/editors/metaball/mball_ops.c +++ b/source/blender/editors/metaball/mball_ops.c @@ -52,9 +52,23 @@ void ED_operatortypes_metaball(void) WM_operatortype_append(MBALL_OT_reveal_metaelems); WM_operatortype_append(MBALL_OT_select_all); + WM_operatortype_append(MBALL_OT_select_similar); WM_operatortype_append(MBALL_OT_select_random_metaelems); } +void ED_operatormacros_metaball(void) +{ + wmOperatorType *ot; + wmOperatorTypeMacro *otmacro; + + ot = WM_operatortype_append_macro("MBALL_OT_duplicate_move", "Duplicate", + "Make copies of the selected bones within the same armature and move them", + OPTYPE_UNDO | OPTYPE_REGISTER); + WM_operatortype_macro_define(ot, "MBALL_OT_duplicate_metaelems"); + otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); + RNA_enum_set(otmacro->ptr, "proportional", 0); +} + void ED_keymap_metaball(wmKeyConfig *keyconf) { wmKeyMap *keymap; @@ -73,13 +87,15 @@ void ED_keymap_metaball(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MBALL_OT_delete_metaelems", XKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "MBALL_OT_delete_metaelems", DELKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "MBALL_OT_duplicate_metaelems", DKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "MBALL_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0); kmi = WM_keymap_add_item(keymap, "MBALL_OT_select_all", AKEY, KM_PRESS, 0, 0); RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); kmi = WM_keymap_add_item(keymap, "MBALL_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + WM_keymap_add_item(keymap, "MBALL_OT_select_similar", GKEY, KM_PRESS, KM_SHIFT, 0); + ED_keymap_proportional_cycle(keyconf, keymap); ED_keymap_proportional_editmode(keyconf, keymap, TRUE); } diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index 3e7aeba63c3..143a33c3fdd 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -53,6 +53,7 @@ set(SRC object_select.c object_shapekey.c object_transform.c + object_warp.c object_vgroup.c object_intern.h diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index db68a0eca4d..9dd686326bb 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -152,7 +152,7 @@ void ED_object_location_from_view(bContext *C, float loc[3]) Scene *scene = CTX_data_scene(C); const float *cursor; - cursor = give_cursor(scene, v3d); + cursor = ED_view3d_cursor3d_get(scene, v3d); copy_v3_v3(loc, cursor); } @@ -1220,9 +1220,11 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, const short use_base_parent, const short use_hierarchy) { + Main *bmain = CTX_data_main(C); ListBase *lb; DupliObject *dob; GHash *dupli_gh = NULL, *parent_gh = NULL; + Object *object; if (!(base->object->transflag & OB_DUPLI)) return; @@ -1237,6 +1239,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, for (dob = lb->first; dob; dob = dob->next) { Base *basen; Object *ob = BKE_object_copy(dob->ob); + /* font duplis can have a totcol without material, we get them from parent * should be implemented better... */ @@ -1330,6 +1333,17 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, } } + /* The same how BKE_object_unlink detects which object proxies to clear. */ + if (base->object->transflag & OB_DUPLIGROUP && base->object->dup_group) { + for (object = bmain->object.first; object; object = object->id.next) { + if (object->proxy_group == base->object) { + object->proxy = NULL; + object->proxy_from = NULL; + DAG_id_tag_update(&object->id, OB_RECALC_OB); + } + } + } + if (dupli_gh) BLI_ghash_free(dupli_gh, NULL, NULL); if (parent_gh) @@ -1603,6 +1617,9 @@ static int convert_exec(bContext *C, wmOperator *op) for (nu = cu->nurb.first; nu; nu = nu->next) nu->charidx = 0; + cu->flag &= ~CU_3D; + BKE_curve_curve_dimension_update(cu); + if (target == OB_MESH) { curvetomesh(scene, newob); diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 4a8097f260e..55564703a87 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -156,12 +156,6 @@ static bool multiresbake_check(bContext *C, wmOperator *op) break; } - if (mmd->lvl == 0) { - BKE_report(op->reports, RPT_ERROR, "Multires data baking is not supported for preview subdivision level 0"); - ok = false; - break; - } - if (!me->mtpoly) { BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking"); @@ -214,28 +208,23 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l DerivedMesh *dm; MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); Mesh *me = (Mesh *)ob->data; + MultiresModifierData tmp_mmd = *mmd; + DerivedMesh *cddm = CDDM_from_mesh(me, ob); - *lvl = mmd->lvl; - - if (*lvl == 0) { - DerivedMesh *tmp_dm = CDDM_from_mesh(me, ob); - - DM_set_only_copy(tmp_dm, CD_MASK_BAREMESH | CD_MASK_MTFACE); - - dm = CDDM_copy(tmp_dm); - tmp_dm->release(tmp_dm); + if (mmd->lvl > 0) { + *lvl = mmd->lvl; } else { - MultiresModifierData tmp_mmd = *mmd; - DerivedMesh *cddm = CDDM_from_mesh(me, ob); + *lvl = 1; + tmp_mmd.simple = true; + } - DM_set_only_copy(cddm, CD_MASK_BAREMESH | CD_MASK_MTFACE); + DM_set_only_copy(cddm, CD_MASK_BAREMESH | CD_MASK_MTFACE); - tmp_mmd.lvl = *lvl; - tmp_mmd.sculptlvl = *lvl; - dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0); - cddm->release(cddm); - } + tmp_mmd.lvl = *lvl; + tmp_mmd.sculptlvl = *lvl; + dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0); + cddm->release(cddm); return dm; } @@ -556,7 +545,7 @@ static int multiresbake_image_exec(bContext *C, wmOperator *op) wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Multires Bake", WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE); WM_jobs_customdata_set(wm_job, bkr, multiresbake_freejob); - WM_jobs_timer(wm_job, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */ + WM_jobs_timer(wm_job, 0.5, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */ WM_jobs_callbacks(wm_job, multiresbake_startjob, NULL, NULL, NULL); G.is_break = FALSE; @@ -816,7 +805,7 @@ static int objects_bake_render_invoke(bContext *C, wmOperator *op, const wmEvent wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake", WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE); WM_jobs_customdata_set(wm_job, bkr, bake_freejob); - WM_jobs_timer(wm_job, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */ + WM_jobs_timer(wm_job, 0.5, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */ WM_jobs_callbacks(wm_job, bake_startjob, NULL, bake_update, NULL); G.is_break = FALSE; diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 8af9401e30f..d4fac49e973 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -1331,7 +1331,7 @@ static int pose_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op)) /* do updates */ DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob); + WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, ob); return OPERATOR_FINISHED; } @@ -1365,7 +1365,7 @@ static int object_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op)) DAG_relations_tag_update(bmain); /* do updates */ - WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, NULL); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index bd4c2e997fe..2e011493fce 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -351,7 +351,7 @@ static bool ED_object_editmode_load_ex(Object *obedit, const bool freedata) load_editNurb(obedit); if (freedata) free_editNurb(obedit); } - else if (obedit->type == OB_FONT && freedata) { + else if (obedit->type == OB_FONT) { load_editText(obedit); if (freedata) free_editText(obedit); } @@ -1110,6 +1110,23 @@ static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, View3D * /* ******************* force field toggle operator ***************** */ +void ED_object_check_force_modifiers(Main *bmain, Scene *scene, Object *object) +{ + PartDeflect *pd = object->pd; + ModifierData *md = modifiers_findByType(object, eModifierType_Surface); + + /* add/remove modifier as needed */ + if (!md) { + if (pd && (pd->shape == PFIELD_SHAPE_SURFACE) && ELEM(pd->forcefield, PFIELD_GUIDE, PFIELD_TEXTURE) == 0) + if (ELEM4(object->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVE)) + ED_object_modifier_add(NULL, bmain, scene, object, NULL, eModifierType_Surface); + } + else { + if (!pd || pd->shape != PFIELD_SHAPE_SURFACE || pd->forcefield != PFIELD_FORCE) + ED_object_modifier_remove(NULL, bmain, object, md); + } +} + static int forcefield_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = CTX_data_active_object(C); @@ -1122,7 +1139,9 @@ static int forcefield_toggle_exec(bContext *C, wmOperator *UNUSED(op)) else ob->pd->forcefield = 0; - WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL); + ED_object_check_force_modifiers(CTX_data_main(C), CTX_data_scene(C), ob); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c index 37656f82b25..7f97aa0b4c1 100644 --- a/source/blender/editors/object/object_hook.c +++ b/source/blender/editors/object/object_hook.c @@ -65,6 +65,7 @@ #include "ED_curve.h" #include "ED_mesh.h" #include "ED_screen.h" +#include "ED_object.h" #include "WM_types.h" #include "WM_api.h" @@ -701,26 +702,9 @@ static int object_hook_reset_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_ERROR, "Could not find hook modifier"); return OPERATOR_CANCELLED; } - - /* reset functionality */ - if (hmd->object) { - bPoseChannel *pchan = BKE_pose_channel_find_name(hmd->object->pose, hmd->subtarget); - - if (hmd->subtarget[0] && pchan) { - float imat[4][4], mat[4][4]; - - /* calculate the world-space matrix for the pose-channel target first, then carry on as usual */ - mul_m4_m4m4(mat, hmd->object->obmat, pchan->pose_mat); - - invert_m4_m4(imat, mat); - mul_m4_m4m4(hmd->parentinv, imat, ob->obmat); - } - else { - invert_m4_m4(hmd->object->imat, hmd->object->obmat); - mul_m4_m4m4(hmd->parentinv, hmd->object->imat, ob->obmat); - } - } - + + BKE_object_modifier_hook_reset(ob, hmd); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 4ff3bc9ac06..bfed1f2f982 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -222,6 +222,7 @@ void OBJECT_OT_vertex_group_fix(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_invert(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_blend(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_clean(struct wmOperatorType *ot); +void OBJECT_OT_vertex_group_quantize(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_limit_total(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_mirror(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_set_active(struct wmOperatorType *ot); @@ -233,6 +234,9 @@ void OBJECT_OT_vertex_weight_set_active(struct wmOperatorType *ot); void OBJECT_OT_vertex_weight_normalize_active_vertex(struct wmOperatorType *ot); void OBJECT_OT_vertex_weight_copy(struct wmOperatorType *ot); +/* object_warp.c */ +void OBJECT_OT_vertex_warp(struct wmOperatorType *ot); + /* object_shapekey.c */ void OBJECT_OT_shape_key_add(struct wmOperatorType *ot); void OBJECT_OT_shape_key_remove(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index a79b0607421..3425aa08955 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -528,7 +528,7 @@ typedef enum eLattice_FlipAxes { LATTICE_FLIP_W = 2 } eLattice_FlipAxes; -/* Flip midpoint value so that relative distances between midpoint and neighbour-pair is maintained +/* Flip midpoint value so that relative distances between midpoint and neighbor-pair is maintained * ! Assumes that uvw <=> xyz (i.e. axis-aligned index-axes with coordinate-axes) * - Helper for lattice_flip_exec() */ diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 0ba84e27420..01dafe69d31 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -87,7 +87,6 @@ #include "object_intern.h" -static void modifier_skin_customdata_ensure(struct Object *ob); static void modifier_skin_customdata_delete(struct Object *ob); /******************************** API ****************************/ @@ -299,9 +298,6 @@ static int object_modifier_remove(Main *bmain, Object *ob, ModifierData *md, *sort_depsgraph = 1; } else if (md->type == eModifierType_Surface) { - if (ob->pd && ob->pd->shape == PFIELD_SHAPE_SURFACE) - ob->pd->shape = PFIELD_SHAPE_PLANE; - *sort_depsgraph = 1; } else if (md->type == eModifierType_Multires) { @@ -1434,7 +1430,7 @@ void OBJECT_OT_multires_base_apply(wmOperatorType *ot) /************************** skin modifier ***********************/ -static void modifier_skin_customdata_ensure(Object *ob) +void modifier_skin_customdata_ensure(Object *ob) { Mesh *me = ob->data; BMesh *bm = me->edit_btmesh ? me->edit_btmesh->bm : NULL; @@ -1857,7 +1853,7 @@ void OBJECT_OT_skin_armature_create(wmOperatorType *ot) static int meshdeform_poll(bContext *C) { - return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier, (1 << OB_MESH)); + return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier, 0); } static int meshdeform_bind_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 333e5ff3006..6d760acb698 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -191,6 +191,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_levels); WM_operatortype_append(OBJECT_OT_vertex_group_blend); WM_operatortype_append(OBJECT_OT_vertex_group_clean); + WM_operatortype_append(OBJECT_OT_vertex_group_quantize); WM_operatortype_append(OBJECT_OT_vertex_group_limit_total); WM_operatortype_append(OBJECT_OT_vertex_group_mirror); WM_operatortype_append(OBJECT_OT_vertex_group_set_active); @@ -202,6 +203,8 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_weight_normalize_active_vertex); WM_operatortype_append(OBJECT_OT_vertex_weight_copy); + WM_operatortype_append(OBJECT_OT_vertex_warp); + WM_operatortype_append(OBJECT_OT_game_property_new); WM_operatortype_append(OBJECT_OT_game_property_remove); WM_operatortype_append(OBJECT_OT_game_property_copy); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index be4948d8a80..c70a70c47b2 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2211,6 +2211,8 @@ static int make_single_user_exec(bContext *C, wmOperator *op) int flag = RNA_enum_get(op->ptr, "type"); /* 0==ALL, SELECTED==selected objecs */ bool copy_groups = false; + clear_id_newpoins(); + if (RNA_boolean_get(op->ptr, "object")) single_object_users(bmain, scene, v3d, flag, copy_groups); @@ -2227,6 +2229,11 @@ static int make_single_user_exec(bContext *C, wmOperator *op) if (RNA_boolean_get(op->ptr, "animation")) single_object_action_users(scene, flag); + /* TODO(sergey): This should not be needed, however some tool still could rely + * on the fact, that id->newid is kept NULL by default. + * Need to make sure all the guys are learing newid before they're + * using it, not after. + */ clear_id_newpoins(); WM_event_add_notifier(C, NC_WINDOW, NULL); diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index 974dc3acef9..ffa9eed65b9 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -1078,12 +1078,12 @@ static int object_select_mirror_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN (C, Base *, primbase, selected_bases) { - char tmpname[MAXBONENAME]; + char name_flip[MAXBONENAME]; - flip_side_name(tmpname, primbase->object->id.name + 2, TRUE); + BKE_deform_flip_side_name(name_flip, primbase->object->id.name + 2, true); - if (strcmp(tmpname, primbase->object->id.name + 2) != 0) { /* names differ */ - Object *ob = (Object *)BKE_libblock_find_name(ID_OB, tmpname); + if (!STREQ(name_flip, primbase->object->id.name + 2)) { + Object *ob = (Object *)BKE_libblock_find_name(ID_OB, name_flip); if (ob) { Base *secbase = BKE_scene_base_find(scene, ob); diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index ea96db514b2..6be4a2fed2c 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -290,6 +290,17 @@ static int shape_key_mode_poll(bContext *C) return (ob && !ob->id.lib && data && !data->lib && ob->mode != OB_MODE_EDIT); } +static int shape_key_mode_exists_poll(bContext *C) +{ + Object *ob = ED_object_context(C); + ID *data = (ob) ? ob->data : NULL; + + /* same as shape_key_mode_poll */ + return (ob && !ob->id.lib && data && !data->lib && ob->mode != OB_MODE_EDIT) && + /* check a keyblock exists */ + (BKE_keyblock_from_object(ob) != NULL); +} + static int shape_key_poll(bContext *C) { Object *ob = ED_object_context(C); @@ -359,6 +370,7 @@ void OBJECT_OT_shape_key_remove(wmOperatorType *ot) /* api callbacks */ ot->poll = shape_key_mode_poll; + ot->poll = shape_key_mode_exists_poll; ot->exec = shape_key_remove_exec; /* flags */ diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 4d7abbe7c39..fef5ae392ea 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -712,7 +712,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) else { /* get the view settings if 'around' isn't set and the view is available */ View3D *v3d = CTX_wm_view3d(C); - copy_v3_v3(cursor, give_cursor(scene, v3d)); + copy_v3_v3(cursor, ED_view3d_cursor3d_get(scene, v3d)); if (v3d && !RNA_struct_property_is_set(op->ptr, "center")) around = v3d->around; } diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index d6c365e9247..16ee400fa67 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -348,7 +348,7 @@ void ED_vgroup_parray_mirror_sync(Object *ob, return; } if (em) { - EDBM_index_arrays_ensure(em, BM_VERT); + BM_mesh_elem_table_ensure(em->bm, BM_VERT); } for (i = 0; i < dvert_tot; i++) { @@ -390,7 +390,7 @@ void ED_vgroup_parray_mirror_assign(Object *ob, } BLI_assert(dvert_tot == dvert_tot_all); if (em) { - EDBM_index_arrays_ensure(em, BM_VERT); + BM_mesh_elem_table_ensure(em->bm, BM_VERT); } for (i = 0; i < dvert_tot; i++) { @@ -1283,8 +1283,8 @@ static float get_vert_def_nr(Object *ob, const int def_nr, const int vertnum) if (cd_dvert_offset != -1) { BMVert *eve; - EDBM_index_arrays_ensure(em, BM_VERT); - eve = EDBM_vert_at_index(em, vertnum); + BM_mesh_elem_table_ensure(em->bm, BM_VERT); + eve = BM_vert_at_index(em->bm, vertnum); dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); } else { @@ -2179,7 +2179,7 @@ static void vgroup_blend_subset(Object *ob, const bool *vgroup_validmap, const i memset(vgroup_subset_weights, 0, sizeof(*vgroup_subset_weights) * subset_count); if (bm) { - EDBM_index_arrays_ensure(em, BM_VERT); + BM_mesh_elem_table_ensure(bm, BM_VERT); emap = NULL; emap_mem = NULL; @@ -2197,7 +2197,7 @@ static void vgroup_blend_subset(Object *ob, const bool *vgroup_validmap, const i /* in case its not selected */ if (bm) { - BMVert *v = EDBM_vert_at_index(em, i); + BMVert *v = BM_vert_at_index(bm, i); if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { BMIter eiter; BMEdge *e; @@ -2398,6 +2398,44 @@ static void vgroup_clean_subset(Object *ob, const bool *vgroup_validmap, const i } } +static void vgroup_quantize_subset(Object *ob, const bool *vgroup_validmap, const int vgroup_tot, const int UNUSED(subset_count), + const int steps) +{ + MDeformVert **dvert_array = NULL; + int dvert_tot = 0; + const bool use_vert_sel = vertex_group_use_vert_sel(ob); + const bool use_mirror = (ob->type == OB_MESH) ? (((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_X) != 0 : false; + ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, use_vert_sel); + + if (dvert_array) { + const float steps_fl = steps; + MDeformVert *dv; + int i; + + if (use_mirror && use_vert_sel) { + ED_vgroup_parray_mirror_assign(ob, dvert_array, dvert_tot); + } + + for (i = 0; i < dvert_tot; i++) { + MDeformWeight *dw; + int j; + + /* in case its not selected */ + if (!(dv = dvert_array[i])) { + continue; + } + + for (j = 0, dw = dv->dw; j < dv->totweight; j++, dw++) { + if ((dw->def_nr < vgroup_tot) && vgroup_validmap[dw->def_nr]) { + dw->weight = floorf((dw->weight * steps_fl) + 0.5f) / steps_fl; + CLAMP(dw->weight, 0.0f, 1.0f); + } + } + } + + MEM_freeN(dvert_array); + } +} static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr, const char sel, const char sel_mirr, @@ -3754,6 +3792,44 @@ void OBJECT_OT_vertex_group_clean(wmOperatorType *ot) "Keep verts assigned to at least one group when cleaning"); } +static int vertex_group_quantize_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_context(C); + + const int steps = RNA_int_get(op->ptr, "steps"); + eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); + + int subset_count, vgroup_tot; + + const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + vgroup_quantize_subset(ob, vgroup_validmap, vgroup_tot, subset_count, steps); + MEM_freeN((void *)vgroup_validmap); + + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_vertex_group_quantize(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Quantize Vertex Weights"; + ot->idname = "OBJECT_OT_vertex_group_quantize"; + ot->description = "Set weights to a fixed number of steps"; + + /* api callbacks */ + ot->poll = vertex_group_poll; + ot->exec = vertex_group_quantize_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + vgroup_operator_subset_select_props(ot, true); + RNA_def_int(ot->srna, "steps", 4, 1, 1000, "Steps", "Number of steps between 0 and 1", 1, 100); +} + static int vertex_group_limit_total_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); @@ -3777,7 +3853,7 @@ static int vertex_group_limit_total_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } else { - /* note, would normally return cancelled, except we want the redo + /* note, would normally return canceled, except we want the redo * UI to show up for users to change */ return OPERATOR_FINISHED; } diff --git a/source/blender/editors/object/object_warp.c b/source/blender/editors/object/object_warp.c new file mode 100644 index 00000000000..06b59a8e954 --- /dev/null +++ b/source/blender/editors/object/object_warp.c @@ -0,0 +1,325 @@ +/* + * ***** 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) 2013 by Blender Foundation + * All rights reserved. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/object/object_warp.c + * \ingroup edobj + */ + +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_view3d_types.h" + +#include "BLI_math.h" + +#include "BKE_utildefines.h" +#include "BKE_context.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_view3d.h" +#include "ED_transverts.h" + +#include "object_intern.h" + + +static void object_warp_calc_view_matrix(float r_mat_view[4][4], float r_center_view[3], + Object *obedit, float viewmat[4][4], const float center[3], + const float offset_angle) +{ + float mat_offset[4][4]; + float viewmat_roll[4][4]; + + /* apply the rotation offset by rolling the view */ + unit_m4(mat_offset); + rotate_m4(mat_offset, 'Z', offset_angle); + mul_m4_m4m4(viewmat_roll, mat_offset, viewmat); + + /* apply the view and the object matrix */ + mul_m4_m4m4(r_mat_view, viewmat_roll, obedit->obmat); + + /* get the view-space cursor */ + mul_v3_m4v3(r_center_view, viewmat_roll, center); +} + + +static void object_warp_transverts_minmax_x(TransVertStore *tvs, + float mat_view[4][4], const float center_view[3], + float *r_min, float *r_max) +{ + /* no need to apply translation and cursor offset for every vertex, delay this */ + const float x_ofs = (mat_view[3][0] - center_view[0]); + float min = FLT_MAX, max = -FLT_MAX; + + TransVert *tv; + int i; + + + tv = tvs->transverts; + for (i = 0; i < tvs->transverts_tot; i++, tv++) { + float val; + + /* convert objectspace->viewspace */ + val = dot_m4_v3_row_x(mat_view, tv->loc); + + min = min_ff(min, val); + max = max_ff(max, val); + } + + *r_min = min + x_ofs; + *r_max = max + x_ofs; +} + + +static void object_warp_transverts(TransVertStore *tvs, + float mat_view[4][4], const float center_view[3], + const float angle_, const float min, const float max) +{ + TransVert *tv; + int i; + const float angle = -angle_; + /* cache vars for tiny speedup */ +#if 1 + const float range = max - min; + const float range_inv = 1.0f / range; + const float min_ofs = min + (0.5f * range); +#endif + + float dir_min[2], dir_max[2]; + float imat_view[4][4]; + + + invert_m4_m4(imat_view, mat_view); + + /* calculate the direction vectors outside min/max range */ + { + const float phi = angle * 0.5f; + + dir_max[0] = cosf(phi); + dir_max[1] = sinf(phi); + + dir_min[0] = -dir_max[0]; + dir_min[1] = dir_max[1]; + } + + + tv = tvs->transverts; + for (i = 0; i < tvs->transverts_tot; i++, tv++) { + float co[3], co_add[2]; + float val, phi; + + /* convert objectspace->viewspace */ + mul_v3_m4v3(co, mat_view, tv->loc); + sub_v2_v2(co, center_view); + + val = co[0]; + /* is overwritten later anyway */ + // co[0] = 0.0f; + + if (val < min) { + mul_v2_v2fl(co_add, dir_min, min - val); + val = min; + } + else if (val > max) { + mul_v2_v2fl(co_add, dir_max, val - max); + val = max; + } + else { + zero_v2(co_add); + } + + /* map from x axis to (-0.5 - 0.5) */ +#if 0 + val = ((val - min) / (max - min)) - 0.5f; +#else + val = (val - min_ofs) * range_inv; +#endif + + /* convert the x axis into a rotation */ + phi = val * angle; + + co[0] = -sinf(phi) * co[1]; + co[1] = cosf(phi) * co[1]; + + add_v2_v2(co, co_add); + + /* convert viewspace->objectspace */ + add_v2_v2(co, center_view); + mul_v3_m4v3(tv->loc, imat_view, co); + } +} + +static int object_warp_verts_exec(bContext *C, wmOperator *op) +{ + const float warp_angle = RNA_float_get(op->ptr, "warp_angle"); + const float offset_angle = RNA_float_get(op->ptr, "offset_angle"); + + TransVertStore tvs = {NULL}; + Object *obedit = CTX_data_edit_object(C); + + /* typically from 'rv3d' and 3d cursor */ + float viewmat[4][4]; + float center[3]; + + /* 'viewmat' relative vars */ + float mat_view[4][4]; + float center_view[3]; + + float min, max; + + + ED_transverts_create_from_obedit(&tvs, obedit, TM_ALL_JOINTS | TM_SKIP_HANDLES); + if (tvs.transverts == 0) { + return OPERATOR_CANCELLED; + } + + + /* get viewmatrix */ + { + PropertyRNA *prop_viewmat = RNA_struct_find_property(op->ptr, "viewmat"); + if (RNA_property_is_set(op->ptr, prop_viewmat)) { + RNA_property_float_get_array(op->ptr, prop_viewmat, (float *)viewmat); + } + else { + RegionView3D *rv3d = CTX_wm_region_view3d(C); + + if (rv3d) { + copy_m4_m4(viewmat, rv3d->viewmat); + } + else { + unit_m4(viewmat); + } + + RNA_property_float_set_array(op->ptr, prop_viewmat, (float *)viewmat); + } + } + + + /* get center */ + { + PropertyRNA *prop_center = RNA_struct_find_property(op->ptr, "center"); + if (RNA_property_is_set(op->ptr, prop_center)) { + RNA_property_float_get_array(op->ptr, prop_center, center); + } + else { + Scene *scene = CTX_data_scene(C); + View3D *v3d = CTX_wm_view3d(C); + const float *cursor; + + cursor = ED_view3d_cursor3d_get(scene, v3d); + copy_v3_v3(center, cursor); + + RNA_property_float_set_array(op->ptr, prop_center, center); + } + } + + + object_warp_calc_view_matrix(mat_view, center_view, obedit, viewmat, center, offset_angle); + + + /* get minmax */ + { + PropertyRNA *prop_min = RNA_struct_find_property(op->ptr, "min"); + PropertyRNA *prop_max = RNA_struct_find_property(op->ptr, "max"); + + if (RNA_property_is_set(op->ptr, prop_min) || + RNA_property_is_set(op->ptr, prop_max)) + { + min = RNA_property_float_get(op->ptr, prop_min); + max = RNA_property_float_get(op->ptr, prop_max); + } + else { + /* handy to set the bounds of the mesh */ + object_warp_transverts_minmax_x(&tvs, mat_view, center_view, &min, &max); + + RNA_property_float_set(op->ptr, prop_min, min); + RNA_property_float_set(op->ptr, prop_max, max); + } + + if (min > max) { + SWAP(float, min, max); + } + } + + if (min != max) { + object_warp_transverts(&tvs, mat_view, center_view, warp_angle, min, max); + } + + ED_transverts_update_obedit(&tvs, obedit); + ED_transverts_free(&tvs); + + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit); + + return OPERATOR_FINISHED; +} + +static int object_warp_verts_poll(bContext *C) +{ + Object *obedit = CTX_data_edit_object(C); + if (obedit) { + if (ED_transverts_check_obedit(obedit)) { + return true; + } + } + return false; +} + + +void OBJECT_OT_vertex_warp(struct wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Warp"; + ot->description = "Warp vertices around the cursor"; + ot->idname = "OBJECT_OT_vertex_warp"; + + /* api callbacks */ + ot->exec = object_warp_verts_exec; + ot->poll = object_warp_verts_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + prop = RNA_def_float(ot->srna, "warp_angle", DEG2RADF(360.0f), -FLT_MAX, FLT_MAX, "Warp Angle", + "Amount to warp about the cursor", DEG2RADF(-360.0f), DEG2RADF(360.0f)); + RNA_def_property_subtype(prop, PROP_ANGLE); + + prop = RNA_def_float(ot->srna, "offset_angle", DEG2RADF(0.0f), -FLT_MAX, FLT_MAX, "Offset Angle", + "Angle to use as the basis for warping", DEG2RADF(-360.0f), DEG2RADF(360.0f)); + RNA_def_property_subtype(prop, PROP_ANGLE); + + prop = RNA_def_float(ot->srna, "min", -1.0f, -FLT_MAX, FLT_MAX, "Min", "", -100.0, 100.0); + prop = RNA_def_float(ot->srna, "max", 1.0f, -FLT_MAX, FLT_MAX, "Max", "", -100.0, 100.0); + + /* hidden props */ + prop = RNA_def_float_matrix(ot->srna, "viewmat", 4, 4, NULL, 0.0f, 0.0f, "Matrix", "", 0.0f, 0.0f); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + + prop = RNA_def_float_vector_xyz(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "", -FLT_MAX, FLT_MAX); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); +} diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index b0e19d04e35..65a3e5b558e 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -3880,11 +3880,9 @@ static int brush_edit_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static int brush_edit_cancel(bContext *UNUSED(C), wmOperator *op) +static void brush_edit_cancel(bContext *UNUSED(C), wmOperator *op) { brush_edit_exit(op); - - return OPERATOR_CANCELLED; } void PARTICLE_OT_brush_edit(wmOperatorType *ot) diff --git a/source/blender/editors/render/SConscript b/source/blender/editors/render/SConscript index 7406d42f416..41576f9b485 100644 --- a/source/blender/editors/render/SConscript +++ b/source/blender/editors/render/SConscript @@ -61,9 +61,6 @@ if env['WITH_BF_QUICKTIME']: incs += ' ../../quicktime' env.Append(CFLAGS=['-DWITH_QUICKTIME']) -if env['USE_QTKIT']: - env.Append(CFLAGS=['-DUSE_QTKIT']) - if env['WITH_BF_INTERNATIONAL']: defs.append('WITH_INTERNATIONAL') diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index df8d5ec4e84..71bf67220fe 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -564,15 +564,13 @@ static int screen_render_modal(bContext *C, wmOperator *op, const wmEvent *event return OPERATOR_PASS_THROUGH; } -static int screen_render_cancel(bContext *C, wmOperator *op) +static void screen_render_cancel(bContext *C, wmOperator *op) { wmWindowManager *wm = CTX_wm_manager(C); Scene *scene = (Scene *) op->customdata; /* kill on cancel, because job is using op->reports */ WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_RENDER); - - return OPERATOR_CANCELLED; } /* using context, starts job */ @@ -1239,3 +1237,13 @@ void ED_viewport_render_kill_jobs(const bContext *C, bool free_database) } } +Scene *ED_render_job_get_scene(const bContext *C) +{ + wmWindowManager *wm = CTX_wm_manager(C); + RenderJob *rj = (RenderJob *)WM_jobs_customdata_from_type(wm, WM_JOB_TYPE_RENDER); + + if (rj) + return rj->scene; + + return NULL; +} diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 21074bdc47c..107674babdd 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -485,11 +485,9 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) MEM_freeN(oglrender); } -static int screen_opengl_render_cancel(bContext *C, wmOperator *op) +static void screen_opengl_render_cancel(bContext *C, wmOperator *op) { screen_opengl_render_end(C, op->customdata); - - return OPERATOR_CANCELLED; } /* share between invoke and exec */ diff --git a/source/blender/editors/render/render_ops.c b/source/blender/editors/render/render_ops.c index 7c52b7d0d39..3401577ee55 100644 --- a/source/blender/editors/render/render_ops.c +++ b/source/blender/editors/render/render_ops.c @@ -37,10 +37,6 @@ #include "render_intern.h" // own include -#if (defined(WITH_QUICKTIME) && !defined(USE_QTKIT)) -#include "quicktime_export.h" -#endif - /***************************** render ***********************************/ void ED_operatortypes_render(void) @@ -81,10 +77,6 @@ void ED_operatortypes_render(void) WM_operatortype_append(SCENE_OT_freestyle_modifier_copy); #endif -#if (defined(WITH_QUICKTIME) && !defined(USE_QTKIT)) - WM_operatortype_append(SCENE_OT_render_data_set_quicktime_codec); -#endif - WM_operatortype_append(TEXTURE_OT_slot_copy); WM_operatortype_append(TEXTURE_OT_slot_paste); WM_operatortype_append(TEXTURE_OT_slot_move); diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 553a543390f..3ef1f0db647 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -739,6 +739,10 @@ static int freestyle_active_lineset_poll(bContext *C) Scene *scene = CTX_data_scene(C); SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay); + if (!srl) { + return FALSE; + } + return BKE_freestyle_lineset_get_active(&srl->freestyleConfig) != NULL; } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index fbdd90312dd..93923c24c84 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -750,11 +750,9 @@ static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static int actionzone_cancel(bContext *UNUSED(C), wmOperator *op) +static void actionzone_cancel(bContext *UNUSED(C), wmOperator *op) { actionzone_exit(op); - - return OPERATOR_CANCELLED; } static void SCREEN_OT_actionzone(wmOperatorType *ot) @@ -825,10 +823,9 @@ static void area_swap_exit(bContext *C, wmOperator *op) op->customdata = NULL; } -static int area_swap_cancel(bContext *C, wmOperator *op) +static void area_swap_cancel(bContext *C, wmOperator *op) { area_swap_exit(C, op); - return OPERATOR_CANCELLED; } static int area_swap_invoke(bContext *C, wmOperator *op, const wmEvent *event) @@ -857,8 +854,8 @@ static int area_swap_modal(bContext *C, wmOperator *op, const wmEvent *event) case LEFTMOUSE: /* release LMB */ if (event->val == KM_RELEASE) { if (!sad->sa2 || sad->sa1 == sad->sa2) { - - return area_swap_cancel(C, op); + area_swap_cancel(C, op); + return OPERATOR_CANCELLED; } ED_area_tag_redraw(sad->sa1); @@ -875,7 +872,8 @@ static int area_swap_modal(bContext *C, wmOperator *op, const wmEvent *event) break; case ESCKEY: - return area_swap_cancel(C, op); + area_swap_cancel(C, op); + return OPERATOR_CANCELLED; } return OPERATOR_RUNNING_MODAL; } @@ -917,14 +915,7 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event) sa = sad->sa1; } - - /* poll() checks area context, but we don't accept full-area windows */ - if (sc->full != SCREENNORMAL) { - if (event->type == EVT_ACTIONZONE_AREA) - actionzone_exit(op); - return OPERATOR_CANCELLED; - } - + /* adds window to WM */ rect = sa->totrct; BLI_rcti_translate(&rect, win->posx, win->posy); @@ -1148,14 +1139,12 @@ static int area_move_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static int area_move_cancel(bContext *C, wmOperator *op) +static void area_move_cancel(bContext *C, wmOperator *op) { RNA_int_set(op->ptr, "delta", 0); area_move_apply(C, op); area_move_exit(C, op); - - return OPERATOR_CANCELLED; } /* modal callback for while moving edges */ @@ -1186,7 +1175,8 @@ static int area_move_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_FINISHED; case KM_MODAL_CANCEL: - return area_move_cancel(C, op); + area_move_cancel(C, op); + return OPERATOR_CANCELLED; case KM_MODAL_STEP10: md->step = 10; @@ -1530,7 +1520,7 @@ static int area_split_exec(bContext *C, wmOperator *op) } -static int area_split_cancel(bContext *C, wmOperator *op) +static void area_split_cancel(bContext *C, wmOperator *op) { sAreaSplitData *sd = (sAreaSplitData *)op->customdata; @@ -1546,8 +1536,6 @@ static int area_split_cancel(bContext *C, wmOperator *op) } } area_split_exit(C, op); - - return OPERATOR_CANCELLED; } static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event) @@ -1640,7 +1628,8 @@ static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event) case RIGHTMOUSE: /* cancel operation */ case ESCKEY: - return area_split_cancel(C, op); + area_split_cancel(C, op); + return OPERATOR_CANCELLED; } return OPERATOR_RUNNING_MODAL; @@ -1915,12 +1904,10 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static int region_scale_cancel(bContext *UNUSED(C), wmOperator *op) +static void region_scale_cancel(bContext *UNUSED(C), wmOperator *op) { MEM_freeN(op->customdata); op->customdata = NULL; - - return OPERATOR_CANCELLED; } static void SCREEN_OT_region_scale(wmOperatorType *ot) @@ -2123,6 +2110,66 @@ static void SCREEN_OT_keyframe_jump(wmOperatorType *ot) RNA_def_boolean(ot->srna, "next", TRUE, "Next Keyframe", ""); } +/* ************** jump to marker operator ***************************** */ + +/* function to be called outside UI context, or for redo */ +static int marker_jump_exec(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + TimeMarker *marker; + int closest; + short next = RNA_boolean_get(op->ptr, "next"); + bool found = false; + + /* find matching marker in the right direction */ + for (marker = scene->markers.first; marker; marker = marker->next) { + if (next) { + if (marker->frame > CFRA && (!found || closest > marker->frame)) { + closest = marker->frame; + found = true; + } + } + else { + if (marker->frame < CFRA && (!found || closest < marker->frame)) { + closest = marker->frame; + found = true; + } + } + } + + /* any success? */ + if (!found) { + BKE_report(op->reports, RPT_INFO, "No more markers to jump to in this direction"); + + return OPERATOR_CANCELLED; + } + else { + CFRA = closest; + + sound_seek_scene(bmain, scene); + + WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); + + return OPERATOR_FINISHED; + } +} + +static void SCREEN_OT_marker_jump(wmOperatorType *ot) +{ + ot->name = "Jump to Marker"; + ot->description = "Jump to previous/next marker"; + ot->idname = "SCREEN_OT_marker_jump"; + + ot->exec = marker_jump_exec; + + ot->poll = ED_operator_screenactive_norender; + ot->flag = OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "next", TRUE, "Next Marker", ""); +} + /* ************** switch screen operator ***************************** */ static int screen_set_is_ok(bScreen *screen, bScreen *screen_prev) @@ -2389,7 +2436,7 @@ static int area_join_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static int area_join_cancel(bContext *C, wmOperator *op) +static void area_join_cancel(bContext *C, wmOperator *op) { sAreaJoinData *jd = (sAreaJoinData *)op->customdata; @@ -2405,8 +2452,6 @@ static int area_join_cancel(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_WINDOW, NULL); area_join_exit(C, op); - - return OPERATOR_CANCELLED; } /* modal callback while selecting area (space) that will be removed */ @@ -2494,7 +2539,8 @@ static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event) case RIGHTMOUSE: case ESCKEY: - return area_join_cancel(C, op); + area_join_cancel(C, op); + return OPERATOR_CANCELLED; } return OPERATOR_RUNNING_MODAL; @@ -3807,6 +3853,7 @@ void ED_operatortypes_screen(void) WM_operatortype_append(SCREEN_OT_frame_offset); WM_operatortype_append(SCREEN_OT_frame_jump); WM_operatortype_append(SCREEN_OT_keyframe_jump); + WM_operatortype_append(SCREEN_OT_marker_jump); WM_operatortype_append(SCREEN_OT_animation_step); WM_operatortype_append(SCREEN_OT_animation_play); @@ -3984,6 +4031,13 @@ void ED_keymap_screen(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", MEDIAFIRST, KM_PRESS, 0, 0); RNA_boolean_set(kmi->ptr, "next", FALSE); + + kmi = WM_keymap_add_item(keymap, "SCREEN_OT_marker_jump", RIGHTARROWKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "next", TRUE); + + kmi = WM_keymap_add_item(keymap, "SCREEN_OT_marker_jump", LEFTARROWKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "next", FALSE); + /* play (forward and backwards) */ WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT, 0); diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c index dbe1197436b..0153d609adb 100644 --- a/source/blender/editors/screen/screendump.c +++ b/source/blender/editors/screen/screendump.c @@ -105,7 +105,7 @@ static unsigned int *screenshot(bContext *C, int *dumpsx, int *dumpsy) dumprect = MEM_mallocN(sizeof(int) * (*dumpsx) * (*dumpsy), "dumprect"); glReadBuffer(GL_FRONT); - screenshot_read_pixels(x, y, *dumpsx, *dumpsy, (unsigned char*)dumprect); + screenshot_read_pixels(x, y, *dumpsx, *dumpsy, (unsigned char *)dumprect); glReadBuffer(GL_BACK); } @@ -237,10 +237,9 @@ static bool screenshot_check(bContext *UNUSED(C), wmOperator *op) return WM_operator_filesel_ensure_ext_imtype(op, &scd->im_format); } -static int screenshot_cancel(bContext *UNUSED(C), wmOperator *op) +static void screenshot_cancel(bContext *UNUSED(C), wmOperator *op) { screenshot_data_free(op); - return OPERATOR_CANCELLED; } static bool screenshot_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop) diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index a5d4ff98b4b..003db8a9c43 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -898,10 +898,9 @@ static int grab_clone_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static int grab_clone_cancel(bContext *UNUSED(C), wmOperator *op) +static void grab_clone_cancel(bContext *UNUSED(C), wmOperator *op) { MEM_freeN(op->customdata); - return OPERATOR_CANCELLED; } void PAINT_OT_grab_clone(wmOperatorType *ot) @@ -936,11 +935,23 @@ static int sample_color_exec(bContext *C, wmOperator *op) Paint *paint = BKE_paint_get_active_from_context(C); Brush *brush = BKE_paint_brush(paint); ARegion *ar = CTX_wm_region(C); + wmWindow *win = CTX_wm_window(C); + bool show_cursor = ((paint->flags & PAINT_SHOW_BRUSH) != 0); int location[2]; + paint->flags &= ~PAINT_SHOW_BRUSH; + + /* force redraw without cursor */ + WM_paint_cursor_tag_redraw(win, ar); + WM_redraw_windows(C); + RNA_int_get_array(op->ptr, "location", location); paint_sample_color(C, ar, location[0], location[1]); + if (show_cursor) { + paint->flags |= PAINT_SHOW_BRUSH; + } + WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush); return OPERATOR_FINISHED; @@ -950,14 +961,20 @@ static int sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *event { Paint *paint = BKE_paint_get_active_from_context(C); SampleColorData *data = MEM_mallocN(sizeof(SampleColorData), "sample color custom data"); + ARegion *ar = CTX_wm_region(C); + wmWindow *win = CTX_wm_window(C); data->event_type = event->type; data->show_cursor = ((paint->flags & PAINT_SHOW_BRUSH) != 0); op->customdata = data; paint->flags &= ~PAINT_SHOW_BRUSH; + /* force redraw without cursor */ + WM_paint_cursor_tag_redraw(win, ar); + WM_redraw_windows(C); + RNA_int_set_array(op->ptr, "location", event->mval); - sample_color_exec(C, op); + paint_sample_color(C, ar, event->mval[0], event->mval[1]); WM_event_add_modal_handler(C, op); @@ -967,11 +984,11 @@ static int sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *event static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event) { SampleColorData *data = op->customdata; + Paint *paint = BKE_paint_get_active_from_context(C); + Brush *brush = BKE_paint_brush(paint); if ((event->type == data->event_type) && (event->val == KM_RELEASE)) { - Paint *paint = BKE_paint_get_active_from_context(C); - - if(data->show_cursor) { + if (data->show_cursor) { paint->flags |= PAINT_SHOW_BRUSH; } @@ -981,9 +998,13 @@ static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event) switch (event->type) { case MOUSEMOVE: + { + ARegion *ar = CTX_wm_region(C); RNA_int_set_array(op->ptr, "location", event->mval); - sample_color_exec(C, op); + paint_sample_color(C, ar, event->mval[0], event->mval[1]); + WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush); break; + } } return OPERATOR_RUNNING_MODAL; diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 4a2046f6682..88cc954fb17 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -164,6 +164,7 @@ BLI_INLINE unsigned char f_to_char(const float val) /* used for testing doubles, if a point is on a line etc */ #define PROJ_GEOM_TOLERANCE 0.00075f +#define PROJ_PIXEL_TOLERANCE 0.01f /* vert flags */ #define PROJ_VERT_CULL 1 @@ -514,8 +515,8 @@ static void uvco_to_wrapped_pxco(const float uv[2], int ibuf_x, int ibuf_y, floa } /* Set the top-most face color that the screen space coord 'pt' touches (or return 0 if none touch) */ -static int project_paint_PickColor(const ProjPaintState *ps, const float pt[2], - float *rgba_fp, unsigned char *rgba, const int interp) +static bool project_paint_PickColor(const ProjPaintState *ps, const float pt[2], + float *rgba_fp, unsigned char *rgba, const bool interp) { float w[3], uv[2]; int side; @@ -575,11 +576,8 @@ static int project_paint_PickColor(const ProjPaintState *ps, const float pt[2], //if (xi < 0 || xi >= ibuf->x || yi < 0 || yi >= ibuf->y) return 0; /* wrap */ - xi = ((int)(uv[0] * ibuf->x)) % ibuf->x; - if (xi < 0) xi += ibuf->x; - yi = ((int)(uv[1] * ibuf->y)) % ibuf->y; - if (yi < 0) yi += ibuf->y; - + xi = mod_i((int)(uv[0] * ibuf->x), ibuf->x); + yi = mod_i((int)(uv[1] * ibuf->y), ibuf->y); if (rgba) { if (ibuf->rect_float) { @@ -611,7 +609,9 @@ static int project_paint_PickColor(const ProjPaintState *ps, const float pt[2], * 1 : occluded * 2 : occluded with w[3] weights set (need to know in some cases) */ -static int project_paint_occlude_ptv(float pt[3], float v1[4], float v2[4], float v3[4], float w[3], int is_ortho) +static int project_paint_occlude_ptv(const float pt[3], + const float v1[4], const float v2[4], const float v3[4], + float w[3], const bool is_ortho) { /* if all are behind us, return false */ if (v1[2] > pt[2] && v2[2] > pt[2] && v3[2] > pt[2]) @@ -642,7 +642,7 @@ static int project_paint_occlude_ptv(float pt[3], float v1[4], float v2[4], floa static int project_paint_occlude_ptv_clip(const ProjPaintState *ps, const MFace *mf, - float pt[3], float v1[4], float v2[4], float v3[4], + const float pt[3], const float v1[4], const float v2[4], const float v3[4], const int side) { float w[3], wco[3]; @@ -671,7 +671,8 @@ static int project_paint_occlude_ptv_clip(const ProjPaintState *ps, const MFace /* Check if a screenspace location is occluded by any other faces * check, pixelScreenCo must be in screenspace, its Z-Depth only needs to be used for comparison * and doesn't need to be correct in relation to X and Y coords (this is the case in perspective view) */ -static int project_bucket_point_occluded(const ProjPaintState *ps, LinkNode *bucketFace, const int orig_face, float pixelScreenCo[4]) +static bool project_bucket_point_occluded(const ProjPaintState *ps, LinkNode *bucketFace, + const int orig_face, const float pixelScreenCo[4]) { MFace *mf; int face_index; @@ -702,11 +703,11 @@ static int project_bucket_point_occluded(const ProjPaintState *ps, LinkNode *buc if (isect_ret >= 1) { /* TODO - we may want to cache the first hit, * it is not possible to swap the face order in the list anymore */ - return 1; + return true; } } } - return 0; + return false; } /* basic line intersection, could move to math_geom.c, 2 points with a horiz line @@ -785,7 +786,7 @@ static int line_isect_x(const float p1[2], const float p2[2], const float x_leve * tile, but do not do this for the adjacent face, it could return a false positive. * This is so unlikely that Id not worry about it. */ #ifndef PROJ_DEBUG_NOSEAMBLEED -static int cmp_uv(const float vec2a[2], const float vec2b[2]) +static bool cmp_uv(const float vec2a[2], const float vec2b[2]) { /* if the UV's are not between 0.0 and 1.0 */ float xa = (float)fmodf(vec2a[0], 1.0f); @@ -807,11 +808,11 @@ static int cmp_uv(const float vec2a[2], const float vec2b[2]) /* set min_px and max_px to the image space bounds of the UV coords * return zero if there is no area in the returned rectangle */ #ifndef PROJ_DEBUG_NOSEAMBLEED -static int pixel_bounds_uv( +static bool pixel_bounds_uv( const float uv1[2], const float uv2[2], const float uv3[2], const float uv4[2], rcti *bounds_px, const int ibuf_x, const int ibuf_y, - int is_quad + const bool is_quad ) { float min_uv[2], max_uv[2]; /* UV bounds */ @@ -837,7 +838,7 @@ static int pixel_bounds_uv( } #endif -static int pixel_bounds_array(float (*uv)[2], rcti *bounds_px, const int ibuf_x, const int ibuf_y, int tot) +static bool pixel_bounds_array(float (*uv)[2], rcti *bounds_px, const int ibuf_x, const int ibuf_y, int tot) { float min_uv[2], max_uv[2]; /* UV bounds */ @@ -868,7 +869,9 @@ static int pixel_bounds_array(float (*uv)[2], rcti *bounds_px, const int ibuf_x, /* This function returns 1 if this face has a seam along the 2 face-vert indices * 'orig_i1_fidx' and 'orig_i2_fidx' */ -static int check_seam(const ProjPaintState *ps, const int orig_face, const int orig_i1_fidx, const int orig_i2_fidx, int *other_face, int *orig_fidx) +static bool check_seam(const ProjPaintState *ps, + const int orig_face, const int orig_i1_fidx, const int orig_i2_fidx, + int *other_face, int *orig_fidx) { LinkNode *node; int face_index; @@ -941,7 +944,7 @@ static int check_seam(const ProjPaintState *ps, const int orig_face, const int o * since the outset coords are a margin that keep an even distance from the original UV's, * note that the image aspect is taken into account */ static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const float scaler, - const int ibuf_x, const int ibuf_y, const int is_quad) + const int ibuf_x, const int ibuf_y, const bool is_quad) { float a1, a2, a3, a4 = 0.0f; float puv[4][2]; /* pixelspace uv's */ @@ -1339,7 +1342,7 @@ static ProjPixel *project_paint_uvpixel_init( const ProjPaintState *ps, MemArena *arena, const ImBuf *ibuf, - short x_px, short y_px, + int x_px, int y_px, const float mask, const int face_index, const int image_index, @@ -1351,10 +1354,9 @@ static ProjPixel *project_paint_uvpixel_init( ProjPixel *projPixel; /* wrap pixel location */ - x_px = x_px % ibuf->x; - if (x_px < 0) x_px += ibuf->x; - y_px = y_px % ibuf->y; - if (y_px < 0) y_px += ibuf->y; + + x_px = mod_i(x_px, ibuf->x); + y_px = mod_i(y_px, ibuf->y); BLI_assert(ps->pixel_sizeof == project_paint_pixel_sizeof(ps->tool)); projPixel = (ProjPixel *)BLI_memarena_alloc(arena, ps->pixel_sizeof); @@ -1465,7 +1467,7 @@ static ProjPixel *project_paint_uvpixel_init( return projPixel; } -static int line_clip_rect2f( +static bool line_clip_rect2f( rctf *rect, const float l1[2], const float l2[2], float l1_clip[2], float l2_clip[2]) @@ -1681,7 +1683,7 @@ static float len_squared_v2v2_alt(const float *v1, const float v2_1, const float /* note, use a squared value so we can use len_squared_v2v2 * be sure that you have done a bounds check first or this may fail */ /* only give bucket_bounds as an arg because we need it elsewhere */ -static int project_bucket_isect_circle(const float cent[2], const float radius_squared, rctf *bucket_bounds) +static bool project_bucket_isect_circle(const float cent[2], const float radius_squared, rctf *bucket_bounds) { /* Would normally to a simple intersection test, however we know the bounds of these 2 already intersect @@ -1823,9 +1825,11 @@ static float angle_2d_clockwise(const float p1[2], const float p2[2], const floa #define ISECT_ALL4 ((1 << 4) - 1) /* limit must be a fraction over 1.0f */ -static int IsectPT2Df_limit(float pt[2], float v1[2], float v2[2], float v3[2], float limit) +static bool IsectPT2Df_limit(float pt[2], float v1[2], float v2[2], float v3[2], float limit) { - return ((area_tri_v2(pt, v1, v2) + area_tri_v2(pt, v2, v3) + area_tri_v2(pt, v3, v1)) / (area_tri_v2(v1, v2, v3))) < limit; + return ((area_tri_v2(pt, v1, v2) + + area_tri_v2(pt, v2, v3) + + area_tri_v2(pt, v3, v1)) / (area_tri_v2(v1, v2, v3))) < limit; } /* Clip the face by a bucket and set the uv-space bucket_bounds_uv @@ -2004,8 +2008,8 @@ static void project_bucket_clip_face( /* remove doubles */ /* first/last check */ - if (fabsf(isectVCosSS[0][0] - isectVCosSS[(*tot) - 1][0]) < PROJ_GEOM_TOLERANCE && - fabsf(isectVCosSS[0][1] - isectVCosSS[(*tot) - 1][1]) < PROJ_GEOM_TOLERANCE) + if (fabsf(isectVCosSS[0][0] - isectVCosSS[(*tot) - 1][0]) < PROJ_PIXEL_TOLERANCE && + fabsf(isectVCosSS[0][1] - isectVCosSS[(*tot) - 1][1]) < PROJ_PIXEL_TOLERANCE) { (*tot)--; } @@ -2021,8 +2025,8 @@ static void project_bucket_clip_face( while (doubles == TRUE) { doubles = FALSE; for (i = 1; i < (*tot); i++) { - if (fabsf(isectVCosSS[i - 1][0] - isectVCosSS[i][0]) < PROJ_GEOM_TOLERANCE && - fabsf(isectVCosSS[i - 1][1] - isectVCosSS[i][1]) < PROJ_GEOM_TOLERANCE) + if (fabsf(isectVCosSS[i - 1][0] - isectVCosSS[i][0]) < PROJ_PIXEL_TOLERANCE && + fabsf(isectVCosSS[i - 1][1] - isectVCosSS[i][1]) < PROJ_PIXEL_TOLERANCE) { int j; for (j = i + 1; j < (*tot); j++) { @@ -2136,7 +2140,7 @@ static void project_bucket_clip_face( /* checks if pt is inside a convex 2D polyline, the polyline must be ordered rotating clockwise * otherwise it would have to test for mixed (line_point_side_v2 > 0.0f) cases */ -static int IsectPoly2Df(const float pt[2], float uv[][2], const int tot) +static bool IsectPoly2Df(const float pt[2], float uv[][2], const int tot) { int i; if (line_point_side_v2(uv[tot - 1], uv[0], pt) < 0.0f) @@ -2150,7 +2154,7 @@ static int IsectPoly2Df(const float pt[2], float uv[][2], const int tot) return 1; } -static int IsectPoly2Df_twoside(const float pt[2], float uv[][2], const int tot) +static bool IsectPoly2Df_twoside(const float pt[2], float uv[][2], const int tot) { int i; int side = (line_point_side_v2(uv[tot - 1], uv[0], pt) > 0.0f); @@ -2410,7 +2414,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i if (outset_uv[0][0] == FLT_MAX) /* first time initialize */ - uv_image_outset(tf_uv_pxoffset, outset_uv, ps->seam_bleed_px, ibuf->x, ibuf->y, mf->v4); + uv_image_outset(tf_uv_pxoffset, outset_uv, ps->seam_bleed_px, ibuf->x, ibuf->y, mf->v4 != 0); /* ps->faceSeamUVs cant be modified when threading, now this is done we can unlock */ if (ps->thread_tot > 1) @@ -2465,7 +2469,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i interp_v3_v3v3(edge_verts_inset_clip[1], insetCos[fidx1], insetCos[fidx2], fac2); - if (pixel_bounds_uv(seam_subsection[0], seam_subsection[1], seam_subsection[2], seam_subsection[3], &bounds_px, ibuf->x, ibuf->y, 1)) { + if (pixel_bounds_uv(seam_subsection[0], seam_subsection[1], seam_subsection[2], seam_subsection[3], &bounds_px, ibuf->x, ibuf->y, true)) { /* bounds between the seam rect and the uvspace bucket pixels */ has_isect = 0; @@ -2671,7 +2675,7 @@ static void project_bucket_init(const ProjPaintState *ps, const int thread_index * calculated when it might not be needed later, (at the moment at least) * obviously it shouldn't have bugs though */ -static int project_bucket_face_isect(ProjPaintState *ps, int bucket_x, int bucket_y, const MFace *mf) +static bool project_bucket_face_isect(ProjPaintState *ps, int bucket_x, int bucket_y, const MFace *mf) { /* TODO - replace this with a tricker method that uses sideofline for all screenCoords's edges against the closest bucket corner */ rctf bucket_bounds; @@ -3303,7 +3307,7 @@ static void paint_proj_begin_clone(ProjPaintState *ps, const float mouse[2]) /* setup clone offset */ if (ps->tool == PAINT_TOOL_CLONE) { float projCo[4]; - copy_v3_v3(projCo, give_cursor(ps->scene, ps->v3d)); + copy_v3_v3(projCo, ED_view3d_cursor3d_get(ps->scene, ps->v3d)); mul_m4_v3(ps->ob->imat, projCo); projCo[3] = 1.0f; @@ -3465,9 +3469,9 @@ static void partial_redraw_array_init(ImagePaintPartialRedraw *pr) } -static int partial_redraw_array_merge(ImagePaintPartialRedraw *pr, ImagePaintPartialRedraw *pr_other, int tot) +static bool partial_redraw_array_merge(ImagePaintPartialRedraw *pr, ImagePaintPartialRedraw *pr_other, int tot) { - int touch = 0; + bool touch = 0; while (tot--) { pr->x1 = min_ii(pr->x1, pr_other->x1); pr->y1 = min_ii(pr->y1, pr_other->y1); @@ -3485,12 +3489,12 @@ static int partial_redraw_array_merge(ImagePaintPartialRedraw *pr, ImagePaintPar } /* Loop over all images on this mesh and update any we have touched */ -static int project_image_refresh_tagged(ProjPaintState *ps) +static bool project_image_refresh_tagged(ProjPaintState *ps) { ImagePaintPartialRedraw *pr; ProjPaintImage *projIma; int a, i; - int redraw = 0; + bool redraw = false; for (a = 0, projIma = ps->projImages; a < ps->image_tot; a++, projIma++) { @@ -3513,7 +3517,7 @@ static int project_image_refresh_tagged(ProjPaintState *ps) } /* run this per painting onto each mouse location */ -static int project_bucket_iter_init(ProjPaintState *ps, const float mval_f[2]) +static bool project_bucket_iter_init(ProjPaintState *ps, const float mval_f[2]) { if (ps->source == PROJ_SRC_VIEW) { float min_brush[2], max_brush[2]; @@ -3553,7 +3557,7 @@ static int project_bucket_iter_init(ProjPaintState *ps, const float mval_f[2]) } -static int project_bucket_iter_next(ProjPaintState *ps, int *bucket_index, rctf *bucket_bounds, const float mval[2]) +static bool project_bucket_iter_next(ProjPaintState *ps, int *bucket_index, rctf *bucket_bounds, const float mval[2]) { const int diameter = 2 * BKE_brush_size_get(ps->scene, ps->brush); @@ -3815,7 +3819,7 @@ static void *do_projectpaint_thread(void *ph_v) float falloff; int bucket_index; - int is_floatbuf = 0; + bool is_floatbuf = false; const short tool = ps->tool; rctf bucket_bounds; @@ -3870,7 +3874,7 @@ static void *do_projectpaint_thread(void *ph_v) last_projIma = projImages + last_index; last_projIma->touch = 1; - is_floatbuf = last_projIma->ibuf->rect_float ? 1 : 0; + is_floatbuf = (last_projIma->ibuf->rect_float != NULL); } /* end copy */ @@ -3996,7 +4000,7 @@ static void *do_projectpaint_thread(void *ph_v) last_projIma = projImages + last_index; last_projIma->touch = 1; - is_floatbuf = last_projIma->ibuf->rect_float ? 1 : 0; + is_floatbuf = (last_projIma->ibuf->rect_float != NULL); } /* end copy */ @@ -4075,11 +4079,11 @@ static void *do_projectpaint_thread(void *ph_v) return NULL; } -static int project_paint_op(void *state, const float lastpos[2], const float pos[2]) +static bool project_paint_op(void *state, const float lastpos[2], const float pos[2]) { /* First unpack args from the struct */ ProjPaintState *ps = (ProjPaintState *)state; - int touch_any = 0; + bool touch_any = false; ProjectHandle handles[BLENDER_MAX_THREADS]; ListBase threads; @@ -4159,7 +4163,7 @@ void paint_proj_stroke(bContext *C, void *pps, const float prev_pos[2], const fl if (ps->tool == PAINT_TOOL_CLONE && ps->mode == BRUSH_STROKE_INVERT) { Scene *scene = ps->scene; View3D *v3d = ps->v3d; - float *cursor = give_cursor(scene, v3d); + float *cursor = ED_view3d_cursor3d_get(scene, v3d); int mval_i[2] = {(int)pos[0], (int)pos[1]}; view3d_operator_needs_opengl(C); diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 2545328ec65..5fff02f016b 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -80,7 +80,7 @@ bool paint_supports_jitter(enum PaintMode mode); struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf); int paint_stroke_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event); int paint_stroke_exec(struct bContext *C, struct wmOperator *op); -int paint_stroke_cancel(struct bContext *C, struct wmOperator *op); +void paint_stroke_cancel(struct bContext *C, struct wmOperator *op); struct ViewContext *paint_stroke_view_context(struct PaintStroke *stroke); void *paint_stroke_mode_data(struct PaintStroke *stroke); void paint_stroke_set_mode_data(struct PaintStroke *stroke, void *mode_data); @@ -264,5 +264,7 @@ typedef enum { } PaintMaskFloodMode; void PAINT_OT_mask_flood_fill(struct wmOperatorType *ot); +void PAINT_OT_mask_box_fill(struct wmOperatorType *ot); +void PAINT_OT_mask_lasso_gesture(struct wmOperatorType *ot); #endif /* __PAINT_INTERN_H__ */ diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 8767b080355..9b906c460e3 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -36,7 +36,13 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" +#include "BIF_glutil.h" + +#include "BLI_math_matrix.h" +#include "BLI_math_geom.h" #include "BLI_utildefines.h" +#include "BLI_lasso.h" + #include "BKE_pbvh.h" #include "BKE_ccg.h" #include "BKE_context.h" @@ -53,6 +59,7 @@ #include "ED_screen.h" #include "ED_sculpt.h" +#include "ED_view3d.h" #include "bmesh.h" @@ -110,7 +117,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) mask_flood_fill_set_elem(vi.mask, mode, value); } BKE_pbvh_vertex_iter_end; - BKE_pbvh_node_mark_update(nodes[i]); + BKE_pbvh_node_mark_redraw(nodes[i]); if (BKE_pbvh_type(pbvh) == PBVH_GRIDS) multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED); } @@ -148,3 +155,264 @@ void PAINT_OT_mask_flood_fill(struct wmOperatorType *ot) RNA_def_float(ot->srna, "value", 0, 0, 1, "Value", "Mask level to use when mode is 'Value'; zero means no masking and one is fully masked", 0, 1); } + +/* Box select, operator is VIEW3D_OT_select_border, defined in view3d_select.c */ + +static int is_effected(float planes[4][4], const float co[3]) +{ + return isect_point_planes_v3(planes, 4, co); +} + +static void flip_plane(float out[4], const float in[4], const char symm) +{ + if (symm & SCULPT_SYMM_X) + out[0] = -in[0]; + else + out[0] = in[0]; + if (symm & SCULPT_SYMM_Y) + out[1] = -in[1]; + else + out[1] = in[1]; + if (symm & SCULPT_SYMM_Z) + out[2] = -in[2]; + else + out[2] = in[2]; + + out[3] = in[3]; +} + +int do_sculpt_mask_box_select(ViewContext *vc, rcti *rect, bool select, bool UNUSED(extend)) +{ + Sculpt *sd = vc->scene->toolsettings->sculpt; + BoundBox bb; + bglMats mats = {{0}}; + float clip_planes[4][4]; + float clip_planes_final[4][4]; + ARegion *ar = vc->ar; + struct Scene *scene = vc->scene; + Object *ob = vc->obact; + struct MultiresModifierData *mmd = sculpt_multires_active(scene, ob); + PaintMaskFloodMode mode; + float value; + DerivedMesh *dm; + PBVH *pbvh; + PBVHNode **nodes; + int totnode, i, symmpass; + int symm = sd->flags & 7; + + mode = PAINT_MASK_FLOOD_VALUE; + value = select ? 1.0 : 0.0; + + /* transform the clip planes in object space */ + view3d_get_transformation(vc->ar, vc->rv3d, vc->obact, &mats); + ED_view3d_clipping_calc(&bb, clip_planes, &mats, rect); + mul_m4_fl(clip_planes, -1.0f); + + ED_sculpt_mask_layers_ensure(ob, mmd); + + dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + pbvh = dm->getPBVH(ob, dm); + ob->sculpt->pbvh = pbvh; + + sculpt_undo_push_begin("Mask box fill"); + + for (symmpass = 0; symmpass <= symm; ++symmpass) { + if (symmpass == 0 || + (symm & symmpass && + (symm != 5 || symmpass != 3) && + (symm != 6 || (symmpass != 3 && symmpass != 5)))) + { + int j = 0; + + /* flip the planes symmetrically as needed */ + for (; j < 4; j++) { + flip_plane(clip_planes_final[j], clip_planes[j], symmpass); + } + + BKE_pbvh_search_gather(pbvh, BKE_pbvh_node_planes_contain_AABB, clip_planes_final, &nodes, &totnode); + +#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) + for (i = 0; i < totnode; i++) { + PBVHVertexIter vi; + bool any_masked = false; + + BKE_pbvh_vertex_iter_begin(pbvh, nodes[i], vi, PBVH_ITER_UNIQUE) { + if (is_effected(clip_planes_final, vi.co)) { + if (!any_masked) { + any_masked = true; + + sculpt_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK); + + BKE_pbvh_node_mark_redraw(nodes[i]); + if (BKE_pbvh_type(pbvh) == PBVH_GRIDS) + multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED); + } + mask_flood_fill_set_elem(vi.mask, mode, value); + } + } BKE_pbvh_vertex_iter_end; + } + + if (nodes) + MEM_freeN(nodes); + } + } + + sculpt_undo_push_end(); + + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + +typedef struct LassoMaskData { + struct ViewContext *vc; + float projviewobjmat[4][4]; + bool *px; + int width; + rcti rect; /* bounding box for scanfilling */ +} LassoMaskData; + + +/* Lasso select. This could be defined as part of VIEW3D_OT_select_lasso, still the shortcuts conflict, + * so we will use a separate operator */ + +static bool is_effected_lasso(LassoMaskData *data, float co[3]) +{ + float scr_co_f[2]; + short scr_co_s[2]; + + /* first project point to 2d space */ + ED_view3d_project_float_v2_m4(data->vc->ar, co, scr_co_f, data->projviewobjmat); + + scr_co_s[0] = scr_co_f[0]; + scr_co_s[1] = scr_co_f[1]; + + /* clip against screen, because lasso is limited to screen only */ + if (scr_co_s[0] < data->rect.xmin || scr_co_s[1] < data->rect.ymin || scr_co_s[0] >= data->rect.xmax || scr_co_s[1] >= data->rect.ymax) + return false; + + scr_co_s[0] -= data->rect.xmin; + scr_co_s[1] -= data->rect.ymin; + + return data->px[scr_co_s[1] * data->width + scr_co_s[0]]; +} + +static void mask_lasso_px_cb(int x, int y, void *user_data) +{ + struct LassoMaskData *data = user_data; + data->px[(y * data->width) + x] = true; +} + +static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op) +{ + int mcords_tot; + int (*mcords)[2] = (int (*)[2])WM_gesture_lasso_path_to_array(C, op, &mcords_tot); + + if (mcords) { + float clip_planes[4][4]; + BoundBox bb; + bglMats mats = {{0}}; + Object *ob; + ViewContext vc; + LassoMaskData data; +#ifdef _OPENMP + Sculpt *sd = CTX_data_tool_settings(C)->sculpt; +#endif + struct MultiresModifierData *mmd; + DerivedMesh *dm; + PBVH *pbvh; + PBVHNode **nodes; + int totnode, i; + PaintMaskFloodMode mode = PAINT_MASK_FLOOD_VALUE; + bool select = true; /* TODO: see how to implement deselection */ + float value = select ? 1.0 : 0.0; + + /* Calculations of individual vertices are done in 2D screen space to diminish the amount of + * calculations done. Bounding box PBVH collision is not computed against enclosing rectangle + * of lasso */ + view3d_set_viewcontext(C, &vc); + view3d_get_transformation(vc.ar, vc.rv3d, vc.obact, &mats); + + /* lasso data calculations */ + data.vc = &vc; + ob = vc.obact; + ED_view3d_ob_project_mat_get(vc.rv3d, ob, data.projviewobjmat); + + BLI_lasso_boundbox(&data.rect, (const int (*)[2])mcords, mcords_tot); + data.width = data.rect.xmax - data.rect.xmin; + data.px = MEM_callocN(sizeof(*data.px) * data.width * (data.rect.ymax - data.rect.ymin), "lasso_mask_pixel_buffer"); + + fill_poly_v2i_n( + data.rect.xmin, data.rect.ymin, data.rect.xmax, data.rect.ymax, + (const int (*)[2])mcords, mcords_tot, + mask_lasso_px_cb, &data); + + ED_view3d_clipping_calc(&bb, clip_planes, &mats, &data.rect); + mul_m4_fl(clip_planes, -1.0f); + + mmd = sculpt_multires_active(vc.scene, ob); + ED_sculpt_mask_layers_ensure(ob, mmd); + dm = mesh_get_derived_final(vc.scene, ob, CD_MASK_BAREMESH); + pbvh = dm->getPBVH(ob, dm); + ob->sculpt->pbvh = pbvh; + + /* gather nodes inside lasso's enclosing rectangle (should greatly help with bigger meshes) */ + BKE_pbvh_search_gather(pbvh, BKE_pbvh_node_planes_contain_AABB, clip_planes, &nodes, &totnode); + + sculpt_undo_push_begin("Mask lasso fill"); + +#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) + for (i = 0; i < totnode; i++) { + PBVHVertexIter vi; + bool any_masked = false; + + BKE_pbvh_vertex_iter_begin(pbvh, nodes[i], vi, PBVH_ITER_UNIQUE) { + if (is_effected_lasso(&data, vi.co)) { + if (!any_masked) { + any_masked = true; + + sculpt_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK); + + BKE_pbvh_node_mark_redraw(nodes[i]); + if (BKE_pbvh_type(pbvh) == PBVH_GRIDS) + multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED); + } + + mask_flood_fill_set_elem(vi.mask, mode, value); + } + } BKE_pbvh_vertex_iter_end; + } + + sculpt_undo_push_end(); + + if (nodes) + MEM_freeN(nodes); + + ED_region_tag_redraw(vc.ar); + MEM_freeN((void *)mcords); + MEM_freeN(data.px); + + return OPERATOR_FINISHED; + } + return OPERATOR_PASS_THROUGH; +} + +void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot) +{ + PropertyRNA *prop; + + ot->name = "Mask Lasso Gesture"; + ot->idname = "PAINT_OT_mask_lasso_gesture"; + ot->description = "Add mask within the lasso as you move the pointer"; + + ot->invoke = WM_gesture_lasso_invoke; + ot->modal = WM_gesture_lasso_modal; + ot->exec = paint_mask_gesture_lasso_exec; + + ot->poll = sculpt_mode_poll; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + prop = RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath); +} diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 8b038973831..809e9911e09 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -613,13 +613,12 @@ static void stencil_restore(StencilControlData *scd) *scd->rot_target = scd->init_rot; } -static int stencil_control_cancel(bContext *UNUSED(C), wmOperator *op) +static void stencil_control_cancel(bContext *UNUSED(C), wmOperator *op) { StencilControlData *scd = op->customdata; stencil_restore(scd); MEM_freeN(op->customdata); - return OPERATOR_CANCELLED; } static void stencil_control_calculate(StencilControlData *scd, const int mval[2]) @@ -987,6 +986,7 @@ void ED_operatortypes_paint(void) /* paint masking */ WM_operatortype_append(PAINT_OT_mask_flood_fill); + WM_operatortype_append(PAINT_OT_mask_lasso_gesture); } @@ -1149,6 +1149,8 @@ void ED_keymap_paint(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "PAINT_OT_mask_flood_fill", IKEY, KM_PRESS, KM_CTRL, 0); RNA_enum_set(kmi->ptr, "mode", PAINT_MASK_INVERT); + WM_keymap_add_item(keymap, "PAINT_OT_mask_lasso_gesture", LEFTMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0); + /* Toggle dynamic topology */ WM_keymap_add_item(keymap, "SCULPT_OT_dynamic_topology_toggle", DKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index b00b1c3ecff..397baeae4c9 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -718,10 +718,13 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event) /* Cancel */ if (event->type == EVT_MODAL_MAP && event->val == PAINT_STROKE_MODAL_CANCEL) { - if (op->type->cancel) - return op->type->cancel(C, op); - else - return paint_stroke_cancel(C, op); + if (op->type->cancel) { + op->type->cancel(C, op); + } + else { + paint_stroke_cancel(C, op); + } + return OPERATOR_CANCELLED; } if (event->type == stroke->event_type && event->val == KM_RELEASE && !first_modal) { @@ -787,10 +790,9 @@ int paint_stroke_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -int paint_stroke_cancel(bContext *C, wmOperator *op) +void paint_stroke_cancel(bContext *C, wmOperator *op) { stroke_done(C, op); - return OPERATOR_CANCELLED; } ViewContext *paint_stroke_view_context(PaintStroke *stroke) diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 1c3caf5d8bc..714d67c8039 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -378,12 +378,12 @@ static int wpaint_mirror_vgroup_ensure(Object *ob, const int vgroup_active) if (defgroup) { int mirrdef; - char name[MAXBONENAME]; + char name_flip[MAXBONENAME]; - flip_side_name(name, defgroup->name, FALSE); - mirrdef = defgroup_name_index(ob, name); + BKE_deform_flip_side_name(name_flip, defgroup->name, false); + mirrdef = defgroup_name_index(ob, name_flip); if (mirrdef == -1) { - if (BKE_defgroup_new(ob, name)) { + if (BKE_defgroup_new(ob, name_flip)) { mirrdef = BLI_countlist(&ob->defbase) - 1; } } @@ -2059,7 +2059,7 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op) BKE_mesh_flush_select_from_polys(me); } - /* weight paint spesific */ + /* weight paint specific */ mesh_octree_table(NULL, NULL, NULL, 'e'); mesh_mirrtopo_table(NULL, 'e'); @@ -2075,7 +2075,7 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op) BKE_paint_init(&wp->paint, PAINT_CURSOR_WEIGHT_PAINT); - /* weight paint spesific */ + /* weight paint specific */ mesh_octree_table(ob, NULL, NULL, 's'); ED_vgroup_sync_from_pose(ob); } @@ -2593,11 +2593,9 @@ static int wpaint_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int wpaint_cancel(bContext *C, wmOperator *op) +static void wpaint_cancel(bContext *C, wmOperator *op) { paint_stroke_cancel(C, op); - - return OPERATOR_CANCELLED; } void PAINT_OT_weight_paint(wmOperatorType *ot) @@ -3144,11 +3142,9 @@ static int vpaint_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int vpaint_cancel(bContext *C, wmOperator *op) +static void vpaint_cancel(bContext *C, wmOperator *op) { paint_stroke_cancel(C, op); - - return OPERATOR_CANCELLED; } void PAINT_OT_vertex_paint(wmOperatorType *ot) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 2a6b6d4b3d9..6bd935af436 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1082,6 +1082,7 @@ static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nod float out_flip[3] = {0.0f, 0.0f, 0.0f}; SculptSession *ss = ob->sculpt; + const Brush *brush = BKE_paint_brush(&sd->paint); int n, original; /* Grab brush requires to test on original data (see r33888 and @@ -1090,8 +1091,14 @@ static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nod TRUE : ss->cache->original); /* In general the original coords are not available with dynamic - * topology */ - if (ss->bm) + * topology + * + * Mask tool could not use undo nodes to get coordinates from + * since the coordinates are not stored in those odes. + * And mask tool is not gonna to modify vertex coordinates, + * so we don't actually need to use modified coords. + */ + if (ss->bm || brush->sculpt_tool == SCULPT_TOOL_MASK) original = FALSE; (void)sd; /* unused w/o openmp */ @@ -2481,7 +2488,7 @@ static void calc_area_normal_and_flatten_center(Sculpt *sd, Object *ob, /* for flatten center */ add_v3_v3(fc, private_fc); - add_v3_v3(fc_flip, private_fc); + add_v3_v3(fc_flip, private_fc_flip); count += private_count; count_flipped += private_count_flip; } @@ -4560,7 +4567,7 @@ static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int sculpt_brush_stroke_cancel(bContext *C, wmOperator *op) +static void sculpt_brush_stroke_cancel(bContext *C, wmOperator *op) { Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; @@ -4578,8 +4585,6 @@ static int sculpt_brush_stroke_cancel(bContext *C, wmOperator *op) } sculpt_brush_exit_tex(sd); - - return OPERATOR_CANCELLED; } static void SCULPT_OT_brush_stroke(wmOperatorType *ot) @@ -4653,7 +4658,7 @@ static void SCULPT_OT_set_persistent_base(wmOperatorType *ot) static void sculpt_dynamic_topology_triangulate(BMesh *bm) { if (bm->totloop != bm->totface * 3) { - BM_mesh_triangulate(bm, false, false, NULL, NULL); + BM_mesh_triangulate(bm, MOD_TRIANGULATE_QUAD_FIXED, MOD_TRIANGULATE_NGON_SCANFILL, false, NULL, NULL); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c index 7a973d8c1ae..626df03a5d4 100644 --- a/source/blender/editors/sculpt_paint/sculpt_uv.c +++ b/source/blender/editors/sculpt_paint/sculpt_uv.c @@ -480,7 +480,7 @@ static void uv_sculpt_stroke_exit(bContext *C, wmOperator *op) WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), data->timer); } if (data->elementMap) { - EDBM_uv_element_map_free(data->elementMap); + BM_uv_element_map_free(data->elementMap); } if (data->uv) { MEM_freeN(data->uv); @@ -501,7 +501,7 @@ static void uv_sculpt_stroke_exit(bContext *C, wmOperator *op) static int uv_element_offset_from_face_get(UvElementMap *map, BMFace *efa, BMLoop *l, int island_index, int doIslands) { - UvElement *element = ED_uv_element_get(map, efa, l); + UvElement *element = BM_uv_element_get(map, efa, l); if (!element || (doIslands && element->island != island_index)) { return -1; } @@ -566,18 +566,18 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm if (do_island_optimization) { /* We will need island information */ if (ts->uv_flag & UV_SYNC_SELECTION) { - data->elementMap = EDBM_uv_element_map_create(em, 0, 1); + data->elementMap = BM_uv_element_map_create(bm, false, true); } else { - data->elementMap = EDBM_uv_element_map_create(em, 1, 1); + data->elementMap = BM_uv_element_map_create(bm, true, true); } } else { if (ts->uv_flag & UV_SYNC_SELECTION) { - data->elementMap = EDBM_uv_element_map_create(em, 0, 0); + data->elementMap = BM_uv_element_map_create(bm, false, false); } else { - data->elementMap = EDBM_uv_element_map_create(em, 1, 0); + data->elementMap = BM_uv_element_map_create(bm, true, false); } } @@ -596,7 +596,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm Image *ima = CTX_data_edit_image(C); uv_find_nearest_vert(scene, ima, em, co, NULL, &hit); - element = ED_uv_element_get(data->elementMap, hit.efa, hit.l); + element = BM_uv_element_get(data->elementMap, hit.efa, hit.l); island_index = element->island; } diff --git a/source/blender/editors/sound/SConscript b/source/blender/editors/sound/SConscript index 016f8055da0..33feedf51cc 100644 --- a/source/blender/editors/sound/SConscript +++ b/source/blender/editors/sound/SConscript @@ -44,4 +44,10 @@ incs = ' '.join(incs) defs = [] +if env['WITH_BF_FFMPEG']: + defs.append('WITH_FFMPEG') + +if env['WITH_BF_SNDFILE']: + defs.append('WITH_SNDFILE') + env.BlenderLib ( 'bf_editors_sound', sources, Split(incs), defs, libtype=['core'], priority=[35] ) diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index a2189f6237c..81b0992c878 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -77,11 +77,10 @@ /******************** open sound operator ********************/ -static int sound_open_cancel(bContext *UNUSED(C), wmOperator *op) +static void sound_open_cancel(bContext *UNUSED(C), wmOperator *op) { MEM_freeN(op->customdata); op->customdata = NULL; - return OPERATOR_CANCELLED; } static void sound_open_init(bContext *C, wmOperator *op) diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c index 7d238bf7887..346ffcbc3e2 100644 --- a/source/blender/editors/space_action/action_ops.c +++ b/source/blender/editors/space_action/action_ops.c @@ -97,12 +97,9 @@ void ED_operatormacros_action(void) ot = WM_operatortype_append_macro("ACTION_OT_duplicate_move", "Duplicate", "Make a copy of all selected keyframes and move them", OPTYPE_UNDO | OPTYPE_REGISTER); - if (ot) { - WM_operatortype_macro_define(ot, "ACTION_OT_duplicate"); - otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_transform"); - RNA_enum_set(otmacro->ptr, "mode", TFM_TIME_DUPLICATE); - } - + WM_operatortype_macro_define(ot, "ACTION_OT_duplicate"); + otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_transform"); + RNA_enum_set(otmacro->ptr, "mode", TFM_TIME_DUPLICATE); } /* ************************** registration - keymaps **********************************/ @@ -112,21 +109,38 @@ static void action_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) wmKeyMapItem *kmi; /* action_select.c - selection tools */ - /* click-select */ + /* click-select: keyframe (replace) */ kmi = WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, 0, 0); RNA_boolean_set(kmi->ptr, "extend", FALSE); RNA_boolean_set(kmi->ptr, "column", FALSE); + RNA_boolean_set(kmi->ptr, "channel", FALSE); + /* click-select: all on same frame (replace) */ kmi = WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT, 0); RNA_boolean_set(kmi->ptr, "extend", FALSE); RNA_boolean_set(kmi->ptr, "column", TRUE); + RNA_boolean_set(kmi->ptr, "channel", FALSE); + /* click-select: keyframe (add) */ kmi = WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "extend", TRUE); RNA_boolean_set(kmi->ptr, "column", FALSE); + RNA_boolean_set(kmi->ptr, "channel", FALSE); + /* click-select: all on same frame (add) */ kmi = WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT | KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "extend", TRUE); RNA_boolean_set(kmi->ptr, "column", TRUE); + RNA_boolean_set(kmi->ptr, "channel", FALSE); + /* click-select: all on same channel (replace) */ + kmi = WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL | KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_boolean_set(kmi->ptr, "column", FALSE); + RNA_boolean_set(kmi->ptr, "channel", TRUE); + /* click-select: all on same channel (add) */ + kmi = WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL | KM_ALT | KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "extend", TRUE); + RNA_boolean_set(kmi->ptr, "column", FALSE); + RNA_boolean_set(kmi->ptr, "channel", TRUE); - /* select left/right */ + /* click-select: left/right */ kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); RNA_boolean_set(kmi->ptr, "extend", FALSE); RNA_enum_set(kmi->ptr, "mode", ACTKEYS_LRSEL_TEST); @@ -163,7 +177,7 @@ static void action_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) WM_keymap_add_item(keymap, "ACTION_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "ACTION_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0); - /* select linekd */ + /* select linked */ WM_keymap_add_item(keymap, "ACTION_OT_select_linked", LKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index 9d124cf08ee..d62dd88418f 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -930,6 +930,7 @@ void ACTION_OT_select_leftright(wmOperatorType *ot) * - 1) keyframe under mouse - no special modifiers * - 2) all keyframes on the same side of current frame indicator as mouse - ALT modifier * - 3) column select all keyframes in frame under mouse - CTRL modifier + * - 4) all keyframes in channel under mouse - CTRL+ALT modifiers * * In addition to these basic options, the SHIFT modifier can be used to toggle the * selection mode between replacing the selection (without) and inverting the selection (with). @@ -949,24 +950,31 @@ static void actkeys_mselect_single(bAnimContext *ac, bAnimListElem *ale, short s ked.f1 = selx; /* select the nominated keyframe on the given frame */ - if (ale->type == ANIMTYPE_GPLAYER) + if (ale->type == ANIMTYPE_GPLAYER) { ED_gpencil_select_frame(ale->data, selx, select_mode); - else if (ale->type == ANIMTYPE_MASKLAYER) + } + else if (ale->type == ANIMTYPE_MASKLAYER) { ED_mask_select_frame(ale->data, selx, select_mode); + } else { if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK) && (ale->type == ANIMTYPE_SUMMARY) && (ale->datatype == ALE_ALL)) { ListBase anim_data = {NULL, NULL}; int filter; + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + for (ale = anim_data.first; ale; ale = ale->next) { - if (ale->type == ANIMTYPE_GPLAYER) + if (ale->type == ANIMTYPE_GPLAYER) { ED_gpencil_select_frame(ale->data, selx, select_mode); - else if (ale->type == ANIMTYPE_MASKLAYER) + } + else if (ale->type == ANIMTYPE_MASKLAYER) { ED_mask_select_frame(ale->data, selx, select_mode); + } } + BLI_freelistN(&anim_data); } else { @@ -1023,10 +1031,52 @@ static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float se BLI_freelistN(&ked.list); BLI_freelistN(&anim_data); } + +/* option 4) select all keyframes in same channel */ +static void actkeys_mselect_channel_only(bAnimContext *ac, bAnimListElem *ale, short select_mode) +{ + KeyframeEditFunc select_cb; + + /* get functions for selecting keyframes */ + select_cb = ANIM_editkeyframes_select(select_mode); + + /* select all keyframes in this channel */ + if (ale->type == ANIMTYPE_GPLAYER) { + ED_gpencil_select_frames(ale->data, select_mode); + } + else if (ale->type == ANIMTYPE_MASKLAYER) { + ED_mask_select_frames(ale->data, select_mode); + } + else { + if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK) && + (ale->type == ANIMTYPE_SUMMARY) && (ale->datatype == ALE_ALL)) + { + ListBase anim_data = {NULL, NULL}; + int filter; + + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ | ANIMFILTER_NODUPLIS); + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + + for (ale = anim_data.first; ale; ale = ale->next) { + if (ale->type == ANIMTYPE_GPLAYER) { + ED_gpencil_select_frames(ale->data, select_mode); + } + else if (ale->type == ANIMTYPE_MASKLAYER) { + ED_mask_select_frames(ale->data, select_mode); + } + } + + BLI_freelistN(&anim_data); + } + else { + ANIM_animchannel_keyframes_loop(NULL, ac->ads, ale, NULL, select_cb, NULL); + } + } +} /* ------------------- */ -static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_mode, short column) +static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_mode, bool column, bool same_channel) { ListBase anim_data = {NULL, NULL}; DLRBT_Tree anim_keys; @@ -1211,6 +1261,10 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_ /* select all keyframes in the same frame as the one we hit on the active channel */ actkeys_mselect_column(ac, select_mode, selx); } + else if (same_channel) { + /* select all keyframes in the active channel */ + actkeys_mselect_channel_only(ac, ale, select_mode); + } else { /* select the nominated keyframe on the given frame */ actkeys_mselect_single(ac, ale, select_mode, selx); @@ -1227,7 +1281,8 @@ static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent { bAnimContext ac; /* ARegion *ar; */ /* UNUSED */ - short selectmode, column; + short selectmode; + bool column, channel; /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) @@ -1244,9 +1299,10 @@ static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent /* column selection */ column = RNA_boolean_get(op->ptr, "column"); + channel = RNA_boolean_get(op->ptr, "channel"); /* select keyframe(s) based upon mouse position*/ - mouse_action_keys(&ac, event->mval, selectmode, column); + mouse_action_keys(&ac, event->mval, selectmode, column, channel); /* set notifier that keyframe selection (and channels too) have changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | ND_ANIMCHAN | NA_SELECTED, NULL); @@ -1272,10 +1328,16 @@ void ACTION_OT_clickselect(wmOperatorType *ot) ot->flag = OPTYPE_UNDO; /* properties */ - prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY + prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", + "Toggle keyframe selection instead of leaving newly selected keyframes only"); // SHIFTKEY + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + + prop = RNA_def_boolean(ot->srna, "column", 0, "Column Select", + "Select all keyframes that occur on the same frame as the one under the mouse"); // ALTKEY RNA_def_property_flag(prop, PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, "column", 0, "Column Select", ""); // ALTKEY + prop = RNA_def_boolean(ot->srna, "channel", 0, "Only Channel", + "Select all the keyframes in the channel under the mouse"); // CTRLKEY + ALTKEY RNA_def_property_flag(prop, PROP_SKIP_SAVE); } diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index a89a02b7e01..fdccedd9c3c 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -541,7 +541,7 @@ void ED_spacetype_action(void) art = MEM_callocN(sizeof(ARegionType), "spacetype action region"); art->regionid = RGN_TYPE_CHANNELS; art->prefsizex = 200; - art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D; + art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES; art->init = action_channel_area_init; art->draw = action_channel_area_draw; diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index bb0521d6589..e2262398a52 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -133,6 +133,7 @@ void ED_spacetypes_init(void) * maybe we'll need to have them go after python operators too? */ ED_operatormacros_armature(); ED_operatormacros_mesh(); + ED_operatormacros_metaball(); ED_operatormacros_node(); ED_operatormacros_object(); ED_operatormacros_file(); diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index cf277957e70..4fbf5aa5fb7 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -158,12 +158,10 @@ static int file_browse_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int file_browse_cancel(bContext *UNUSED(C), wmOperator *op) +static void file_browse_cancel(bContext *UNUSED(C), wmOperator *op) { MEM_freeN(op->customdata); op->customdata = NULL; - - return OPERATOR_CANCELLED; } static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event) diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c index 8508123f942..975123f244c 100644 --- a/source/blender/editors/space_buttons/buttons_texture.c +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -516,7 +516,7 @@ static void template_texture_user_menu(bContext *C, uiLayout *layout, void *UNUS if (!last_category || strcmp(last_category, user->category) != 0) { uiItemL(layout, user->category, ICON_NONE); but = block->buttons.last; - but->flag = UI_TEXT_LEFT; + but->drawflag = UI_BUT_TEXT_LEFT; } /* create button */ @@ -577,7 +577,7 @@ void uiTemplateTextureUser(uiLayout *layout, bContext *C) /* some cosmetic tweaks */ but->type = MENU; - but->flag |= UI_TEXT_LEFT; + but->drawflag |= UI_BUT_TEXT_LEFT; but->flag &= ~UI_ICON_SUBMENU; } diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index f5db34d87d7..0e1a2f98d40 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -639,7 +639,7 @@ static unsigned char *prefetch_read_file_to_memory(MovieClip *clip, int current_ BKE_movieclip_filename_for_frame(clip, &user, name); - file = open(name, O_BINARY | O_RDONLY, 0); + file = BLI_open(name, O_BINARY | O_RDONLY, 0); if (file < 0) { return NULL; } @@ -711,7 +711,7 @@ static unsigned char *prefetch_thread_next_frame(PrefetchQueue *queue, MovieClip current_frame = prefetch_find_uncached_frame(clip, queue->current_frame + 1, queue->end_frame, queue->render_size, queue->render_flag, 1); /* switch direction if read frames from current up to scene end frames */ - if (current_frame >= queue->end_frame) { + if (current_frame > queue->end_frame) { queue->current_frame = queue->initial_frame; queue->direction = -1; } @@ -752,6 +752,7 @@ static unsigned char *prefetch_thread_next_frame(PrefetchQueue *queue, MovieClip static void *do_prefetch_thread(void *data_v) { PrefetchThread *data = (PrefetchThread *) data_v; + MovieClip *clip = data->clip; unsigned char *mem; size_t size; int current_frame; @@ -766,7 +767,7 @@ static void *do_prefetch_thread(void *data_v) user.render_size = data->queue->render_size; user.render_flag = data->queue->render_flag; - ibuf = IMB_ibImageFromMemory(mem, size, flag, NULL, "prefetch frame"); + ibuf = IMB_ibImageFromMemory(mem, size, flag, clip->colorspace_settings.name, "prefetch frame"); result = BKE_movieclip_put_frame_if_possible(data->clip, &user, ibuf); diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c index 173d65ee4fc..80b844464db 100644 --- a/source/blender/editors/space_clip/clip_graph_draw.c +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -123,10 +123,16 @@ static void tracking_segment_end_cb(void *UNUSED(userdata)) glLineWidth(1.0f); } +typedef struct TrackMotionCurveUserData { + MovieTrackingTrack *act_track; + bool sel; + float xscale, yscale, hsize; +} TrackMotionCurveUserData; + static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, int scene_framenr, float val) { - struct { MovieTrackingTrack *act_track; bool sel; float xscale, yscale, hsize; } *data = userdata; + TrackMotionCurveUserData *data = (TrackMotionCurveUserData *) userdata; int sel = 0, sel_flag; if (track != data->act_track) @@ -151,7 +157,7 @@ static void draw_tracks_curves(View2D *v2d, SpaceClip *sc) MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); int width, height; - struct { MovieTrackingTrack *act_track; bool sel; float xscale, yscale, hsize; } userdata; + TrackMotionCurveUserData userdata; BKE_movieclip_get_size(clip, &sc->user, &width, &height); @@ -163,19 +169,25 @@ static void draw_tracks_curves(View2D *v2d, SpaceClip *sc) userdata.sel = false; userdata.act_track = act_track; UI_view2d_getscale(v2d, &userdata.xscale, &userdata.yscale); - clip_graph_tracking_values_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY, sc->flag & SC_SHOW_GRAPH_HIDDEN, + clip_graph_tracking_values_iterate(sc, + (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, + (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, &userdata, tracking_segment_knot_cb, NULL, NULL); /* draw graph lines */ glEnable(GL_BLEND); - clip_graph_tracking_values_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY, sc->flag & SC_SHOW_GRAPH_HIDDEN, + clip_graph_tracking_values_iterate(sc, + (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, + (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, act_track, tracking_segment_point_cb, tracking_segment_start_cb, tracking_segment_end_cb); glDisable(GL_BLEND); /* selected knot handles on top of curves */ userdata.sel = TRUE; - clip_graph_tracking_values_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY, sc->flag & SC_SHOW_GRAPH_HIDDEN, + clip_graph_tracking_values_iterate(sc, + (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, + (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, &userdata, tracking_segment_knot_cb, NULL, NULL); } diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c index 393f92f5af5..d1c44693995 100644 --- a/source/blender/editors/space_clip/clip_graph_ops.c +++ b/source/blender/editors/space_clip/clip_graph_ops.c @@ -190,8 +190,10 @@ static bool mouse_select_knot(bContext *C, float co[2], bool extend) if (!extend) { SelectUserData selectdata = {SEL_DESELECT}; - clip_graph_tracking_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY, - sc->flag & SC_SHOW_GRAPH_HIDDEN, &selectdata, + clip_graph_tracking_iterate(sc, + (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, + (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, + &selectdata, toggle_selection_cb); } @@ -217,7 +219,9 @@ static bool mouse_select_curve(bContext *C, float co[2], bool extend) MouseSelectUserData userdata; mouse_select_init_data(&userdata, co); - clip_graph_tracking_values_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY, sc->flag & SC_SHOW_GRAPH_HIDDEN, + clip_graph_tracking_values_iterate(sc, + (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, + (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, &userdata, find_nearest_tracking_segment_cb, NULL, find_nearest_tracking_segment_end_cb); @@ -237,9 +241,10 @@ static bool mouse_select_curve(bContext *C, float co[2], bool extend) BKE_tracking_track_select(tracksbase, userdata.track, TRACK_AREA_ALL, TRUE); /* deselect all knots on newly selected curve */ - clip_graph_tracking_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY, - sc->flag & SC_SHOW_GRAPH_HIDDEN, &selectdata, - toggle_selection_cb); + clip_graph_tracking_iterate(sc, + (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, + (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, + &selectdata, toggle_selection_cb); } return true; @@ -565,9 +570,10 @@ static int view_all_exec(bContext *C, wmOperator *UNUSED(op)) userdata.max = -FLT_MAX; userdata.min = FLT_MAX; - clip_graph_tracking_values_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY, - sc->flag & SC_SHOW_GRAPH_HIDDEN, &userdata, - view_all_cb, NULL, NULL); + clip_graph_tracking_values_iterate(sc, + (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, + (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, + &userdata, view_all_cb, NULL, NULL); /* set extents of view to start/end frames */ v2d->cur.xmin = (float) SFRA; diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h index 39af856d280..513014a2d0d 100644 --- a/source/blender/editors/space_clip/clip_intern.h +++ b/source/blender/editors/space_clip/clip_intern.h @@ -126,12 +126,12 @@ void clip_graph_tracking_values_iterate_track(struct SpaceClip *sc, struct Movie void (*segment_start)(void *userdata, struct MovieTrackingTrack *track, int coord), void (*segment_end)(void *userdata)); -void clip_graph_tracking_values_iterate(struct SpaceClip *sc, int selected_only, int include_hidden, void *userdata, +void clip_graph_tracking_values_iterate(struct SpaceClip *sc, bool selected_only, bool include_hidden, void *userdata, 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_iterate(struct SpaceClip *sc, int selected_only, int include_hidden, void *userdata, +void clip_graph_tracking_iterate(struct SpaceClip *sc, bool selected_only, bool include_hidden, void *userdata, void (*func)(void *userdata, struct MovieTrackingMarker *marker)); void clip_delete_track(struct bContext *C, struct MovieClip *clip, struct MovieTrackingTrack *track); diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index a76f4364492..9aa6eab7fc8 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -159,12 +159,10 @@ static void open_init(bContext *C, wmOperator *op) uiIDContextProperty(C, &pprop->ptr, &pprop->prop); } -static int open_cancel(bContext *UNUSED(C), wmOperator *op) +static void open_cancel(bContext *UNUSED(C), wmOperator *op) { MEM_freeN(op->customdata); op->customdata = NULL; - - return OPERATOR_CANCELLED; } static int open_exec(bContext *C, wmOperator *op) @@ -444,11 +442,9 @@ static int view_pan_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static int view_pan_cancel(bContext *C, wmOperator *op) +static void view_pan_cancel(bContext *C, wmOperator *op) { - view_pan_exit(C, op, 1); - - return OPERATOR_CANCELLED; + view_pan_exit(C, op, true); } void CLIP_OT_view_pan(wmOperatorType *ot) @@ -578,11 +574,9 @@ static int view_zoom_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static int view_zoom_cancel(bContext *C, wmOperator *op) +static void view_zoom_cancel(bContext *C, wmOperator *op) { - view_zoom_exit(C, op, 1); - - return OPERATOR_CANCELLED; + view_zoom_exit(C, op, true); } void CLIP_OT_view_zoom(wmOperatorType *ot) diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index 635aa388541..060531ae82c 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -37,7 +37,9 @@ #include "BLI_utildefines.h" #include "BLI_math.h" #include "BLI_listbase.h" +#include "BLI_string.h" +#include "BKE_animsys.h" #include "BKE_context.h" #include "BKE_movieclip.h" #include "BKE_tracking.h" @@ -125,7 +127,7 @@ void clip_graph_tracking_values_iterate_track( } void clip_graph_tracking_values_iterate( - SpaceClip *sc, int selected_only, int include_hidden, void *userdata, + SpaceClip *sc, bool selected_only, bool include_hidden, void *userdata, void (*func)(void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord), @@ -147,7 +149,7 @@ void clip_graph_tracking_values_iterate( } } -void clip_graph_tracking_iterate(SpaceClip *sc, int selected_only, int include_hidden, void *userdata, +void clip_graph_tracking_iterate(SpaceClip *sc, bool selected_only, bool include_hidden, void *userdata, void (*func)(void *userdata, MovieTrackingMarker *marker)) { MovieClip *clip = ED_space_clip_get_clip(sc); @@ -184,8 +186,8 @@ void clip_delete_track(bContext *C, MovieClip *clip, MovieTrackingTrack *track) MovieTrackingPlaneTrack *plane_track, *next_plane_track; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); - bool has_bundle = false, update_stab = false; + char track_name_escaped[MAX_NAME], prefix[MAX_NAME * 2]; if (track == act_track) tracking->act_track = NULL; @@ -245,6 +247,11 @@ void clip_delete_track(bContext *C, MovieClip *clip, MovieTrackingTrack *track) } } + /* Delete f-curves associated with the track (such as weight, i.e.) */ + BLI_strescape(track_name_escaped, track->name, sizeof(track_name_escaped)); + BLI_snprintf(prefix, sizeof(prefix), "tracks[\"%s\"]", track_name_escaped); + BKE_animdata_fix_paths_remove(&clip->id, prefix); + BKE_tracking_track_free(track); BLI_freelinkN(tracksbase, track); diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 246ea7fe140..5607d7dc635 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -1097,16 +1097,16 @@ static int track_markers_testbreak(void) return G.is_break; } -static int track_count_markers(SpaceClip *sc, MovieClip *clip) +static int track_count_markers(SpaceClip *sc, MovieClip *clip, int framenr) { int tot = 0; ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); MovieTrackingTrack *track; - int framenr = ED_space_clip_get_clip_frame_number(sc); track = tracksbase->first; while (track) { - if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { + bool selected = sc ? TRACK_VIEW_SELECTED(sc, track) : TRACK_SELECTED(track); + if (selected && (track->flag & TRACK_LOCKED) == 0) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if (!marker || (marker->flag & MARKER_DISABLED) == 0) @@ -1142,18 +1142,20 @@ static void clear_invisible_track_selection(SpaceClip *sc, MovieClip *clip) } } -static void track_init_markers(SpaceClip *sc, MovieClip *clip, int *frames_limit_r) +static void track_init_markers(SpaceClip *sc, MovieClip *clip, int framenr, int *frames_limit_r) { ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); MovieTrackingTrack *track; - int framenr = ED_space_clip_get_clip_frame_number(sc); int frames_limit = 0; - clear_invisible_track_selection(sc, clip); + if (sc != NULL) { + clear_invisible_track_selection(sc, clip); + } track = tracksbase->first; while (track) { - if (TRACK_VIEW_SELECTED(sc, track)) { + bool selected = sc ? TRACK_VIEW_SELECTED(sc, track) : TRACK_SELECTED(track); + if (selected) { if ((track->flag & TRACK_HIDDEN) == 0 && (track->flag & TRACK_LOCKED) == 0) { BKE_tracking_marker_ensure(track, framenr); @@ -1193,8 +1195,9 @@ static int track_markers_initjob(bContext *C, TrackMarkersJob *tmj, int backward Scene *scene = CTX_data_scene(C); MovieTrackingSettings *settings = &clip->tracking.settings; int frames_limit; + int framenr = ED_space_clip_get_clip_frame_number(sc); - track_init_markers(sc, clip, &frames_limit); + track_init_markers(sc, clip, framenr, &frames_limit); tmj->sfra = ED_space_clip_get_clip_frame_number(sc); tmj->clip = clip; @@ -1317,20 +1320,49 @@ static void track_markers_freejob(void *tmv) static int track_markers_exec(bContext *C, wmOperator *op) { - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); + SpaceClip *sc; + MovieClip *clip; Scene *scene = CTX_data_scene(C); struct MovieTrackingContext *context; - int framenr = ED_space_clip_get_clip_frame_number(sc); - int sfra = framenr, efra; + MovieClipUser *user, fake_user = {0}; + int framenr, sfra, efra; int backwards = RNA_boolean_get(op->ptr, "backwards"); int sequence = RNA_boolean_get(op->ptr, "sequence"); int frames_limit; - if (track_count_markers(sc, clip) == 0) + if (RNA_struct_property_is_set(op->ptr, "clip")) { + Main *bmain = CTX_data_main(C); + char clip_name[MAX_ID_NAME - 2]; + + RNA_string_get(op->ptr, "clip", clip_name); + clip = (MovieClip *)BLI_findstring(&bmain->movieclip, clip_name, offsetof(ID, name) + 2); + sc = NULL; + + if (clip == NULL) { + return OPERATOR_CANCELLED; + } + framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, CFRA); + fake_user.framenr = framenr; + user = &fake_user; + } + else { + sc = CTX_wm_space_clip(C); + + if (sc == NULL) { + return OPERATOR_CANCELLED; + } + + clip = ED_space_clip_get_clip(sc); + framenr = ED_space_clip_get_clip_frame_number(sc); + user = &sc->user; + } + + sfra = framenr; + + if (track_count_markers(sc, clip, framenr) == 0) return OPERATOR_CANCELLED; - track_init_markers(sc, clip, &frames_limit); + track_init_markers(sc, clip, framenr, &frames_limit); if (backwards) efra = SFRA; @@ -1351,7 +1383,7 @@ static int track_markers_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; /* do not disable tracks due to threshold when tracking frame-by-frame */ - context = BKE_tracking_context_new(clip, &sc->user, backwards, sequence); + context = BKE_tracking_context_new(clip, user, backwards, sequence); while (framenr != efra) { if (!BKE_tracking_context_step(context)) @@ -1382,10 +1414,21 @@ static int track_markers_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS TrackMarkersJob *tmj; ScrArea *sa = CTX_wm_area(C); SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); + MovieClip *clip; wmJob *wm_job; - int backwards = RNA_boolean_get(op->ptr, "backwards"); - int sequence = RNA_boolean_get(op->ptr, "sequence"); + bool backwards = RNA_boolean_get(op->ptr, "backwards"); + bool sequence = RNA_boolean_get(op->ptr, "sequence"); + int framenr; + + if (sc == NULL) { + /* TODO(sergey): Support clip for invoke as well. */ + BKE_report(op->reports, RPT_ERROR, + "Invoking this operator only supported from Clip Editor space"); + return OPERATOR_CANCELLED; + } + + clip = ED_space_clip_get_clip(sc); + framenr = ED_space_clip_get_clip_frame_number(sc); if (WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C), WM_JOB_TYPE_ANY)) { /* only one tracking is allowed at a time */ @@ -1395,7 +1438,7 @@ static int track_markers_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS if (clip->tracking_context) return OPERATOR_CANCELLED; - if (track_count_markers(sc, clip) == 0) + if (track_count_markers(sc, clip, framenr) == 0) return OPERATOR_CANCELLED; if (!sequence) @@ -1453,6 +1496,8 @@ static int track_markers_modal(bContext *C, wmOperator *UNUSED(op), const wmEven void CLIP_OT_track_markers(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Track Markers"; ot->description = "Track selected markers"; @@ -1461,7 +1506,6 @@ 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_poll; ot->modal = track_markers_modal; /* flags */ @@ -1470,6 +1514,8 @@ void CLIP_OT_track_markers(wmOperatorType *ot) /* properties */ RNA_def_boolean(ot->srna, "backwards", 0, "Backwards", "Do backwards tracking"); RNA_def_boolean(ot->srna, "sequence", 0, "Track Sequence", "Track marker during image sequence rather than single image"); + prop = RNA_def_string(ot->srna, "clip", "", MAX_NAME, "Movie Clip", "Movie Clip to be tracked"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } /********************** refine track position operator *********************/ @@ -1550,7 +1596,7 @@ static int solve_camera_initjob(bContext *C, SolveCameraJob *scj, wmOperator *op scj->reports = op->reports; scj->user = sc->user; - scj->context = BKE_tracking_reconstruction_context_new(tracking, object, + scj->context = BKE_tracking_reconstruction_context_new(clip, object, object->keyframe1, object->keyframe2, width, height); tracking->stats = MEM_callocN(sizeof(MovieTrackingStats), "solve camera stats"); diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index 289986d7fba..f24a204912e 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -1123,10 +1123,9 @@ static int console_modal_select(bContext *C, wmOperator *op, const wmEvent *even return OPERATOR_RUNNING_MODAL; } -static int console_modal_select_cancel(bContext *C, wmOperator *op) +static void console_modal_select_cancel(bContext *C, wmOperator *op) { console_cursor_set_exit(C, op); - return OPERATOR_FINISHED; } void CONSOLE_OT_select_set(wmOperatorType *ot) diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 43df3be45ac..1ec2e3c804b 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -188,7 +188,7 @@ void file_draw_buttons(const bContext *C, ARegion *ar) uiButSetFlag(but, UI_BUT_NO_UTF8); if ((params->flag & FILE_DIRSEL_ONLY) == 0) { - but = uiDefBut(block, TEX, B_FS_FILENAME, "", + but = uiDefButTextO(block, TEX, "FILE_OT_filename", 0, "", min_x, line2_y, line2_w - chan_offs, btn_h, params->file, 0.0, (float)FILE_MAXFILE, 0, 0, TIP_(overwrite_alert ? N_("File name, overwrite existing") : N_("File name"))); @@ -251,6 +251,9 @@ static int get_file_icon(struct direntry *file) if (strcmp(file->relname, "..") == 0) { return ICON_FILE_PARENT; } + if (file->flags & APPLICATIONBUNDLE) { + return ICON_UGLYPACKAGE; + } if (file->flags & BLENDERFILE) { return ICON_FILE_BLEND; } diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index d01286442be..134fe0ac6bc 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -73,6 +73,7 @@ void FILE_OT_cancel(struct wmOperatorType *ot); void FILE_OT_parent(struct wmOperatorType *ot); void FILE_OT_directory_new(struct wmOperatorType *ot); void FILE_OT_directory(struct wmOperatorType *ot); +void FILE_OT_filename(struct wmOperatorType *ot); void FILE_OT_previous(struct wmOperatorType *ot); void FILE_OT_next(struct wmOperatorType *ot); void FILE_OT_refresh(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index a97b3b1d719..ca2f7b41334 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -32,6 +32,8 @@ #include "BLI_utildefines.h" #include "BLI_fileops_types.h" +#include "BLO_readfile.h" + #include "BKE_context.h" #include "BKE_screen.h" #include "BKE_global.h" @@ -1240,13 +1242,31 @@ int file_directory_exec(bContext *C, wmOperator *UNUSED(unused)) return OPERATOR_FINISHED; } +static int file_filename_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + SpaceFile *sfile = CTX_wm_space_file(C); + + if (sfile->params) { + file_expand_directory(C); + + return file_filename_exec(C, op); + } + + return OPERATOR_CANCELLED; +} + int file_filename_exec(bContext *C, wmOperator *UNUSED(unused)) { SpaceFile *sfile = CTX_wm_space_file(C); char matched_file[FILE_MAX]; + char filepath[sizeof(sfile->params->dir)]; + if (sfile->params) { + int matches = 0; matched_file[0] = '\0'; - if (file_select_match(sfile, sfile->params->file, matched_file)) { + filepath[0] = '\0'; + + if ((matches = file_select_match(sfile, sfile->params->file, matched_file))) { /* int i, numfiles = filelist_numfiles(sfile->files); */ /* XXX UNUSED */ sfile->params->file[0] = '\0'; /* replace the pattern (or filename that the user typed in, with the first selected file of the match */ @@ -1254,6 +1274,31 @@ int file_filename_exec(bContext *C, wmOperator *UNUSED(unused)) WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); } + + if (matches == 1) { + + BLI_join_dirfile(filepath, sizeof(sfile->params->dir), sfile->params->dir, sfile->params->file); + + /* if directory, open it and empty filename field */ + if (BLI_is_dir(filepath)) { + BLI_cleanup_dir(G.main->name, filepath); + BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir)); + sfile->params->file[0] = '\0'; + file_change_dir(C, 1); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); + } + else if (sfile->params->type == FILE_LOADLIB) { + char tdir[FILE_MAX], tgroup[FILE_MAX]; + BLI_add_slash(filepath); + if (BLO_is_a_library(filepath, tdir, tgroup)) { + BLI_cleanup_dir(G.main->name, filepath); + BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir)); + sfile->params->file[0] = '\0'; + file_change_dir(C, 0); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); + } + } + } } return OPERATOR_FINISHED; @@ -1281,6 +1326,18 @@ void FILE_OT_directory(struct wmOperatorType *ot) ot->poll = file_directory_poll; /* <- important, handler is on window level */ } +void FILE_OT_filename(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Enter File Name"; + ot->description = "Enter a file name"; + ot->idname = "FILE_OT_filename"; + + /* api callbacks */ + ot->invoke = file_filename_invoke; + ot->exec = file_filename_exec; +} + void FILE_OT_refresh(struct wmOperatorType *ot) { /* identifiers */ diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c index f4161c7da1c..1809c6cb835 100644 --- a/source/blender/editors/space_file/file_panels.c +++ b/source/blender/editors/space_file/file_panels.c @@ -116,7 +116,7 @@ static void file_panel_category(const bContext *C, Panel *pa, FSMenuCategory cat but = uiDefIconTextButS(block, LISTROW, 0, icon, dir, 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, nr, 0, i, 0, 0, entry); uiButSetFunc(but, file_panel_cb, entry, NULL); uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ - uiButSetFlag(but, UI_ICON_LEFT | UI_TEXT_LEFT); + uiButSetDrawFlag(but, UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT); /* create delete button */ if (allow_delete && fsmenu_can_save(fsmenu, category, i)) { diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 19a6296993d..a2f81498dd3 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -764,56 +764,73 @@ static int file_is_blend_backup(const char *str) return (retval); } - -static int file_extension_type(const char *relname) +static int path_extension_type(const char *path) { - if (BLO_has_bfile_extension(relname)) { + if (BLO_has_bfile_extension(path)) { return BLENDERFILE; } - else if (file_is_blend_backup(relname)) { + else if (file_is_blend_backup(path)) { return BLENDERFILE_BACKUP; } - else if (BLI_testextensie(relname, ".py")) { + else if (BLI_testextensie(path, ".app")) { + return APPLICATIONBUNDLE; + } + else if (BLI_testextensie(path, ".py")) { return PYSCRIPTFILE; } - else if (BLI_testextensie(relname, ".txt") || - BLI_testextensie(relname, ".glsl") || - BLI_testextensie(relname, ".osl") || - BLI_testextensie(relname, ".data")) + else if (BLI_testextensie(path, ".txt") || + BLI_testextensie(path, ".glsl") || + BLI_testextensie(path, ".osl") || + BLI_testextensie(path, ".data")) { return TEXTFILE; } - else if (BLI_testextensie(relname, ".ttf") || - BLI_testextensie(relname, ".ttc") || - BLI_testextensie(relname, ".pfb") || - BLI_testextensie(relname, ".otf") || - BLI_testextensie(relname, ".otc")) + else if (BLI_testextensie(path, ".ttf") || + BLI_testextensie(path, ".ttc") || + BLI_testextensie(path, ".pfb") || + BLI_testextensie(path, ".otf") || + BLI_testextensie(path, ".otc")) { return FTFONTFILE; } - else if (BLI_testextensie(relname, ".btx")) { + else if (BLI_testextensie(path, ".btx")) { return BTXFILE; } - else if (BLI_testextensie(relname, ".dae")) { + else if (BLI_testextensie(path, ".dae")) { return COLLADAFILE; } - else if (BLI_testextensie_array(relname, imb_ext_image) || - (G.have_quicktime && BLI_testextensie_array(relname, imb_ext_image_qt))) + else if (BLI_testextensie_array(path, imb_ext_image) || + (G.have_quicktime && BLI_testextensie_array(path, imb_ext_image_qt))) { return IMAGEFILE; } - else if (BLI_testextensie_array(relname, imb_ext_movie)) { + else if (BLI_testextensie(path, ".ogg")) { + if (IMB_isanim(path)) { + return MOVIEFILE; + } + else { + return SOUNDFILE; + } + } + else if (BLI_testextensie_array(path, imb_ext_movie)) { return MOVIEFILE; } - else if (BLI_testextensie_array(relname, imb_ext_audio)) { + else if (BLI_testextensie_array(path, imb_ext_audio)) { return SOUNDFILE; } return 0; } -int ED_file_extension_icon(const char *relname) +static int file_extension_type(const char *dir, const char *relname) { - int type = file_extension_type(relname); + char path[FILE_MAX]; + BLI_join_dirfile(path, sizeof(path), dir, relname); + return path_extension_type(path); +} + +int ED_file_extension_icon(const char *path) +{ + int type = path_extension_type(path); if (type == BLENDERFILE) return ICON_FILE_BLEND; @@ -848,12 +865,13 @@ static void filelist_setfiletypes(struct FileList *filelist) for (num = 0; num < filelist->numfiles; num++, file++) { file->type = file->s.st_mode; /* restore the mess below */ - - /* Don't check extensions for directories */ +#ifndef __APPLE__ + /* Don't check extensions for directories, allow in OSX cause bundles have extensions*/ if (file->type & S_IFDIR) { continue; } - file->flags = file_extension_type(file->relname); +#endif + file->flags = file_extension_type(filelist->dir, file->relname); if (filelist->filter_glob[0] && BLI_testextensie_glob(file->relname, filelist->filter_glob)) diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 9d762c80405..3cda5dd5e80 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -627,7 +627,7 @@ int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matche if (!match) { BLI_strncpy(matched_file, file->relname, FILE_MAX); } - match = 1; + match++; } } @@ -637,7 +637,7 @@ int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matche bool autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v)) { SpaceFile *sfile = CTX_wm_space_file(C); - bool change = false; + int match = AUTOCOMPLETE_NO_MATCH; /* search if str matches the beginning of name */ if (str[0] && sfile->files) { @@ -672,9 +672,9 @@ bool autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v)) } closedir(dir); - change = autocomplete_end(autocpl, str); - if (change) { - if (BLI_exists(str)) { + match = autocomplete_end(autocpl, str); + if (match) { + if (match == AUTOCOMPLETE_FULL_MATCH) { BLI_add_slash(str); } else { @@ -684,13 +684,13 @@ bool autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v)) } } - return change; + return match == AUTOCOMPLETE_FULL_MATCH; } bool autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v)) { SpaceFile *sfile = CTX_wm_space_file(C); - bool change = false; + int match = AUTOCOMPLETE_NO_MATCH; /* search if str matches the beginning of name */ if (str[0] && sfile->files) { @@ -700,13 +700,13 @@ bool autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v)) for (i = 0; i < nentries; ++i) { struct direntry *file = filelist_file(sfile->files, i); - if (file && S_ISREG(file->type)) { + if (file && (S_ISREG(file->type) || S_ISDIR(file->type))) { autocomplete_do_name(autocpl, file->relname); } } - change = autocomplete_end(autocpl, str); + match = autocomplete_end(autocpl, str); } - return change; + return match == AUTOCOMPLETE_FULL_MATCH; } void ED_fileselect_clear(struct wmWindowManager *wm, struct SpaceFile *sfile) diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c index 04c68e5ea68..62cf4889797 100644 --- a/source/blender/editors/space_file/fsmenu.c +++ b/source/blender/editors/space_file/fsmenu.c @@ -55,9 +55,7 @@ #endif #ifdef __APPLE__ -/* XXX BIG WARNING: carbon.h can not be included in blender code, it conflicts with struct ID */ -# define ID ID_ -# include <CoreServices/CoreServices.h> +#include <Carbon/Carbon.h> #endif /* __APPLE__ */ #ifdef __linux__ @@ -350,7 +348,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) #else #ifdef __APPLE__ { -#if (MAC_OS_X_VERSION_MIN_REQUIRED <= 1040) +#if (MAC_OS_X_VERSION_MIN_REQUIRED <= 1050) OSErr err = noErr; int i; const char *home; @@ -399,71 +397,38 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); } } -#else - /* 10.5 provides ability to retrieve Finder favorite places */ - UInt32 seed; - OSErr err = noErr; - CFArrayRef pathesArray; - LSSharedFileListRef list; - LSSharedFileListItemRef itemRef; - CFIndex i, pathesCount; - CFURLRef cfURL = NULL; - CFStringRef pathString = NULL; +#else /* OSX 10.6+ */ + /* Get mounted volumes better method OSX 10.6 and higher, see: */ + /*https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFURLRef/Reference/reference.html*/ + /* we get all volumes sorted including network and do not relay on user-defined finder visibility, less confusing */ - /* First get local mounted volumes */ - list = LSSharedFileListCreate(NULL, kLSSharedFileListFavoriteVolumes, NULL); - pathesArray = LSSharedFileListCopySnapshot(list, &seed); - pathesCount = CFArrayGetCount(pathesArray); + CFURLRef cfURL = NULL; + CFURLEnumeratorResult result = kCFURLEnumeratorSuccess; + CFURLEnumeratorRef volEnum = CFURLEnumeratorCreateForMountedVolumes(NULL, kCFURLEnumeratorSkipInvisibles, NULL); - for (i = 0; i < pathesCount; i++) { - itemRef = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(pathesArray, i); - - err = LSSharedFileListItemResolve(itemRef, - kLSSharedFileListNoUserInteraction | - kLSSharedFileListDoNotMountVolumes, - &cfURL, NULL); - if (err != noErr) - continue; - - pathString = CFURLCopyFileSystemPath(cfURL, kCFURLPOSIXPathStyle); - - if (!CFStringGetCString(pathString, line, sizeof(line), kCFStringEncodingASCII)) + while (result != kCFURLEnumeratorEnd) { + unsigned char defPath[FILE_MAX]; + + result = CFURLEnumeratorGetNextURL(volEnum, &cfURL, NULL); + if (result != kCFURLEnumeratorSuccess) continue; - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, line, FS_INSERT_SORTED); - CFRelease(pathString); - CFRelease(cfURL); + CFURLGetFileSystemRepresentation(cfURL, false, (UInt8 *)defPath, FILE_MAX); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)defPath, FS_INSERT_SORTED); } - CFRelease(pathesArray); - CFRelease(list); - - /* Then get network volumes */ - err = noErr; - for (i = 1; err != nsvErr; i++) { - FSRef dir; - FSVolumeRefNum volRefNum; - struct GetVolParmsInfoBuffer volParmsBuffer; - unsigned char path[FILE_MAX]; - - err = FSGetVolumeInfo(kFSInvalidVolumeRefNum, i, &volRefNum, kFSVolInfoNone, NULL, NULL, &dir); - if (err != noErr) - continue; - - err = FSGetVolumeParms(volRefNum, &volParmsBuffer, sizeof(volParmsBuffer)); - if ((err != noErr) || (volParmsBuffer.vMServerAdr == 0)) /* Exclude local devices */ - continue; - - - FSRefMakePath(&dir, path, FILE_MAX); - if (strcmp((char *)path, "/home") && strcmp((char *)path, "/net")) { - /* /net and /home are meaningless on OSX, home folders are stored in /Users */ - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)path, FS_INSERT_SORTED); - } - } + CFRelease(volEnum); /* Finally get user favorite places */ if (read_bookmarks) { + UInt32 seed; + OSErr err = noErr; + CFArrayRef pathesArray; + LSSharedFileListRef list; + LSSharedFileListItemRef itemRef; + CFIndex i, pathesCount; + CFURLRef cfURL = NULL; + CFStringRef pathString = NULL; list = LSSharedFileListCreate(NULL, kLSSharedFileListFavoriteItems, NULL); pathesArray = LSSharedFileListCopySnapshot(list, &seed); pathesCount = CFArrayGetCount(pathesArray); @@ -491,7 +456,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) CFRelease(pathesArray); CFRelease(list); } -#endif /* OSX 10.5+ */ +#endif /* OSX 10.6+ */ } #else /* unix */ diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 1a8565a58b1..0bc2d073e0a 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -396,6 +396,7 @@ static void file_operatortypes(void) WM_operatortype_append(FILE_OT_rename); WM_operatortype_append(FILE_OT_smoothscroll); WM_operatortype_append(FILE_OT_directory); + WM_operatortype_append(FILE_OT_filename); } /* NOTE: do not add .blend file reading on this level */ diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index 23c39a5e99a..e7c98437b9f 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -206,7 +206,7 @@ static void draw_fcurve_handle_control(float x, float y, float xscale, float ysc } /* helper func - draw handle vertices only for an F-Curve (if it is not protected) */ -static void draw_fcurve_vertices_handles(FCurve *fcu, SpaceIpo *sipo, View2D *v2d, short sel, short sel_handle_only) +static void draw_fcurve_vertices_handles(FCurve *fcu, SpaceIpo *sipo, View2D *v2d, short sel, short sel_handle_only, float units_scale) { BezTriple *bezt = fcu->bezt; BezTriple *prevbezt = NULL; @@ -216,6 +216,9 @@ static void draw_fcurve_vertices_handles(FCurve *fcu, SpaceIpo *sipo, View2D *v2 /* get view settings */ hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE) * U.pixelsize; UI_view2d_getscale(v2d, &xscale, &yscale); + + /* Compensate OGL scale sued for unit mapping, so circle will be circle, not ellipse */ + yscale *= units_scale; /* set handle color */ if (sel) UI_ThemeColor(TH_HANDLE_VERTEX_SELECT); @@ -271,7 +274,7 @@ static void set_fcurve_vertex_color(FCurve *fcu, short sel) } -static void draw_fcurve_vertices(SpaceIpo *sipo, ARegion *ar, FCurve *fcu, short do_handles, short sel_handle_only) +static void draw_fcurve_vertices(SpaceIpo *sipo, ARegion *ar, FCurve *fcu, short do_handles, short sel_handle_only, float units_scale) { View2D *v2d = &ar->v2d; @@ -287,10 +290,10 @@ static void draw_fcurve_vertices(SpaceIpo *sipo, ARegion *ar, FCurve *fcu, short /* draw the two handles first (if they're shown, the curve doesn't have just a single keyframe, and the curve is being edited) */ if (do_handles) { set_fcurve_vertex_color(fcu, 0); - draw_fcurve_vertices_handles(fcu, sipo, v2d, 0, sel_handle_only); + draw_fcurve_vertices_handles(fcu, sipo, v2d, 0, sel_handle_only, units_scale); set_fcurve_vertex_color(fcu, 1); - draw_fcurve_vertices_handles(fcu, sipo, v2d, 1, sel_handle_only); + draw_fcurve_vertices_handles(fcu, sipo, v2d, 1, sel_handle_only, units_scale); } /* draw keyframes over the handles */ @@ -487,6 +490,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d float stime, etime; float unitFac; float dx, dy; + short mapping_flag = ANIM_get_normalization_flags(ac); /* when opening a blend file on a different sized screen or while dragging the toolbar this can happen * best just bail out in this case */ @@ -500,7 +504,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d fcu->driver = NULL; /* compute unit correction factor */ - unitFac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, 0); + unitFac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag); /* Note about sampling frequency: * Ideally, this is chosen such that we have 1-2 pixels = 1 segment @@ -547,11 +551,15 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie FPoint *fpt = prevfpt + 1; float fac, v[2]; int b = fcu->totvert - 1; - - glBegin(GL_LINE_STRIP); - + float unit_scale; + short mapping_flag = ANIM_get_normalization_flags(ac); + /* apply unit mapping */ - ANIM_unit_mapping_apply_fcurve(ac->scene, id, fcu, 0); + glPushMatrix(); + unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag); + glScalef(1.0f, unit_scale, 1.0f); + + glBegin(GL_LINE_STRIP); /* extrapolate to left? - left-side of view comes before first keyframe? */ if (prevfpt->vec[0] > v2d->cur.xmin) { @@ -611,10 +619,8 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie glVertex2fv(v); } - /* unapply unit mapping */ - ANIM_unit_mapping_apply_fcurve(ac->scene, id, fcu, ANIM_UNITCONV_RESTORE); - glEnd(); + glPopMatrix(); } /* helper func - draw one repeat of an F-Curve */ @@ -627,11 +633,15 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2 float fac = 0.0f; int b = fcu->totvert - 1; int resol; - - glBegin(GL_LINE_STRIP); - + float unit_scale; + short mapping_flag = ANIM_get_normalization_flags(ac); + /* apply unit mapping */ - ANIM_unit_mapping_apply_fcurve(ac->scene, id, fcu, 0); + glPushMatrix(); + unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag); + glScalef(1.0f, unit_scale, 1.0f); + + glBegin(GL_LINE_STRIP); /* extrapolate to left? */ if (prevbezt->vec[1][0] > v2d->cur.xmin) { @@ -766,10 +776,8 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2 glVertex2fv(v1); } - /* unapply unit mapping */ - ANIM_unit_mapping_apply_fcurve(ac->scene, id, fcu, ANIM_UNITCONV_RESTORE); - glEnd(); + glPopMatrix(); } /* Debugging -------------------------------- */ @@ -783,7 +791,8 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu) { ChannelDriver *driver = fcu->driver; View2D *v2d = &ac->ar->v2d; - float unitfac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, false); + short mapping_flag = ANIM_get_normalization_flags(ac); + float unitfac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag); /* for now, only show when debugging driver... */ //if ((driver->flag & DRIVER_FLAG_SHOWDEBUG) == 0) @@ -1014,9 +1023,12 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid } } else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) { - /* apply unit mapping */ - ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, fcu, 0); - + short mapping_flag = ANIM_get_normalization_flags(ac); + float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag); + + glPushMatrix(); + glScalef(1.0f, unit_scale, 1.0f); + if (fcu->bezt) { int do_handles = draw_fcurve_handles_check(sipo, fcu); @@ -1027,15 +1039,14 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid glDisable(GL_BLEND); } - draw_fcurve_vertices(sipo, ar, fcu, do_handles, (sipo->flag & SIPO_SELVHANDLESONLY)); + draw_fcurve_vertices(sipo, ar, fcu, do_handles, (sipo->flag & SIPO_SELVHANDLESONLY), unit_scale); } else { /* samples: only draw two indicators at either end as indicators */ draw_fcurve_samples(sipo, ar, fcu); } - - /* unapply unit mapping */ - ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, fcu, ANIM_UNITCONV_RESTORE); + + glPopMatrix(); } } diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 274c06bf871..db13e2a4024 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -116,6 +116,8 @@ void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, floa /* get range */ if (calc_fcurve_bounds(fcu, &txmin, &txmax, &tymin, &tymax, do_sel_only, include_handles)) { + short mapping_flag = ANIM_get_normalization_flags(ac); + /* apply NLA scaling */ if (adt) { txmin = BKE_nla_tweakedit_remap(adt, txmin, NLATIME_CONVERT_MAP); @@ -123,7 +125,7 @@ void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, floa } /* apply unit corrections */ - unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, 0); + unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag); tymin *= unitFac; tymax *= unitFac; @@ -330,12 +332,14 @@ static void create_ghost_curves(bAnimContext *ac, int start, int end) FPoint *fpt; float unitFac; int cfra; - + SpaceIpo *sipo = (SpaceIpo *) ac->sl; + short mapping_flag = ANIM_get_normalization_flags(ac); + /* disable driver so that it don't muck up the sampling process */ fcu->driver = NULL; /* calculate unit-mapping factor */ - unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, 0); + unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag); /* create samples, but store them in a new curve * - we cannot use fcurve_store_samples() as that will only overwrite the original curve @@ -578,6 +582,8 @@ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op) * keyframes if these will be visible after doing so... */ if (fcurve_is_keyframable(fcu)) { + short mapping_flag = ANIM_get_normalization_flags(&ac); + /* get frame and value from props */ frame = RNA_float_get(op->ptr, "frame"); val = RNA_float_get(op->ptr, "value"); @@ -587,7 +593,7 @@ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op) frame = BKE_nla_tweakedit_remap(adt, frame, NLATIME_CONVERT_UNMAP); /* apply inverse unit-mapping to value to get correct value for F-Curves */ - val *= ANIM_unit_mapping_get_factor(ac.scene, ale->id, fcu, 1); + val *= ANIM_unit_mapping_get_factor(ac.scene, ale->id, fcu, mapping_flag | ANIM_UNITCONV_RESTORE); /* insert keyframe on the specified frame + value */ insert_vert_fcurve(fcu, frame, val, 0); @@ -1787,20 +1793,24 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op)) for (ale = anim_data.first; ale; ale = ale->next) { AnimData *adt = ANIM_nla_mapping_get(&ac, ale); - - /* apply unit corrections */ - ANIM_unit_mapping_apply_fcurve(ac.scene, ale->id, ale->key_data, ANIM_UNITCONV_ONLYKEYS); - + short mapping_flag = ANIM_get_normalization_flags(&ac); + KeyframeEditData current_ked; + float unit_scale = ANIM_unit_mapping_get_factor(ac.scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS); + + memset(¤t_ked, 0, sizeof(current_ked)); + if (adt) { ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); - ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_calc_average, NULL); + ANIM_fcurve_keyframes_loop(¤t_ked, ale->key_data, NULL, bezt_calc_average, NULL); ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); } else - ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_calc_average, NULL); - - /* unapply unit corrections */ - ANIM_unit_mapping_apply_fcurve(ac.scene, ale->id, ale->key_data, ANIM_UNITCONV_RESTORE | ANIM_UNITCONV_ONLYKEYS); + ANIM_fcurve_keyframes_loop(¤t_ked, ale->key_data, NULL, bezt_calc_average, NULL); + + ked.f1 += current_ked.f1; + ked.i1 += current_ked.i1; + ked.f2 += current_ked.f2 / unit_scale; + ked.i2 += current_ked.i2; } BLI_freelistN(&anim_data); @@ -1865,6 +1875,7 @@ static void snap_graph_keys(bAnimContext *ac, short mode) KeyframeEditData ked; KeyframeEditFunc edit_cb; + float cursor_value = 0.0f; /* filter data */ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); @@ -1881,16 +1892,17 @@ static void snap_graph_keys(bAnimContext *ac, short mode) } else if (mode == GRAPHKEYS_SNAP_VALUE) { SpaceIpo *sipo = (SpaceIpo *)ac->sl; - ked.f1 = (sipo) ? sipo->cursorVal : 0.0f; + cursor_value = (sipo) ? sipo->cursorVal : 0.0f; } /* snap keyframes */ for (ale = anim_data.first; ale; ale = ale->next) { AnimData *adt = ANIM_nla_mapping_get(ac, ale); - - /* apply unit corrections */ - ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, ale->key_data, 0); - + short mapping_flag = ANIM_get_normalization_flags(ac); + float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag); + + ked.f1 = cursor_value / unit_scale; + if (adt) { ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve); @@ -1898,9 +1910,6 @@ static void snap_graph_keys(bAnimContext *ac, short mode) } else ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve); - - /* apply unit corrections */ - ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, ale->key_data, ANIM_UNITCONV_RESTORE); } BLI_freelistN(&anim_data); @@ -1977,7 +1986,8 @@ static void mirror_graph_keys(bAnimContext *ac, short mode) KeyframeEditData ked; KeyframeEditFunc edit_cb; - + float cursor_value = 0.0f; + /* get beztriple editing callbacks */ edit_cb = ANIM_editkeyframes_mirror(mode); @@ -2000,7 +2010,7 @@ static void mirror_graph_keys(bAnimContext *ac, short mode) } else if (mode == GRAPHKEYS_MIRROR_VALUE) { SpaceIpo *sipo = (SpaceIpo *)ac->sl; - ked.f1 = (sipo) ? sipo->cursorVal : 0.0f; + cursor_value = (sipo) ? sipo->cursorVal : 0.0f; } /* filter data */ @@ -2010,10 +2020,12 @@ static void mirror_graph_keys(bAnimContext *ac, short mode) /* mirror keyframes */ for (ale = anim_data.first; ale; ale = ale->next) { AnimData *adt = ANIM_nla_mapping_get(ac, ale); - + short mapping_flag = ANIM_get_normalization_flags(ac); + float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS); + /* apply unit corrections */ - ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, ale->key_data, ANIM_UNITCONV_ONLYKEYS); - + ked.f1 = cursor_value * unit_scale; + if (adt) { ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve); @@ -2021,9 +2033,6 @@ static void mirror_graph_keys(bAnimContext *ac, short mode) } else ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve); - - /* unapply unit corrections */ - ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, ale->key_data, ANIM_UNITCONV_ONLYKEYS | ANIM_UNITCONV_RESTORE); } BLI_freelistN(&anim_data); diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index e2bc88cf0eb..74114f8ca9d 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -254,11 +254,9 @@ void ED_operatormacros_graph(void) ot = WM_operatortype_append_macro("GRAPH_OT_duplicate_move", "Duplicate", "Make a copy of all selected keyframes and move them", OPTYPE_UNDO | OPTYPE_REGISTER); - if (ot) { - WM_operatortype_macro_define(ot, "GRAPH_OT_duplicate"); - otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_transform"); - RNA_enum_set(otmacro->ptr, "mode", TFM_TIME_DUPLICATE); - } + WM_operatortype_macro_define(ot, "GRAPH_OT_duplicate"); + otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_transform"); + RNA_enum_set(otmacro->ptr, "mode", TFM_TIME_DUPLICATE); } @@ -279,33 +277,38 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) /* graph_select.c - selection tools */ - /* click-select */ + /* click-select: keyframe (replace) */ kmi = WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, 0, 0); RNA_boolean_set(kmi->ptr, "extend", FALSE); RNA_boolean_set(kmi->ptr, "curves", FALSE); RNA_boolean_set(kmi->ptr, "column", FALSE); + /* click-select: all keyframes on same frame (replace) */ kmi = WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT, 0); RNA_boolean_set(kmi->ptr, "extend", FALSE); RNA_boolean_set(kmi->ptr, "curves", FALSE); RNA_boolean_set(kmi->ptr, "column", TRUE); + /* click-select: keyframe (add) */ kmi = WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "extend", TRUE); RNA_boolean_set(kmi->ptr, "curves", FALSE); RNA_boolean_set(kmi->ptr, "column", FALSE); + /* click-select: all keyframes on same frame (add) */ kmi = WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT | KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "extend", TRUE); RNA_boolean_set(kmi->ptr, "curves", FALSE); RNA_boolean_set(kmi->ptr, "column", TRUE); + /* click-select: all keyframes in same curve (replace) */ kmi = WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL | KM_ALT, 0); RNA_boolean_set(kmi->ptr, "extend", FALSE); RNA_boolean_set(kmi->ptr, "curves", TRUE); RNA_boolean_set(kmi->ptr, "column", FALSE); + /* click-select: all keyframes in same curve (add) */ kmi = WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL | KM_ALT | KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "extend", TRUE); RNA_boolean_set(kmi->ptr, "curves", TRUE); RNA_boolean_set(kmi->ptr, "column", FALSE); - /* select left/right */ + /* click-select left/right */ kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); RNA_boolean_set(kmi->ptr, "extend", FALSE); RNA_enum_set(kmi->ptr, "mode", GRAPHKEYS_LRSEL_TEST); diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index d87bd9a5077..d0dcaf91e77 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -227,7 +227,7 @@ static void borderselect_graphkeys(bAnimContext *ac, rcti rect, short mode, shor KeyframeEditData ked; KeyframeEditFunc ok_cb, select_cb; View2D *v2d = &ac->ar->v2d; - rctf rectf; + rctf rectf, scaled_rectf; /* convert mouse coordinates to frame ranges and channel coordinates corrected for view pan/zoom */ UI_view2d_region_to_view(v2d, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin); @@ -243,7 +243,7 @@ static void borderselect_graphkeys(bAnimContext *ac, rcti rect, short mode, shor /* init editing data */ memset(&ked, 0, sizeof(KeyframeEditData)); - ked.data = &rectf; + ked.data = &scaled_rectf; /* treat handles separately? */ if (incl_handles) { @@ -252,21 +252,26 @@ static void borderselect_graphkeys(bAnimContext *ac, rcti rect, short mode, shor } else mapping_flag = ANIM_UNITCONV_ONLYKEYS; - + + mapping_flag |= ANIM_get_normalization_flags(ac); + /* loop over data, doing border select */ for (ale = anim_data.first; ale; ale = ale->next) { AnimData *adt = ANIM_nla_mapping_get(ac, ale); FCurve *fcu = (FCurve *)ale->key_data; - - /* apply unit corrections */ - ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, ale->key_data, mapping_flag); - + float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, 0); + /* apply NLA mapping to all the keyframes, since it's easier than trying to * guess when a callback might use something different */ if (adt) ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, incl_handles == 0); - + + scaled_rectf.xmin = rectf.xmin; + scaled_rectf.xmax = rectf.xmax; + scaled_rectf.ymin = rectf.ymin / unit_scale; + scaled_rectf.ymax = rectf.ymax / unit_scale; + /* set horizontal range (if applicable) * NOTE: these values are only used for x-range and y-range but not region * (which uses ked.data, i.e. rectf) @@ -296,9 +301,6 @@ static void borderselect_graphkeys(bAnimContext *ac, rcti rect, short mode, shor /* un-apply NLA mapping from all the keyframes */ if (adt) ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, incl_handles == 0); - - /* unapply unit corrections */ - ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, ale->key_data, ANIM_UNITCONV_RESTORE | mapping_flag); } /* cleanup */ @@ -936,7 +938,7 @@ static int fcurve_handle_sel_check(SpaceIpo *sipo, BezTriple *bezt) /* check if the given vertex is within bounds or not */ // TODO: should we return if we hit something? -static void nearest_fcurve_vert_store(ListBase *matches, View2D *v2d, FCurve *fcu, BezTriple *bezt, FPoint *fpt, short hpoint, const int mval[2]) +static void nearest_fcurve_vert_store(ListBase *matches, View2D *v2d, FCurve *fcu, BezTriple *bezt, FPoint *fpt, short hpoint, const int mval[2], float unit_scale) { /* Keyframes or Samples? */ if (bezt) { @@ -947,7 +949,7 @@ static void nearest_fcurve_vert_store(ListBase *matches, View2D *v2d, FCurve *fc * needed to access the relevant vertex coordinates in the 3x3 * 'vec' matrix */ - UI_view2d_view_to_region(v2d, bezt->vec[hpoint + 1][0], bezt->vec[hpoint + 1][1], &screen_co[0], &screen_co[1]); + UI_view2d_view_to_region(v2d, bezt->vec[hpoint + 1][0], bezt->vec[hpoint + 1][1] * unit_scale, &screen_co[0], &screen_co[1]); /* check if distance from mouse cursor to vert in screen space is within tolerance */ // XXX: inlined distance calculation, since we cannot do this on ints using the math lib... @@ -996,6 +998,7 @@ static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], L SpaceIpo *sipo = (SpaceIpo *)ac->sl; View2D *v2d = &ac->ar->v2d; + short mapping_flag = 0; /* get curves to search through * - if the option to only show keyframes that belong to selected F-Curves is enabled, @@ -1004,37 +1007,36 @@ static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], L filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); if (sipo->flag & SIPO_SELCUVERTSONLY) // FIXME: this should really be check for by the filtering code... filter |= ANIMFILTER_SEL; + mapping_flag |= ANIM_get_normalization_flags(ac); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); for (ale = anim_data.first; ale; ale = ale->next) { FCurve *fcu = (FCurve *)ale->key_data; AnimData *adt = ANIM_nla_mapping_get(ac, ale); - - /* apply unit corrections */ - ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, ale->key_data, 0); - + float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag); + /* apply NLA mapping to all the keyframes */ if (adt) ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0); - + if (fcu->bezt) { BezTriple *bezt1 = fcu->bezt, *prevbezt = NULL; int i; for (i = 0; i < fcu->totvert; i++, prevbezt = bezt1, bezt1++) { /* keyframe */ - nearest_fcurve_vert_store(matches, v2d, fcu, bezt1, NULL, NEAREST_HANDLE_KEY, mval); + nearest_fcurve_vert_store(matches, v2d, fcu, bezt1, NULL, NEAREST_HANDLE_KEY, mval, unit_scale); /* handles - only do them if they're visible */ if (fcurve_handle_sel_check(sipo, bezt1) && (fcu->totvert > 1)) { /* first handle only visible if previous segment had handles */ if ((!prevbezt && (bezt1->ipo == BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) { - nearest_fcurve_vert_store(matches, v2d, fcu, bezt1, NULL, NEAREST_HANDLE_LEFT, mval); + nearest_fcurve_vert_store(matches, v2d, fcu, bezt1, NULL, NEAREST_HANDLE_LEFT, mval, unit_scale); } /* second handle only visible if this segment is bezier */ if (bezt1->ipo == BEZT_IPO_BEZ) { - nearest_fcurve_vert_store(matches, v2d, fcu, bezt1, NULL, NEAREST_HANDLE_RIGHT, mval); + nearest_fcurve_vert_store(matches, v2d, fcu, bezt1, NULL, NEAREST_HANDLE_RIGHT, mval, unit_scale); } } } @@ -1047,9 +1049,6 @@ static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], L /* un-apply NLA mapping from all the keyframes */ if (adt) ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0); - - /* unapply unit corrections */ - ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, ale->key_data, ANIM_UNITCONV_RESTORE); } /* free channels */ @@ -1365,7 +1364,8 @@ void GRAPH_OT_clickselect(wmOperatorType *ot) ot->flag = OPTYPE_UNDO; /* properties */ - prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY + prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", + "Toggle keyframe selection instead of leaving newly selected keyframes only"); // SHIFTKEY RNA_def_property_flag(prop, PROP_SKIP_SAVE); prop = RNA_def_boolean(ot->srna, "column", 0, "Column Select", diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 710d5c8cd81..b7d3407b826 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -256,7 +256,7 @@ static void image_view_pan_init(bContext *C, wmOperator *op, const wmEvent *even WM_event_add_modal_handler(C, op); } -static void image_view_pan_exit(bContext *C, wmOperator *op, int cancel) +static void image_view_pan_exit(bContext *C, wmOperator *op, bool cancel) { SpaceImage *sima = CTX_wm_space_image(C); ViewPanData *vpd = op->customdata; @@ -330,7 +330,7 @@ static int image_view_pan_modal(bContext *C, wmOperator *op, const wmEvent *even break; default: if (event->type == vpd->event_type && event->val == KM_RELEASE) { - image_view_pan_exit(C, op, 0); + image_view_pan_exit(C, op, false); return OPERATOR_FINISHED; } break; @@ -339,10 +339,9 @@ static int image_view_pan_modal(bContext *C, wmOperator *op, const wmEvent *even return OPERATOR_RUNNING_MODAL; } -static int image_view_pan_cancel(bContext *C, wmOperator *op) +static void image_view_pan_cancel(bContext *C, wmOperator *op) { - image_view_pan_exit(C, op, 1); - return OPERATOR_CANCELLED; + image_view_pan_exit(C, op, true); } void IMAGE_OT_view_pan(wmOperatorType *ot) @@ -412,7 +411,7 @@ static void image_view_zoom_init(bContext *C, wmOperator *op, const wmEvent *eve WM_event_add_modal_handler(C, op); } -static void image_view_zoom_exit(bContext *C, wmOperator *op, int cancel) +static void image_view_zoom_exit(bContext *C, wmOperator *op, bool cancel) { SpaceImage *sima = CTX_wm_space_image(C); ViewZoomData *vpd = op->customdata; @@ -547,17 +546,16 @@ static int image_view_zoom_modal(bContext *C, wmOperator *op, const wmEvent *eve image_zoom_apply(vpd, op, event->x, event->y, U.viewzoom, (U.uiflag & USER_ZOOM_INVERT) != 0); } else if (event_code == VIEW_CONFIRM) { - image_view_zoom_exit(C, op, 0); + image_view_zoom_exit(C, op, false); return OPERATOR_FINISHED; } return OPERATOR_RUNNING_MODAL; } -static int image_view_zoom_cancel(bContext *C, wmOperator *op) +static void image_view_zoom_cancel(bContext *C, wmOperator *op) { - image_view_zoom_exit(C, op, 1); - return OPERATOR_CANCELLED; + image_view_zoom_exit(C, op, true); } void IMAGE_OT_view_zoom(wmOperatorType *ot) @@ -921,11 +919,10 @@ static void image_open_init(bContext *C, wmOperator *op) uiIDContextProperty(C, &pprop->ptr, &pprop->prop); } -static int image_open_cancel(bContext *UNUSED(C), wmOperator *op) +static void image_open_cancel(bContext *UNUSED(C), wmOperator *op) { MEM_freeN(op->customdata); op->customdata = NULL; - return OPERATOR_CANCELLED; } static int image_open_exec(bContext *C, wmOperator *op) @@ -1505,11 +1502,9 @@ static int image_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS return OPERATOR_RUNNING_MODAL; } -static int image_save_as_cancel(bContext *UNUSED(C), wmOperator *op) +static void image_save_as_cancel(bContext *UNUSED(C), wmOperator *op) { image_save_as_free(op); - - return OPERATOR_CANCELLED; } static bool image_save_as_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) @@ -1905,7 +1900,7 @@ static int image_invert_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - ibuf->userflags |= IB_BITMAPDIRTY; + ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID; if (ibuf->mipmap[0]) ibuf->userflags |= IB_MIPMAP_INVALID; @@ -2358,10 +2353,9 @@ static int image_sample_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static int image_sample_cancel(bContext *C, wmOperator *op) +static void image_sample_cancel(bContext *C, wmOperator *op) { image_sample_exit(C, op); - return OPERATOR_CANCELLED; } void IMAGE_OT_sample(wmOperatorType *ot) @@ -2625,7 +2619,7 @@ static int image_record_composite_modal(bContext *C, wmOperator *op, const wmEve return OPERATOR_RUNNING_MODAL; } -static int image_record_composite_cancel(bContext *C, wmOperator *op) +static void image_record_composite_cancel(bContext *C, wmOperator *op) { image_record_composite_exit(C, op); return OPERATOR_CANCELLED; diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 7b20af340ae..2ba9123b30b 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -56,6 +56,7 @@ #include "ED_mask.h" #include "ED_mesh.h" #include "ED_node.h" +#include "ED_render.h" #include "ED_space_api.h" #include "ED_screen.h" #include "ED_uvedit.h" @@ -653,7 +654,16 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) glClear(GL_COLOR_BUFFER_BIT); /* put scene context variable in iuser */ - sima->iuser.scene = scene; + if (sima->image && sima->image->type == IMA_TYPE_R_RESULT) { + /* for render result, try to use the currently rendering scene */ + Scene *render_scene = ED_render_job_get_scene(C); + if (render_scene) + sima->iuser.scene = render_scene; + else + sima->iuser.scene = scene; + } + else + sima->iuser.scene = scene; /* we set view2d from own zoom and offset each time */ image_main_area_set_view2d(sima, ar); diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c index 07f4b64d187..96e0de17918 100644 --- a/source/blender/editors/space_info/space_info.c +++ b/source/blender/editors/space_info/space_info.c @@ -220,6 +220,9 @@ static void info_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "INFO_OT_report_delete", XKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "INFO_OT_report_delete", DELKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "INFO_OT_report_copy", CKEY, KM_PRESS, KM_CTRL, 0); +#ifdef __APPLE__ + WM_keymap_add_item(keymap, "INFO_OT_report_copy", CKEY, KM_PRESS, KM_OSKEY, 0); +#endif } /* add handlers, stuff you only do once or on area/region changes */ @@ -327,7 +330,7 @@ void ED_spacetype_info(void) /* regions: main window */ art = MEM_callocN(sizeof(ARegionType), "spacetype info region"); art->regionid = RGN_TYPE_WINDOW; - art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D; + art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES; art->init = info_main_area_init; art->draw = info_main_area_draw; diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index b4c52a5b1ca..c9a86547984 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -638,53 +638,13 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View { AnimData *adt = ale->adt; - short indent = 0, offset = 0, sel = 0, group = 0, nonSolo = 0; - int expand = -1, protect = -1, special = -1, mute = -1; + short indent = 0, offset = 0, sel = 0, group = 0; + int special = -1; char name[128]; short do_draw = FALSE; /* determine what needs to be drawn */ switch (ale->type) { - case ANIMTYPE_NLATRACK: /* NLA Track */ - { - NlaTrack *nlt = (NlaTrack *)ale->data; - - /* 'solo' as the 'special' button? */ - if (nlt->flag & NLATRACK_SOLO) - special = ICON_SOLO_ON; - else - special = ICON_SOLO_OFF; - - /* if this track is active and we're tweaking it, don't draw these toggles */ - // TODO: need a special macro for this... - if (((nlt->flag & NLATRACK_ACTIVE) && (nlt->flag & NLATRACK_DISABLED)) == 0) { - if (nlt->flag & NLATRACK_MUTED) - mute = ICON_MUTE_IPO_ON; - else - mute = ICON_MUTE_IPO_OFF; - - if (EDITABLE_NLT(nlt)) - protect = ICON_UNLOCKED; - else - protect = ICON_LOCKED; - } - - /* is track enabled for solo drawing? */ - if ((adt) && (adt->flag & ADT_NLA_SOLO_TRACK)) { - if ((nlt->flag & NLATRACK_SOLO) == 0) { - /* tag for special non-solo handling; also hide the mute toggles */ - nonSolo = 1; - mute = 0; - } - } - - sel = SEL_NLT(nlt); - BLI_strncpy(name, nlt->name, sizeof(name)); - - /* draw manually still */ - do_draw = TRUE; - break; - } case ANIMTYPE_NLAACTION: /* NLA Action-Line */ { bAction *act = (bAction *)ale->data; @@ -700,7 +660,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View break; } default: /* handled by standard channel-drawing API */ - // draw backdrops only... + /* (draw backdrops only...) */ ANIM_channel_draw(ac, ale, yminc, ymaxc); break; } @@ -783,25 +743,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View /* clear group value, otherwise we cause errors... */ group = 0; } - else { - /* NLA tracks - darker color if not solo track when we're showing solo */ - UI_ThemeColorShade(TH_HEADER, ((nonSolo == 0) ? 20 : -20)); - - indent += group; - offset += 0.35f * U.widget_unit * indent; - glBegin(GL_QUADS); - glVertex2f(x + offset, yminc); - glVertex2f(x + offset, ymaxc); - glVertex2f((float)v2d->cur.xmax, ymaxc); - glVertex2f((float)v2d->cur.xmax, yminc); - glEnd(); - } - /* draw expand/collapse triangle */ - if (expand > 0) { - UI_icon_draw(x + offset, ydatac, expand); - offset += 0.85f * U.widget_unit; - } /* draw special icon indicating certain data-types */ if (special > -1) { @@ -826,17 +768,6 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); - /* draw protect 'lock' */ - if (protect > -1) { - offset = 0.8f * U.widget_unit; - UI_icon_draw((float)(v2d->cur.xmax - offset), ydatac, protect); - } - - /* draw mute 'eye' */ - if (mute > -1) { - offset += 0.8f * U.widget_unit; - UI_icon_draw((float)(v2d->cur.xmax - offset), ydatac, mute); - } /* draw NLA-action line 'status-icons' - only when there's an action */ if ((ale->type == ANIMTYPE_NLAACTION) && (ale->data)) { diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c index 4d4f27cf1ad..d0ba33358e4 100644 --- a/source/blender/editors/space_nla/space_nla.c +++ b/source/blender/editors/space_nla/space_nla.c @@ -544,7 +544,7 @@ void ED_spacetype_nla(void) art = MEM_callocN(sizeof(ARegionType), "spacetype nla region"); art->regionid = RGN_TYPE_CHANNELS; art->prefsizex = 200; - art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D; + art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES; art->init = nla_channel_area_init; art->draw = nla_channel_area_draw; diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index ba28f502349..b33c3d6c228 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -384,19 +384,21 @@ static void node_draw_frame_prepare(const bContext *UNUSED(C), bNodeTree *ntree, node->totr = rect; } -static void node_draw_frame_label(bNode *node, const float aspect) +static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float aspect) { /* XXX font id is crap design */ const int fontid = UI_GetStyle()->widgetlabel.uifont_id; NodeFrame *data = (NodeFrame *)node->storage; rctf *rct = &node->totr; int color_id = node_get_colorid(node); - const char *label = nodeLabel(node); + char label[MAX_NAME]; /* XXX a bit hacky, should use separate align values for x and y */ float width, ascender; float x, y; const int font_size = data->label_size / aspect; + nodeLabel(ntree, node, label, sizeof(label)); + BLF_enable(fontid, BLF_ASPECT); BLF_aspect(fontid, aspect, aspect, 1.0f); BLF_size(fontid, MIN2(24, font_size), U.dpi); /* clamp otherwise it can suck up a LOT of memory */ @@ -418,7 +420,7 @@ static void node_draw_frame_label(bNode *node, const float aspect) } static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode, - bNodeTree *UNUSED(ntree), bNode *node, bNodeInstanceKey UNUSED(key)) + bNodeTree *ntree, bNode *node, bNodeInstanceKey UNUSED(key)) { rctf *rct = &node->totr; int color_id = node_get_colorid(node); @@ -467,7 +469,7 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode, } /* label */ - node_draw_frame_label(node, snode->aspect); + node_draw_frame_label(ntree, node, snode->aspect); UI_ThemeClearColor(color_id); @@ -1444,7 +1446,7 @@ static void node_composit_buts_despeckle(uiLayout *layout, bContext *UNUSED(C), col = uiLayoutColumn(layout, FALSE); uiItemR(col, ptr, "threshold", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "threshold_neighbour", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "threshold_neighbor", 0, NULL, ICON_NONE); } static void node_composit_buts_diff_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) @@ -1633,7 +1635,7 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi else { col = uiLayoutColumn(layout, TRUE); - uiItemL(col, IFACE_("File Path:"), ICON_NONE); + uiItemL(col, IFACE_("File Subpath:"), ICON_NONE); row = uiLayoutRow(col, FALSE); uiItemR(row, &active_input_ptr, "path", 0, "", ICON_NONE); uiItemFullO(row, "NODE_OT_output_file_remove_active_socket", "", diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 65eb75f8523..6f2f8dee105 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -72,6 +72,11 @@ /* XXX interface.h */ extern void ui_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int select); +float ED_node_grid_size(void) +{ + return U.widget_unit; +} + void ED_node_tree_update(const bContext *C) { SpaceNode *snode = CTX_wm_space_node(C); @@ -863,7 +868,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN UI_ThemeColor(TH_TEXT); #endif - BLI_strncpy(showname, nodeLabel(node), sizeof(showname)); + nodeLabel(ntree, node, showname, sizeof(showname)); //if (node->flag & NODE_MUTED) // BLI_snprintf(showname, sizeof(showname), "[%s]", showname); /* XXX - don't print into self! */ @@ -1030,8 +1035,8 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b UI_ThemeColor(TH_TEXT); if (node->miniwidth > 0.0f) { - BLI_strncpy(showname, nodeLabel(node), sizeof(showname)); - + nodeLabel(ntree, node, showname, sizeof(showname)); + //if (node->flag & NODE_MUTED) // BLI_snprintf(showname, sizeof(showname), "[%s]", showname); /* XXX - don't print into self! */ @@ -1325,7 +1330,7 @@ void drawnodespace(const bContext *C, ARegion *ar) snode_setup_v2d(snode, ar, center); /* grid, uses theme color based on node path depth */ - UI_view2d_multi_grid_draw(v2d, (depth > 0 ? TH_NODE_GROUP : TH_BACK), U.widget_unit, 5, 2); + UI_view2d_multi_grid_draw(v2d, (depth > 0 ? TH_NODE_GROUP : TH_BACK), ED_node_grid_size(), NODE_GRID_STEPS, 2); /* backdrop */ draw_nodespace_back_pix(C, ar, snode, path->parent_key); @@ -1350,7 +1355,7 @@ void drawnodespace(const bContext *C, ARegion *ar) } else { /* default grid */ - UI_view2d_multi_grid_draw(v2d, TH_BACK, U.widget_unit, 5, 2); + UI_view2d_multi_grid_draw(v2d, TH_BACK, ED_node_grid_size(), NODE_GRID_STEPS, 2); /* backdrop */ draw_nodespace_back_pix(C, ar, snode, NODE_INSTANCE_KEY_NONE); diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 1d93fe65c09..f58bc83e5d2 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -859,7 +859,7 @@ static void node_resize_init(bContext *C, wmOperator *op, const wmEvent *UNUSED( WM_event_add_modal_handler(C, op); } -static void node_resize_exit(bContext *C, wmOperator *op, int UNUSED(cancel)) +static void node_resize_exit(bContext *C, wmOperator *op, bool UNUSED(cancel)) { WM_cursor_modal_restore(CTX_wm_window(C)); @@ -961,7 +961,7 @@ static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event) case MIDDLEMOUSE: case RIGHTMOUSE: - node_resize_exit(C, op, 0); + node_resize_exit(C, op, false); ED_node_post_apply_transform(C, snode->edittree); return OPERATOR_FINISHED; @@ -990,11 +990,9 @@ static int node_resize_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; } -static int node_resize_cancel(bContext *C, wmOperator *op) +static void node_resize_cancel(bContext *C, wmOperator *op) { - node_resize_exit(C, op, 1); - - return OPERATOR_CANCELLED; + node_resize_exit(C, op, true); } void NODE_OT_resize(wmOperatorType *ot) diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 176b81f9503..f598a13bea9 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -116,6 +116,7 @@ void NODE_OT_select_all(struct wmOperatorType *ot); void NODE_OT_select_linked_to(struct wmOperatorType *ot); void NODE_OT_select_linked_from(struct wmOperatorType *ot); void NODE_OT_select_border(struct wmOperatorType *ot); +void NODE_OT_select_circle(struct wmOperatorType *ot); void NODE_OT_select_lasso(struct wmOperatorType *ot); void NODE_OT_select_same_type(struct wmOperatorType *ot); void NODE_OT_select_same_type_step(struct wmOperatorType *ot); @@ -169,7 +170,6 @@ void NODE_OT_join(struct wmOperatorType *ot); void NODE_OT_attach(struct wmOperatorType *ot); void NODE_OT_detach(struct wmOperatorType *ot); -void NODE_OT_show_cyclic_dependencies(struct wmOperatorType *ot); void NODE_OT_link_viewer(struct wmOperatorType *ot); /* node_edit.c */ diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index f0d3deb24df..edd422b8148 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -56,6 +56,7 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_select_linked_to); WM_operatortype_append(NODE_OT_select_linked_from); WM_operatortype_append(NODE_OT_select_border); + WM_operatortype_append(NODE_OT_select_circle); WM_operatortype_append(NODE_OT_select_lasso); WM_operatortype_append(NODE_OT_select_same_type); WM_operatortype_append(NODE_OT_select_same_type_step); @@ -70,7 +71,6 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_preview_toggle); WM_operatortype_append(NODE_OT_options_toggle); WM_operatortype_append(NODE_OT_hide_socket_toggle); - WM_operatortype_append(NODE_OT_show_cyclic_dependencies); WM_operatortype_append(NODE_OT_node_copy_color); WM_operatortype_append(NODE_OT_duplicate); @@ -233,6 +233,8 @@ void node_keymap(struct wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "NODE_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT | KM_ALT, 0); RNA_boolean_set(kmi->ptr, "deselect", TRUE); + WM_keymap_add_item(keymap, "NODE_OT_select_circle", CKEY, KM_PRESS, 0, 0); + /* each of these falls through if not handled... */ kmi = WM_keymap_add_item(keymap, "NODE_OT_link", LEFTMOUSE, KM_PRESS, 0, 0); RNA_boolean_set(kmi->ptr, "detach", FALSE); @@ -272,8 +274,6 @@ void node_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "NODE_OT_preview_toggle", HKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "NODE_OT_hide_socket_toggle", HKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "NODE_OT_show_cyclic_dependencies", CKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "NODE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0); diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c index 4b5cc9e42b6..b50066560fb 100644 --- a/source/blender/editors/space_node/node_relationships.c +++ b/source/blender/editors/space_node/node_relationships.c @@ -395,38 +395,33 @@ void NODE_OT_link_viewer(wmOperatorType *ot) /* *************************** add link op ******************** */ -static void node_remove_extra_links(SpaceNode *snode, bNodeSocket *tsock, bNodeLink *link) +static void node_remove_extra_links(SpaceNode *snode, bNodeLink *link) { - bNodeLink *tlink; - bNodeSocket *sock; - - if (tsock && nodeCountSocketLinks(snode->edittree, link->tosock) > tsock->limit) { - - for (tlink = snode->edittree->links.first; tlink; tlink = tlink->next) { - if (link != tlink && tlink->tosock == link->tosock) - break; + bNodeTree *ntree = snode->edittree; + bNodeSocket *from = link->fromsock, *to = link->tosock; + int max_from = from->limit, max_to = to->limit; + int count_from = 1, count_to = 1; /* start at 1, link is included */ + bNodeLink *tlink, *tlink_next; + + for (tlink = ntree->links.first; tlink; tlink = tlink_next) { + tlink_next = tlink->next; + if (tlink == link) + continue; + + if (tlink && tlink->fromsock == from) { + ++count_from; + if (count_from > max_from) { + nodeRemLink(ntree, tlink); + tlink = NULL; + } } - if (tlink) { - /* try to move the existing link to the next available socket */ - if (tlink->tonode) { - /* is there a free input socket with the target type? */ - for (sock = tlink->tonode->inputs.first; sock; sock = sock->next) { - if (sock->type == tlink->tosock->type) - if (nodeCountSocketLinks(snode->edittree, sock) < sock->limit) - break; - } - if (sock) { - tlink->tosock = sock; - sock->flag &= ~SOCK_HIDDEN; - } - else { - nodeRemLink(snode->edittree, tlink); - } + + if (tlink && tlink->tosock == to) { + ++count_to; + if (count_to > max_to) { + nodeRemLink(ntree, tlink); + tlink = NULL; } - else - nodeRemLink(snode->edittree, tlink); - - snode->edittree->update |= NTREE_UPDATE_LINKS; } } } @@ -527,8 +522,7 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event) link->tonode->update |= NODE_UPDATE; /* we might need to remove a link */ - if (in_out == SOCK_OUT) - node_remove_extra_links(snode, link->tosock, link); + node_remove_extra_links(snode, link); } else nodeRemLink(ntree, link); @@ -669,7 +663,7 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; } -static int node_link_cancel(bContext *C, wmOperator *op) +static void node_link_cancel(bContext *C, wmOperator *op) { SpaceNode *snode = CTX_wm_space_node(C); bNodeLinkDrag *nldrag = op->customdata; @@ -678,8 +672,6 @@ static int node_link_cancel(bContext *C, wmOperator *op) BLI_freelistN(&nldrag->links); MEM_freeN(nldrag); - - return OPERATOR_CANCELLED; } void NODE_OT_link(wmOperatorType *ot) @@ -878,34 +870,6 @@ void NODE_OT_links_detach(wmOperatorType *ot) } -/* ****************** Show Cyclic Dependencies Operator ******************* */ - -static int node_show_cycles_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceNode *snode = CTX_wm_space_node(C); - - /* this is just a wrapper around this call... */ - ntreeUpdateTree(CTX_data_main(C), snode->nodetree); - snode_notify(C, snode); - - return OPERATOR_FINISHED; -} - -void NODE_OT_show_cyclic_dependencies(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Show Cyclic Dependencies"; - ot->description = "Sort the nodes and show the cyclic dependencies between the nodes"; - ot->idname = "NODE_OT_show_cyclic_dependencies"; - - /* callbacks */ - ot->exec = node_show_cycles_exec; - ot->poll = ED_operator_node_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - /* ****************** Set Parent ******************* */ static int node_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) @@ -1214,52 +1178,62 @@ void NODE_OT_detach(wmOperatorType *ot) /* prevent duplicate testing code below */ -static SpaceNode *ed_node_link_conditions(ScrArea *sa, bNode **select) +static bool ed_node_link_conditions(ScrArea *sa, bool test, SpaceNode **r_snode, bNode **r_select) { SpaceNode *snode = sa ? sa->spacedata.first : NULL; - bNode *node; + bNode *node, *select = NULL; bNodeLink *link; + *r_snode = snode; + *r_select = NULL; + /* no unlucky accidents */ - if (sa == NULL || sa->spacetype != SPACE_NODE) return NULL; + if (sa == NULL || sa->spacetype != SPACE_NODE) + return false; - *select = NULL; + if (!test) { + /* no need to look for a node */ + return true; + } for (node = snode->edittree->nodes.first; node; node = node->next) { if (node->flag & SELECT) { - if (*select) + if (select) break; else - *select = node; + select = node; } } /* only one selected */ - if (node || *select == NULL) return NULL; + if (node || select == NULL) + return false; /* correct node */ - if ((*select)->inputs.first == NULL || (*select)->outputs.first == NULL) return NULL; + if (select->inputs.first == NULL || select->outputs.first == NULL) + return false; /* test node for links */ for (link = snode->edittree->links.first; link; link = link->next) { if (nodeLinkIsHidden(link)) continue; - if (link->tonode == *select || link->fromnode == *select) - return NULL; + if (link->tonode == select || link->fromnode == select) + return false; } - return snode; + *r_select = select; + return true; } /* test == 0, clear all intersect flags */ void ED_node_link_intersect_test(ScrArea *sa, int test) { bNode *select; - SpaceNode *snode = ed_node_link_conditions(sa, &select); + SpaceNode *snode; bNodeLink *link, *selink = NULL; float mcoords[6][2]; - if (snode == NULL) return; + if (!ed_node_link_conditions(sa, test, &snode, &select)) return; /* clear flags */ for (link = snode->edittree->links.first; link; link = link->next) @@ -1334,11 +1308,11 @@ static bNodeSocket *socket_best_match(ListBase *sockets) void ED_node_link_insert(ScrArea *sa) { bNode *node, *select; - SpaceNode *snode = ed_node_link_conditions(sa, &select); + SpaceNode *snode; bNodeLink *link; bNodeSocket *sockto; - if (snode == NULL) return; + if (!ed_node_link_conditions(sa, true, &snode, &select)) return; /* get the link */ for (link = snode->edittree->links.first; link; link = link->next) @@ -1355,7 +1329,7 @@ void ED_node_link_insert(ScrArea *sa) link->tonode = select; link->tosock = best_input; - node_remove_extra_links(snode, link->tosock, link); + node_remove_extra_links(snode, link); link->flag &= ~NODE_LINKFLAG_HILITE; nodeAddLink(snode->edittree, select, best_output, node, sockto); diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index 958a3433337..2e3e747618b 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -514,6 +514,63 @@ void NODE_OT_select_border(wmOperatorType *ot) RNA_def_boolean(ot->srna, "tweak", 0, "Tweak", "Only activate when mouse is not over a node - useful for tweak gesture"); } +/* ****** Circle Select ****** */ + +static int node_circleselect_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + ARegion *ar = CTX_wm_region(C); + bNode *node; + + int x, y, radius, gesture_mode; + float offset[2]; + + float zoom = (float)(BLI_rcti_size_x(&ar->winrct)) / (float)(BLI_rctf_size_x(&ar->v2d.cur)); + + gesture_mode = RNA_int_get(op->ptr, "gesture_mode"); + + /* get operator properties */ + x = RNA_int_get(op->ptr, "x"); + y = RNA_int_get(op->ptr, "y"); + radius = RNA_int_get(op->ptr, "radius"); + + UI_view2d_region_to_view(&ar->v2d, x, y, &offset[0], &offset[1]); + + for (node = snode->edittree->nodes.first; node; node = node->next) { + if (BLI_rctf_isect_circle(&node->totr, offset, radius / zoom)) { + nodeSetSelected(node, (gesture_mode == GESTURE_MODAL_SELECT)); + } + } + + WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL); + + return OPERATOR_FINISHED; +} + +void NODE_OT_select_circle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Circle Select"; + ot->idname = "NODE_OT_select_circle"; + ot->description = "Use circle selection to select nodes"; + + /* api callbacks */ + ot->invoke = WM_gesture_circle_invoke; + ot->exec = node_circleselect_exec; + ot->modal = WM_gesture_circle_modal; + + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* rna */ + 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); +} + /* ****** Lasso Select ****** */ static int do_lasso_select_node(bContext *C, const int mcords[][2], short moves, short select) diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index a67a8791a64..f8eb0ede262 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -461,7 +461,7 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname) uiItemL(column, IFACE_(cname), ICON_NODE); but = block->buttons.last; - but->flag = UI_TEXT_LEFT; + but->drawflag = UI_BUT_TEXT_LEFT; first = 0; } @@ -471,7 +471,7 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname) cur_node_name = items[i].node_name; uiItemL(column, IFACE_(cur_node_name), ICON_NODE); but = block->buttons.last; - but->flag = UI_TEXT_LEFT; + but->drawflag = UI_BUT_TEXT_LEFT; } BLI_snprintf(name, UI_MAX_NAME_STR, " %s", IFACE_(items[i].socket_name)); @@ -528,7 +528,7 @@ static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_ if (sock->link) { uiItemL(column, IFACE_("Link"), ICON_NONE); but = block->buttons.last; - but->flag = UI_TEXT_LEFT; + but->drawflag = UI_BUT_TEXT_LEFT; but = uiDefBut(block, BUT, 0, IFACE_("Remove"), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Remove nodes connected to the input")); @@ -564,7 +564,8 @@ void uiTemplateNodeLink(uiLayout *layout, bNodeTree *ntree, bNode *node, bNodeSo but = uiDefIconMenuBut(block, ui_template_node_link_menu, NULL, ICON_NONE, 0, 0, UI_UNIT_X, UI_UNIT_Y, ""); but->type = MENU; - but->flag |= UI_TEXT_LEFT | UI_BUT_NODE_LINK; + but->drawflag |= UI_BUT_TEXT_LEFT; + but->flag |= UI_BUT_NODE_LINK; but->poin = (char *)but; but->func_argN = arg; @@ -654,7 +655,7 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree, uiItemL(row, label, ICON_NONE); bt = block->buttons.last; - bt->flag = UI_TEXT_LEFT; + bt->drawflag = UI_BUT_TEXT_LEFT; if (dependency_loop) { row = uiLayoutRow(split, FALSE); diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c index f889a8ec97b..ff441d63479 100644 --- a/source/blender/editors/space_node/node_view.c +++ b/source/blender/editors/space_node/node_view.c @@ -220,6 +220,7 @@ static int snode_bg_viewmove_modal(bContext *C, wmOperator *op, const wmEvent *e CLAMP(snode->yof, nvm->ymin, nvm->ymax); ED_region_tag_redraw(ar); + WM_main_add_notifier(NC_NODE | ND_DISPLAY, NULL); break; @@ -273,12 +274,10 @@ static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, const wmEvent * return OPERATOR_RUNNING_MODAL; } -static int snode_bg_viewmove_cancel(bContext *UNUSED(C), wmOperator *op) +static void snode_bg_viewmove_cancel(bContext *UNUSED(C), wmOperator *op) { MEM_freeN(op->customdata); op->customdata = NULL; - - return OPERATOR_CANCELLED; } void NODE_OT_backimage_move(wmOperatorType *ot) @@ -306,6 +305,7 @@ static int backimage_zoom_exec(bContext *C, wmOperator *op) snode->zoom *= fac; ED_region_tag_redraw(ar); + WM_main_add_notifier(NC_NODE | ND_DISPLAY, NULL); return OPERATOR_FINISHED; } @@ -363,6 +363,7 @@ static int backimage_fit_exec(bContext *C, wmOperator *UNUSED(op)) snode->yof = 0; ED_region_tag_redraw(ar); + WM_main_add_notifier(NC_NODE | ND_DISPLAY, NULL); return OPERATOR_FINISHED; } @@ -612,10 +613,9 @@ static int sample_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static int sample_cancel(bContext *C, wmOperator *op) +static void sample_cancel(bContext *C, wmOperator *op) { sample_exit(C, op); - return OPERATOR_CANCELLED; } void NODE_OT_backimage_sample(wmOperatorType *ot) diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index fe706ce2365..5168c3c873a 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -765,286 +765,6 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa uiBlockSetEmboss(block, UI_EMBOSS); } -static void operator_call_cb(struct bContext *UNUSED(C), void *arg_kmi, void *arg2) -{ - wmOperatorType *ot = arg2; - wmKeyMapItem *kmi = arg_kmi; - - if (ot) - BLI_strncpy(kmi->idname, ot->idname, OP_MAX_TYPENAME); -} - -static void operator_search_cb(const struct bContext *UNUSED(C), void *UNUSED(arg_kmi), - const char *str, uiSearchItems *items) -{ - GHashIterator *iter = WM_operatortype_iter(); - - for (; !BLI_ghashIterator_done(iter); BLI_ghashIterator_step(iter)) { - wmOperatorType *ot = BLI_ghashIterator_getValue(iter); - - if (BLI_strcasestr(ot->idname, str)) { - char name[OP_MAX_TYPENAME]; - - /* display name for menu */ - WM_operator_py_idname(name, ot->idname); - - if (false == uiSearchItemAdd(items, name, ot, 0)) - break; - } - } - BLI_ghashIterator_free(iter); -} - -/* operator Search browse menu, open */ -static uiBlock *operator_search_menu(bContext *C, ARegion *ar, void *arg_kmi) -{ - static char search[OP_MAX_TYPENAME]; - wmEvent event; - wmWindow *win = CTX_wm_window(C); - wmKeyMapItem *kmi = arg_kmi; - wmOperatorType *ot = WM_operatortype_find(kmi->idname, 0); - uiBlock *block; - uiBut *but; - - /* clear initial search string, then all items show */ - search[0] = 0; - - block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS); - uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_SEARCH_MENU); - - /* fake button, it holds space for search items */ - uiDefBut(block, LABEL, 0, "", 10, 15, uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL); - - but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, 150, UI_UNIT_Y, 0, 0, ""); - uiButSetSearchFunc(but, operator_search_cb, arg_kmi, operator_call_cb, ot); - - uiBoundsBlock(block, 6); - uiBlockSetDirection(block, UI_DOWN); - uiEndBlock(C, block); - - wm_event_init_from_window(win, &event); - event.type = EVT_BUT_OPEN; - event.val = KM_PRESS; - event.customdata = but; - event.customdatafree = FALSE; - wm_event_add(win, &event); - - return block; -} - -#define OL_KM_KEYBOARD 0 -#define OL_KM_MOUSE 1 -#define OL_KM_TWEAK 2 -#define OL_KM_SPECIALS 3 - -static short keymap_menu_type(short type) -{ - if (ISKEYBOARD(type)) return OL_KM_KEYBOARD; - if (ISTWEAK(type)) return OL_KM_TWEAK; - if (ISMOUSE(type)) return OL_KM_MOUSE; -// return OL_KM_SPECIALS; - return 0; -} - -static const char *keymap_type_menu(void) -{ - static const char string[] = - "Event Type%t" - "|Keyboard%x" STRINGIFY(OL_KM_KEYBOARD) - "|Mouse%x" STRINGIFY(OL_KM_MOUSE) - "|Tweak%x" STRINGIFY(OL_KM_TWEAK) -// "|Specials%x" STRINGIFY(OL_KM_SPECIALS) - ; - - return string; -} - -static const char *keymap_mouse_menu(void) -{ - static const char string[] = - "Mouse Event%t" - "|Left Mouse%x" STRINGIFY(LEFTMOUSE) - "|Middle Mouse%x" STRINGIFY(MIDDLEMOUSE) - "|Right Mouse%x" STRINGIFY(RIGHTMOUSE) - "|Middle Mouse%x" STRINGIFY(MIDDLEMOUSE) - "|Right Mouse%x" STRINGIFY(RIGHTMOUSE) - "|Button4 Mouse%x" STRINGIFY(BUTTON4MOUSE) - "|Button5 Mouse%x" STRINGIFY(BUTTON5MOUSE) - "|Action Mouse%x" STRINGIFY(ACTIONMOUSE) - "|Select Mouse%x" STRINGIFY(SELECTMOUSE) - "|Mouse Move%x" STRINGIFY(MOUSEMOVE) - "|Wheel Up%x" STRINGIFY(WHEELUPMOUSE) - "|Wheel Down%x" STRINGIFY(WHEELDOWNMOUSE) - "|Wheel In%x" STRINGIFY(WHEELINMOUSE) - "|Wheel Out%x" STRINGIFY(WHEELOUTMOUSE) - "|Mouse/Trackpad Pan%x" STRINGIFY(MOUSEPAN) - "|Mouse/Trackpad Zoom%x" STRINGIFY(MOUSEZOOM) - "|Mouse/Trackpad Rotate%x" STRINGIFY(MOUSEROTATE) - ; - - return string; -} - -static const char *keymap_tweak_menu(void) -{ - static const char string[] = - "Tweak Event%t" - "|Left Mouse%x" STRINGIFY(EVT_TWEAK_L) - "|Middle Mouse%x" STRINGIFY(EVT_TWEAK_M) - "|Right Mouse%x" STRINGIFY(EVT_TWEAK_R) - "|Action Mouse%x" STRINGIFY(EVT_TWEAK_A) - "|Select Mouse%x" STRINGIFY(EVT_TWEAK_S) - ; - - return string; -} - -static const char *keymap_tweak_dir_menu(void) -{ - static const char string[] = - "Tweak Direction%t" - "|Any%x" STRINGIFY(KM_ANY) - "|North%x" STRINGIFY(EVT_GESTURE_N) - "|North-East%x" STRINGIFY(EVT_GESTURE_NE) - "|East%x" STRINGIFY(EVT_GESTURE_E) - "|Sout-East%x" STRINGIFY(EVT_GESTURE_SE) - "|South%x" STRINGIFY(EVT_GESTURE_S) - "|South-West%x" STRINGIFY(EVT_GESTURE_SW) - "|West%x" STRINGIFY(EVT_GESTURE_W) - "|North-West%x" STRINGIFY(EVT_GESTURE_NW) - ; - - return string; -} - - -static void keymap_type_cb(bContext *C, void *kmi_v, void *UNUSED(arg_v)) -{ - wmKeyMapItem *kmi = kmi_v; - short maptype = keymap_menu_type(kmi->type); - - if (maptype != kmi->maptype) { - switch (kmi->maptype) { - case OL_KM_KEYBOARD: - kmi->type = AKEY; - kmi->val = KM_PRESS; - break; - case OL_KM_MOUSE: - kmi->type = LEFTMOUSE; - kmi->val = KM_PRESS; - break; - case OL_KM_TWEAK: - kmi->type = EVT_TWEAK_L; - kmi->val = KM_ANY; - break; - case OL_KM_SPECIALS: - kmi->type = AKEY; - kmi->val = KM_PRESS; - break; - } - ED_region_tag_redraw(CTX_wm_region(C)); - } -} - -static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soops, ListBase *lb) -{ - TreeElement *te; - TreeStoreElem *tselem; - - uiBlockSetEmboss(block, UI_EMBOSST); - - for (te = lb->first; te; te = te->next) { - tselem = TREESTORE(te); - if (te->ys + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) { - uiBut *but; - const char *str; - int xstart = 240; - int butw1 = UI_UNIT_X; /* operator */ - int butw2 = 90; /* event type, menus */ - int butw3 = 43; /* modifiers */ - - if (tselem->type == TSE_KEYMAP_ITEM) { - wmKeyMapItem *kmi = te->directdata; - - /* modal map? */ - if (kmi->propvalue) { - /* pass */ - } - else { - uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, te->ys + 1, butw1, UI_UNIT_Y - 1, - TIP_("Assign new Operator")); - } - xstart += butw1 + 10; - - /* map type button */ - kmi->maptype = keymap_menu_type(kmi->type); - - str = keymap_type_menu(); - but = uiDefButS(block, MENU, 0, str, xstart, te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->maptype, - 0, 0, 0, 0, TIP_("Event type")); - uiButSetFunc(but, keymap_type_cb, kmi, NULL); - xstart += butw2 + 5; - - /* edit actual event */ - switch (kmi->maptype) { - case OL_KM_KEYBOARD: - uiDefKeyevtButS(block, 0, "", xstart, te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, - TIP_("Key code")); - xstart += butw2 + 5; - break; - case OL_KM_MOUSE: - str = keymap_mouse_menu(); - uiDefButS(block, MENU, 0, str, xstart, te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, - 0, 0, 0, 0, TIP_("Mouse button")); - xstart += butw2 + 5; - break; - case OL_KM_TWEAK: - str = keymap_tweak_menu(); - uiDefButS(block, MENU, 0, str, xstart, te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, - 0, 0, 0, 0, TIP_("Tweak gesture")); - xstart += butw2 + 5; - str = keymap_tweak_dir_menu(); - uiDefButS(block, MENU, 0, str, xstart, te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->val, - 0, 0, 0, 0, TIP_("Tweak gesture direction")); - xstart += butw2 + 5; - break; - } - - /* modifiers */ - uiDefButS(block, OPTION, 0, IFACE_("Shift"), xstart, te->ys + 1, butw3 + 5, UI_UNIT_Y - 1, - &kmi->shift, 0, 0, 0, 0, TIP_("Modifier")); - xstart += butw3 + 5; - uiDefButS(block, OPTION, 0, IFACE_("Ctrl"), xstart, te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->ctrl, - 0, 0, 0, 0, TIP_("Modifier")); - xstart += butw3; - uiDefButS(block, OPTION, 0, IFACE_("Alt"), xstart, te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->alt, - 0, 0, 0, 0, TIP_("Modifier")); - xstart += butw3; - uiDefButS(block, OPTION, 0, IFACE_("OS"), xstart, te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->oskey, - 0, 0, 0, 0, TIP_("Modifier")); - xstart += butw3 + 5; - uiDefKeyevtButS(block, 0, "", xstart, te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->keymodifier, - TIP_("Key Modifier code")); - xstart += butw3 + 5; - - /* rna property */ - if (kmi->ptr && kmi->ptr->data) { - uiDefBut(block, LABEL, 0, IFACE_("(RNA property)"), xstart, te->ys + 1, butw2, UI_UNIT_Y - 1, - NULL, 0, 0, 0, 0, ""); - xstart += butw2; - } - - (void)xstart; - } - } - - if (TSELEM_OPEN(tselem, soops)) outliner_draw_keymapbuts(block, ar, soops, &te->subtree); - } - - uiBlockSetEmboss(block, UI_EMBOSS); -} - - static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, TreeElement *te) { uiBut *bt; @@ -1864,7 +1584,7 @@ void draw_outliner(const bContext *C) /* get extents of data */ outliner_height(soops, &soops->tree, &sizey); - if (ELEM3(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF, SO_KEYMAP)) { + if (ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF)) { /* RNA has two columns: * - column 1 is (max_width + OL_RNA_COL_SPACEX) or * (OL_RNA_COL_X), whichever is wider... @@ -1878,11 +1598,7 @@ void draw_outliner(const bContext *C) sizex_rna = max_ii(OL_RNA_COLX, sizex_rna + OL_RNA_COL_SPACEX); /* get width of data (for setting 'tot' rect, this is column 1 + column 2 + a bit extra) */ - if (soops->outlinevis == SO_KEYMAP) - // XXX this is only really a quick hack to make this wide enough... - sizex = sizex_rna + OL_RNA_COL_SIZEX * 3 + 50; - else - sizex = sizex_rna + OL_RNA_COL_SIZEX + 50; + sizex = sizex_rna + OL_RNA_COL_SIZEX + 50; } else { /* width must take into account restriction columns (if visible) so that entries will still be visible */ @@ -1908,7 +1624,7 @@ void draw_outliner(const bContext *C) /* set matrix for 2d-view controls */ UI_view2d_view_ortho(v2d); - /* draw outliner stuff (background, hierachy lines and names) */ + /* draw outliner stuff (background, hierarchy lines and names) */ outliner_back(ar); block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); outliner_draw_tree((bContext *)C, block, scene, ar, soops, &te_edit); @@ -1918,9 +1634,6 @@ void draw_outliner(const bContext *C) outliner_draw_rnacols(ar, sizex_rna); outliner_draw_rnabuts(block, scene, ar, soops, sizex_rna, &soops->tree); } - else if (soops->outlinevis == SO_KEYMAP) { - outliner_draw_keymapbuts(block, ar, soops, &soops->tree); - } else if (!(soops->flag & SO_HIDE_RESTRICTCOLS)) { /* draw restriction columns */ outliner_draw_restrictcols(ar); diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 41ad75bb14f..d1d512409ee 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -902,7 +902,7 @@ int outliner_item_do_activate(bContext *C, int x, int y, bool extend, bool recur UI_view2d_region_to_view(&ar->v2d, x, y, fmval, fmval + 1); - if (!ELEM3(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF, SO_KEYMAP) && + if (!ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF) && !(soops->flag & SO_HIDE_RESTRICTCOLS) && (fmval[0] > ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX)) { diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 10890a305fb..036db3bae91 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -428,8 +428,9 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s outliner_add_element(soops, lb, sce, te, TSE_ANIM_DATA, 0); outliner_add_element(soops, lb, sce->world, te, 0, 0); - - outliner_add_line_styles(soops, lb, sce, te); + + if (STREQ(sce->r.engine, "BLENDER_RENDER") && (sce->r.mode & R_EDGE_FRS)) + outliner_add_line_styles(soops, lb, sce, te); } // can be inlined if necessary @@ -1675,14 +1676,6 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) tselem->flag &= ~TSE_CLOSED; } } - else if (soops->outlinevis == SO_KEYMAP) { - wmWindowManager *wm = mainvar->wm.first; - wmKeyMap *km; - - for (km = wm->defaultconf->keymaps.first; km; km = km->next) { - /* ten = */ outliner_add_element(soops, &soops->tree, (void *)km, NULL, TSE_KEYMAP, 0); - } - } else { ten = outliner_add_element(soops, &soops->tree, OBACT, NULL, 0, 0); if (ten) ten->directdata = BASACT; diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index d695ffa46d5..3a7d001f432 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -476,9 +476,9 @@ void ED_spacetype_outliner(void) st->dropboxes = outliner_dropboxes; /* regions: main window */ - art = MEM_callocN(sizeof(ARegionType), "spacetype time region"); + art = MEM_callocN(sizeof(ARegionType), "spacetype outliner region"); art->regionid = RGN_TYPE_WINDOW; - art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D; + art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES; art->init = outliner_main_area_init; art->draw = outliner_main_area_draw; @@ -487,7 +487,7 @@ void ED_spacetype_outliner(void) BLI_addhead(&st->regiontypes, art); /* regions: header */ - art = MEM_callocN(sizeof(ARegionType), "spacetype time header region"); + art = MEM_callocN(sizeof(ARegionType), "spacetype outliner header region"); art->regionid = RGN_TYPE_HEADER; art->prefsizey = HEADERY; art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER; diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 8b2e7067eb9..63aa92517a7 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -821,7 +821,7 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe) /* like duplicate, but only duplicate and cut overlapping strips, * strips to the left of the cutframe are ignored and strips to the right * are moved to the end of slist - * we have to work on the same slist (not using a seperate list), since + * we have to work on the same slist (not using a separate list), since * otherwise dupli_seq can't check for duplicate names properly and * may generate strips with the same name (which will mess up animdata) */ diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c index deb37f8d943..f39b30adf37 100644 --- a/source/blender/editors/space_sequencer/sequencer_view.c +++ b/source/blender/editors/space_sequencer/sequencer_view.c @@ -211,11 +211,9 @@ static int sample_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static int sample_cancel(bContext *C, wmOperator *op) +static void sample_cancel(bContext *C, wmOperator *op) { sample_exit(C, op); - - return OPERATOR_CANCELLED; } static int sample_poll(bContext *C) diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 84c6329db53..4a4754e8adc 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -54,6 +54,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "UI_interface.h" #include "UI_resources.h" #include "UI_view2d.h" @@ -534,8 +535,9 @@ static void sequencer_preview_area_draw(const bContext *C, ARegion *ar) ScrArea *sa = CTX_wm_area(C); SpaceSeq *sseq = sa->spacedata.first; Scene *scene = CTX_data_scene(C); + wmWindowManager *wm = CTX_wm_manager(C); int show_split = scene->ed && scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW && sseq->mainb == SEQ_DRAW_IMG_IMBUF; - + /* XXX temp fix for wrong setting in sseq->mainb */ if (sseq->mainb == SEQ_DRAW_SEQUENCE) sseq->mainb = SEQ_DRAW_IMG_IMBUF; @@ -554,6 +556,11 @@ static void sequencer_preview_area_draw(const bContext *C, ARegion *ar) draw_image_seq(C, scene, ar, sseq, scene->r.cfra, over_cfra - scene->r.cfra, TRUE); } + if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_playing(wm)) { + rcti rect; + ED_region_visible_rect(ar, &rect); + ED_scene_draw_fps(scene, &rect); + } } static void sequencer_preview_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn) diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index c668c8063a8..ee64d680319 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -239,7 +239,11 @@ static void text_keymap(struct wmKeyConfig *keyconf) #ifdef __APPLE__ WM_keymap_add_item(keymap, "TEXT_OT_start_find", FKEY, KM_PRESS, KM_OSKEY, 0); #endif - + WM_keymap_add_item(keymap, "TEXT_OT_jump", JKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "TEXT_OT_find", GKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "TEXT_OT_replace", HKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "TEXT_OT_properties", TKEY, KM_PRESS, KM_CTRL, 0); + keymap = WM_keymap_find(keyconf, "Text", SPACE_TEXT, 0); #ifdef __APPLE__ @@ -265,7 +269,6 @@ static void text_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "TEXT_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0); WM_keymap_add_item(keymap, "TEXT_OT_paste", VKEY, KM_PRESS, KM_OSKEY, 0); WM_keymap_add_item(keymap, "TEXT_OT_find_set_selected", EKEY, KM_PRESS, KM_OSKEY, 0); - WM_keymap_add_item(keymap, "TEXT_OT_find", GKEY, KM_PRESS, KM_OSKEY, 0); WM_keymap_add_item(keymap, "TEXT_OT_select_all", AKEY, KM_PRESS, KM_OSKEY, 0); WM_keymap_add_item(keymap, "TEXT_OT_select_line", AKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0); #endif @@ -309,13 +312,6 @@ static void text_keymap(struct wmKeyConfig *keyconf) RNA_boolean_set(kmi->ptr, "selection", TRUE); } - WM_keymap_add_item(keymap, "TEXT_OT_properties", TKEY, KM_PRESS, KM_CTRL, 0); - - WM_keymap_add_item(keymap, "TEXT_OT_jump", JKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "TEXT_OT_find", GKEY, KM_PRESS, KM_CTRL, 0); - - WM_keymap_add_item(keymap, "TEXT_OT_replace", HKEY, KM_PRESS, KM_CTRL, 0); - kmi = WM_keymap_add_item(keymap, "TEXT_OT_to_3d_object", MKEY, KM_PRESS, KM_ALT, 0); RNA_boolean_set(kmi->ptr, "split_lines", FALSE); kmi = WM_keymap_add_item(keymap, "TEXT_OT_to_3d_object", MKEY, KM_PRESS, KM_CTRL, 0); @@ -476,13 +472,26 @@ static void text_drop_copy(wmDrag *drag, wmDropBox *drop) RNA_string_set(drop->ptr, "filepath", drag->path); } +static int text_drop_paste_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +{ + if (drag->type == WM_DRAG_ID) + return true; + + return false; +} + +static void text_drop_paste(wmDrag *drag, wmDropBox *drop) +{ + RNA_string_set(drop->ptr, "text", ((ID *)drag->poin)->name + 2); +} + /* this region dropbox definition */ static void text_dropboxes(void) { ListBase *lb = WM_dropboxmap_find("Text", SPACE_TEXT, RGN_TYPE_WINDOW); WM_dropbox_add(lb, "TEXT_OT_open", text_drop_poll, text_drop_copy); - + WM_dropbox_add(lb, "TEXT_OT_insert", text_drop_paste_poll, text_drop_paste); } /* ************* end drop *********** */ diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c index eaba537c0a8..692cefd3ee9 100644 --- a/source/blender/editors/space_text/text_autocomplete.c +++ b/source/blender/editors/space_text/text_autocomplete.c @@ -529,10 +529,9 @@ static void text_autocomplete_free(bContext *C, wmOperator *op) } } -static int text_autocomplete_cancel(bContext *C, wmOperator *op) +static void text_autocomplete_cancel(bContext *C, wmOperator *op) { text_autocomplete_free(C, op); - return OPERATOR_CANCELLED; } void TEXT_OT_autocomplete(wmOperatorType *ot) diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index c078e612d68..dd5e282587d 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -174,12 +174,6 @@ static int text_new_exec(bContext *C, wmOperator *UNUSED(op)) uiIDContextProperty(C, &ptr, &prop); if (prop) { - /* when creating new ID blocks, use is already 1, but RNA - * pointer se also increases user, so this compensates it */ - /* doesnt always seem to happen... (ton) */ - if (text->id.us > 1) - text->id.us--; - RNA_id_pointer_create(&text->id, &idptr); RNA_property_pointer_set(&ptr, prop, idptr); RNA_property_update(C, &ptr, prop); @@ -220,10 +214,9 @@ static void text_open_init(bContext *C, wmOperator *op) uiIDContextProperty(C, &pprop->ptr, &pprop->prop); } -static int text_open_cancel(bContext *UNUSED(C), wmOperator *op) +static void text_open_cancel(bContext *UNUSED(C), wmOperator *op) { MEM_freeN(op->customdata); - return OPERATOR_CANCELLED; } static int text_open_exec(bContext *C, wmOperator *op) @@ -252,10 +245,6 @@ static int text_open_exec(bContext *C, wmOperator *op) pprop = op->customdata; if (pprop->prop) { - /* when creating new ID blocks, use is already 1, but RNA - * pointer se also increases user, so this compensates it */ - text->id.us--; - RNA_id_pointer_create(&text->id, &idptr); RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr); RNA_property_update(C, &pprop->ptr, pprop->prop); @@ -2241,11 +2230,9 @@ static int text_scroll_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static int text_scroll_cancel(bContext *C, wmOperator *op) +static void text_scroll_cancel(bContext *C, wmOperator *op) { scroll_exit(C, op); - - return OPERATOR_CANCELLED; } static int text_scroll_invoke(bContext *C, wmOperator *op, const wmEvent *event) @@ -2716,10 +2703,9 @@ static int text_set_selection_modal(bContext *C, wmOperator *op, const wmEvent * return OPERATOR_RUNNING_MODAL; } -static int text_set_selection_cancel(bContext *C, wmOperator *op) +static void text_set_selection_cancel(bContext *C, wmOperator *op) { text_cursor_set_exit(C, op); - return OPERATOR_FINISHED; } void TEXT_OT_selection_set(wmOperatorType *ot) diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 16423c60cac..a08a6cc1478 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -345,7 +345,10 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O else { /* draw with lights in the scene otherwise */ solidtex = false; - Gtexdraw.is_lit = GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp); + if (v3d->flag2 & V3D_SHADELESS_TEX) + Gtexdraw.is_lit = 0; + else + Gtexdraw.is_lit = GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp); } rgba_float_to_uchar(obcol, ob->col); @@ -571,7 +574,7 @@ static DMDrawOption draw_em_tf_mapped__set_draw(void *userData, int index) if (UNLIKELY(index >= em->bm->totface)) return DM_DRAW_OPTION_NORMAL; - efa = EDBM_face_at_index(em, index); + efa = BM_face_at_index(em->bm, index); if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { return DM_DRAW_OPTION_SKIP; @@ -933,7 +936,7 @@ static bool tex_mat_set_face_editmesh_cb(void *userData, int index) if (UNLIKELY(index >= em->bm->totface)) return DM_DRAW_OPTION_NORMAL; - efa = EDBM_face_at_index(em, index); + efa = BM_face_at_index(em->bm, index); return !BM_elem_flag_test(efa, BM_ELEM_HIDDEN); } @@ -955,7 +958,10 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW); else glFrontFace(GL_CCW); - glEnable(GL_LIGHTING); + if ((v3d->drawtype == OB_TEXTURE) && (v3d->flag2 & V3D_SHADELESS_TEX)) + glColor3f(1.0f, 1.0f, 1.0f); + else + glEnable(GL_LIGHTING); { Mesh *me = ob->data; @@ -977,7 +983,7 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL); if (glsl || picking) { - /* draw glsl */ + /* draw glsl or solid */ dm->drawMappedFacesMat(dm, tex_mat_set_material_cb, set_face_cb, &data); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 1ea1dcfb33d..9c053ee35bc 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -103,7 +103,7 @@ typedef enum eWireDrawMode { } eWireDrawMode; typedef struct drawDMVerts_userData { - BMEditMesh *em; + BMesh *bm; BMVert *eve_act; char sel; @@ -121,7 +121,7 @@ typedef struct drawDMVerts_userData { } drawDMVerts_userData; typedef struct drawDMEdgesSel_userData { - BMEditMesh *em; + BMesh *bm; unsigned char *baseCol, *selCol, *actCol; BMEdge *eed_act; @@ -135,7 +135,7 @@ typedef struct drawDMFacesSel_userData { #endif DerivedMesh *dm; - BMEditMesh *em; + BMesh *bm; BMFace *efa_act; int *orig_index_mf_to_mpoly; @@ -143,7 +143,7 @@ typedef struct drawDMFacesSel_userData { } drawDMFacesSel_userData; typedef struct drawDMNormal_userData { - BMEditMesh *em; + BMesh *bm; int uniform_scale; float normalsize; float tmat[3][3]; @@ -156,7 +156,7 @@ typedef struct bbsObmodeMeshVerts_userData { } bbsObmodeMeshVerts_userData; typedef struct drawDMLayer_userData { - BMEditMesh *em; + BMesh *bm; int cd_layer_offset; } drawDMLayer_userData; @@ -610,6 +610,7 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char if (ibuf && ibuf->rect) { const bool use_clip = (U.glalphaclip != 1.0f); + int zoomfilter = (U.gameflags & USER_DISABLE_MIPMAP )? GL_NEAREST : GL_LINEAR; /* Setup GL params */ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -623,7 +624,7 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char glColor4fv(ob->col); /* Draw the Image on the screen */ - glaDrawPixelsTex(ofs_x, ofs_y, ima_x, ima_y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect); + glaDrawPixelsTex(ofs_x, ofs_y, ima_x, ima_y, GL_RGBA, GL_UNSIGNED_BYTE, zoomfilter, ibuf->rect); glPixelTransferf(GL_ALPHA_SCALE, 1.0f); glDisable(GL_BLEND); @@ -1356,6 +1357,7 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, } /* and back to viewspace */ + glPushMatrix(); glLoadMatrixf(rv3d->viewmat); copy_v3_v3(vec, ob->obmat[3]); @@ -1391,6 +1393,8 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, /* restore for drawing extra stuff */ glColor3ubv(ob_wire_col); } + /* and finally back to org object space! */ + glPopMatrix(); } static void draw_limit_line(float sta, float end, const short dflag, unsigned int col) @@ -2038,7 +2042,7 @@ static void calcDrawDMNormalScale(Object *ob, drawDMNormal_userData *data) static void draw_dm_face_normals__mapFunc(void *userData, int index, const float cent[3], const float no[3]) { drawDMNormal_userData *data = userData; - BMFace *efa = EDBM_face_at_index(data->em, index); + BMFace *efa = BM_face_at_index(data->bm, index); float n[3]; if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { @@ -2062,7 +2066,7 @@ static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, Deriv { drawDMNormal_userData data; - data.em = em; + data.bm = em->bm; data.normalsize = scene->toolsettings->normalsize; calcDrawDMNormalScale(ob, &data); @@ -2074,7 +2078,7 @@ static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, Deriv static void draw_dm_face_centers__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3])) { - BMFace *efa = EDBM_face_at_index(((void **)userData)[0], index); + BMFace *efa = BM_face_at_index(((void **)userData)[0], index); const char sel = *(((char **)userData)[1]); if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && @@ -2085,7 +2089,7 @@ static void draw_dm_face_centers__mapFunc(void *userData, int index, const float } static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, char sel) { - void *ptrs[2] = {em, &sel}; + void *ptrs[2] = {em->bm, &sel}; bglBegin(GL_POINTS); dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, ptrs, DM_FOREACH_NOP); @@ -2095,7 +2099,7 @@ static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, char sel) static void draw_dm_vert_normals__mapFunc(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]) { drawDMNormal_userData *data = userData; - BMVert *eve = EDBM_vert_at_index(data->em, index); + BMVert *eve = BM_vert_at_index(data->bm, index); if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { float no[3], n[3]; @@ -2127,7 +2131,7 @@ static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, Object *ob, Deriv { drawDMNormal_userData data; - data.em = em; + data.bm = em->bm; data.normalsize = scene->toolsettings->normalsize; calcDrawDMNormalScale(ob, &data); @@ -2142,7 +2146,7 @@ static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3], const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) { drawDMVerts_userData *data = userData; - BMVert *eve = EDBM_vert_at_index(data->em, index); + BMVert *eve = BM_vert_at_index(data->bm, index); if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->sel) { /* skin nodes: draw a red circle around the root @@ -2188,7 +2192,7 @@ static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, const char sel, BMVer drawDMVerts_userData data; data.sel = sel; data.eve_act = eve_act; - data.em = em; + data.bm = em->bm; /* Cache theme values */ UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, data.th_editmesh_active); @@ -2216,7 +2220,7 @@ static DMDrawOption draw_dm_edges_sel__setDrawOptions(void *userData, int index) drawDMEdgesSel_userData *data = userData; unsigned char *col; - eed = EDBM_edge_at_index(data->em, index); + eed = BM_edge_at_index(data->bm, index); if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { if (eed == data->eed_act) { @@ -2249,7 +2253,7 @@ static void draw_dm_edges_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *ba data.baseCol = baseCol; data.selCol = selCol; data.actCol = actCol; - data.em = em; + data.bm = em->bm; data.eed_act = eed_act; dm->drawMappedEdges(dm, draw_dm_edges_sel__setDrawOptions, &data); } @@ -2257,7 +2261,7 @@ static void draw_dm_edges_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *ba /* Draw edges */ static DMDrawOption draw_dm_edges__setDrawOptions(void *userData, int index) { - if (BM_elem_flag_test(EDBM_edge_at_index(userData, index), BM_ELEM_HIDDEN)) + if (BM_elem_flag_test(BM_edge_at_index(userData, index), BM_ELEM_HIDDEN)) return DM_DRAW_OPTION_SKIP; else return DM_DRAW_OPTION_NORMAL; @@ -2265,20 +2269,20 @@ static DMDrawOption draw_dm_edges__setDrawOptions(void *userData, int index) static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm) { - dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, em); + dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, em->bm); } /* Draw edges with color interpolated based on selection */ static DMDrawOption draw_dm_edges_sel_interp__setDrawOptions(void *userData, int index) { - if (BM_elem_flag_test(EDBM_edge_at_index(((void **)userData)[0], index), BM_ELEM_HIDDEN)) + if (BM_elem_flag_test(BM_edge_at_index(((void **)userData)[0], index), BM_ELEM_HIDDEN)) return DM_DRAW_OPTION_SKIP; else return DM_DRAW_OPTION_NORMAL; } static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int index, float t) { - BMEdge *eed = EDBM_edge_at_index(((void **)userData)[0], index); + BMEdge *eed = BM_edge_at_index(((void **)userData)[0], index); unsigned char **cols = userData; unsigned char *col0 = cols[(BM_elem_flag_test(eed->v1, BM_ELEM_SELECT)) ? 2 : 1]; unsigned char *col1 = cols[(BM_elem_flag_test(eed->v2, BM_ELEM_SELECT)) ? 2 : 1]; @@ -2291,7 +2295,7 @@ static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int i static void draw_dm_edges_sel_interp(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol) { - void *cols[3] = {em, baseCol, selCol}; + void *cols[3] = {em->bm, baseCol, selCol}; dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols); } @@ -2299,7 +2303,7 @@ static void draw_dm_edges_sel_interp(BMEditMesh *em, DerivedMesh *dm, unsigned c /* Draw only seam edges */ static DMDrawOption draw_dm_edges_seams__setDrawOptions(void *userData, int index) { - BMEdge *eed = EDBM_edge_at_index(userData, index); + BMEdge *eed = BM_edge_at_index(userData, index); if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && BM_elem_flag_test(eed, BM_ELEM_SEAM)) return DM_DRAW_OPTION_NORMAL; @@ -2309,13 +2313,13 @@ static DMDrawOption draw_dm_edges_seams__setDrawOptions(void *userData, int inde static void draw_dm_edges_seams(BMEditMesh *em, DerivedMesh *dm) { - dm->drawMappedEdges(dm, draw_dm_edges_seams__setDrawOptions, em); + dm->drawMappedEdges(dm, draw_dm_edges_seams__setDrawOptions, em->bm); } /* Draw only sharp edges */ static DMDrawOption draw_dm_edges_sharp__setDrawOptions(void *userData, int index) { - BMEdge *eed = EDBM_edge_at_index(userData, index); + BMEdge *eed = BM_edge_at_index(userData, index); if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && !BM_elem_flag_test(eed, BM_ELEM_SMOOTH)) return DM_DRAW_OPTION_NORMAL; @@ -2325,14 +2329,14 @@ static DMDrawOption draw_dm_edges_sharp__setDrawOptions(void *userData, int inde static void draw_dm_edges_sharp(BMEditMesh *em, DerivedMesh *dm) { - dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, em); + dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, em->bm); } #ifdef WITH_FREESTYLE -static int draw_dm_test_freestyle_edge_mark(BMEditMesh *em, BMEdge *eed) +static int draw_dm_test_freestyle_edge_mark(BMesh *bm, BMEdge *eed) { - FreestyleEdge *fed = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_FREESTYLE_EDGE); + FreestyleEdge *fed = CustomData_bmesh_get(&bm->edata, eed->head.data, CD_FREESTYLE_EDGE); if (!fed) return 0; return (fed->flag & FREESTYLE_EDGE_MARK) != 0; @@ -2341,7 +2345,7 @@ static int draw_dm_test_freestyle_edge_mark(BMEditMesh *em, BMEdge *eed) /* Draw only Freestyle feature edges */ static DMDrawOption draw_dm_edges_freestyle__setDrawOptions(void *userData, int index) { - BMEdge *eed = EDBM_edge_at_index(userData, index); + BMEdge *eed = BM_edge_at_index(userData, index); if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && draw_dm_test_freestyle_edge_mark(userData, eed)) return DM_DRAW_OPTION_NORMAL; @@ -2351,12 +2355,12 @@ static DMDrawOption draw_dm_edges_freestyle__setDrawOptions(void *userData, int static void draw_dm_edges_freestyle(BMEditMesh *em, DerivedMesh *dm) { - dm->drawMappedEdges(dm, draw_dm_edges_freestyle__setDrawOptions, em); + dm->drawMappedEdges(dm, draw_dm_edges_freestyle__setDrawOptions, em->bm); } -static int draw_dm_test_freestyle_face_mark(BMEditMesh *em, BMFace *efa) +static int draw_dm_test_freestyle_face_mark(BMesh *bm, BMFace *efa) { - FreestyleFace *ffa = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_FREESTYLE_FACE); + FreestyleFace *ffa = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_FREESTYLE_FACE); if (!ffa) return 0; return (ffa->flag & FREESTYLE_FACE_MARK) != 0; @@ -2369,7 +2373,7 @@ static int draw_dm_test_freestyle_face_mark(BMEditMesh *em, BMFace *efa) static DMDrawOption draw_dm_faces_sel__setDrawOptions(void *userData, int index) { drawDMFacesSel_userData *data = userData; - BMFace *efa = EDBM_face_at_index(data->em, index); + BMFace *efa = BM_face_at_index(data->bm, index); unsigned char *col; if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { @@ -2379,7 +2383,7 @@ static DMDrawOption draw_dm_faces_sel__setDrawOptions(void *userData, int index) } else { #ifdef WITH_FREESTYLE - col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->em, efa) ? 3 : 0]; + col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0]; #else col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0]; #endif @@ -2406,9 +2410,9 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int return 0; i = DM_origindex_mface_mpoly(data->orig_index_mf_to_mpoly, data->orig_index_mp_to_orig, index); - efa = (i != ORIGINDEX_NONE) ? EDBM_face_at_index(data->em, i) : NULL; + efa = (i != ORIGINDEX_NONE) ? BM_face_at_index(data->bm, i) : NULL; i = DM_origindex_mface_mpoly(data->orig_index_mf_to_mpoly, data->orig_index_mp_to_orig, next_index); - next_efa = (i != ORIGINDEX_NONE) ? EDBM_face_at_index(data->em, i) : NULL; + next_efa = (i != ORIGINDEX_NONE) ? BM_face_at_index(data->bm, i) : NULL; if (ELEM(NULL, efa, next_efa)) return 0; @@ -2420,8 +2424,8 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int return 0; #ifdef WITH_FREESTYLE - col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->em, efa) ? 3 : 0]; - next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->em, efa) ? 3 : 0]; + col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0]; + next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0]; #else col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0]; next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : 0]; @@ -2445,7 +2449,7 @@ static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *ba drawDMFacesSel_userData data; data.dm = dm; data.cols[0] = baseCol; - data.em = em; + data.bm = em->bm; data.cols[1] = selCol; data.cols[2] = actCol; #ifdef WITH_FREESTYLE @@ -2465,8 +2469,8 @@ static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *ba static DMDrawOption draw_dm_creases__setDrawOptions(void *userData, int index) { drawDMLayer_userData *data = userData; - BMEditMesh *em = data->em; - BMEdge *eed = EDBM_edge_at_index(em, index); + BMesh *bm = data->bm; + BMEdge *eed = BM_edge_at_index(bm, index); if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { const float crease = BM_ELEM_CD_GET_FLOAT(eed, data->cd_layer_offset); @@ -2481,7 +2485,7 @@ static void draw_dm_creases(BMEditMesh *em, DerivedMesh *dm) { drawDMLayer_userData data; - data.em = em; + data.bm = em->bm; data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE); if (data.cd_layer_offset != -1) { @@ -2494,8 +2498,8 @@ static void draw_dm_creases(BMEditMesh *em, DerivedMesh *dm) static DMDrawOption draw_dm_bweights__setDrawOptions(void *userData, int index) { drawDMLayer_userData *data = userData; - BMEditMesh *em = data->em; - BMEdge *eed = EDBM_edge_at_index(em, index); + BMesh *bm = data->bm; + BMEdge *eed = BM_edge_at_index(bm, index); if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { const float bweight = BM_ELEM_CD_GET_FLOAT(eed, data->cd_layer_offset); @@ -2510,8 +2514,8 @@ static void draw_dm_bweights__mapFunc(void *userData, int index, const float co[ const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) { drawDMLayer_userData *data = userData; - BMEditMesh *em = data->em; - BMVert *eve = EDBM_vert_at_index(em, index); + BMesh *bm = data->bm; + BMVert *eve = BM_vert_at_index(bm, index); if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { const float bweight = BM_ELEM_CD_GET_FLOAT(eve, data->cd_layer_offset); @@ -2528,7 +2532,7 @@ static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm) if (ts->selectmode & SCE_SELECT_VERTEX) { drawDMLayer_userData data; - data.em = em; + data.bm = em->bm; data.cd_layer_offset = CustomData_get_offset(&em->bm->vdata, CD_BWEIGHT); if (data.cd_layer_offset != -1) { @@ -2541,7 +2545,7 @@ static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm) else { drawDMLayer_userData data; - data.em = em; + data.bm = em->bm; data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT); if (data.cd_layer_offset != -1) { @@ -2692,7 +2696,10 @@ static void draw_em_fancy_edges(BMEditMesh *em, Scene *scene, View3D *v3d, static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMesh *em, UnitSettings *unit) { - const short txt_flag = V3D_CACHE_TEXT_ASCII | V3D_CACHE_TEXT_LOCALCLIP; + /* Do not use ascii when using non-default unit system, some unit chars are utf8 (micro, square, etc.). + * See bug #36090. + */ + const short txt_flag = V3D_CACHE_TEXT_LOCALCLIP | (unit->system ? 0 : V3D_CACHE_TEXT_ASCII); Mesh *me = ob->data; float v1[3], v2[3], v3[3], vmid[3], fvec[3]; char numstr[32]; /* Stores the measurement display text here */ @@ -2865,14 +2872,11 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe bUnit_AsString(numstr, sizeof(numstr), \ (double)(area * unit->scale_length * unit->scale_length), \ 3, unit->system, B_UNIT_AREA, do_split, false); \ - view3d_cached_text_draw_add(vmid, numstr, 0, \ - /* Metric system uses unicode "squared" sign! */ \ - txt_flag ^ V3D_CACHE_TEXT_ASCII, col); \ } \ else { \ BLI_snprintf(numstr, sizeof(numstr), conv_float, area); \ - view3d_cached_text_draw_add(vmid, numstr, 0, txt_flag, col); \ } \ + view3d_cached_text_draw_add(vmid, numstr, 0, txt_flag, col); \ } (void)0 UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col); @@ -3060,7 +3064,7 @@ static DMDrawOption draw_em_fancy__setFaceOpts(void *userData, int index) if (UNLIKELY(index >= em->bm->totface)) return DM_DRAW_OPTION_NORMAL; - efa = EDBM_face_at_index(em, index); + efa = BM_face_at_index(em->bm, index); if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { GPU_enable_material(efa->mat_nr + 1, NULL); return DM_DRAW_OPTION_NORMAL; @@ -3078,7 +3082,7 @@ static DMDrawOption draw_em_fancy__setGLSLFaceOpts(void *userData, int index) if (UNLIKELY(index >= em->bm->totface)) return DM_DRAW_OPTION_NORMAL; - efa = EDBM_face_at_index(em, index); + efa = BM_face_at_index(em->bm, index); if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { return DM_DRAW_OPTION_NORMAL; @@ -3116,7 +3120,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d, } } - EDBM_index_arrays_ensure(em, BM_VERT | BM_EDGE | BM_FACE); + BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE); if (check_object_draw_editweight(me, finalDM)) { if (dt > OB_WIRE) { @@ -3128,7 +3132,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d, else { glEnable(GL_DEPTH_TEST); draw_mesh_paint_weight_faces(finalDM, false, draw_em_fancy__setFaceOpts, me->edit_btmesh); - draw_mesh_paint_weight_edges(rv3d, finalDM, true, draw_dm_edges__setDrawOptions, me->edit_btmesh); + draw_mesh_paint_weight_edges(rv3d, finalDM, true, draw_dm_edges__setDrawOptions, me->edit_btmesh->bm); glDisable(GL_DEPTH_TEST); } } @@ -4054,7 +4058,7 @@ static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3 if (BKE_mball_is_basis(ob)) { lb = ob->curve_cache ? &ob->curve_cache->disp : NULL; - if (ELEM(lb, lb->first, NULL)) { + if (ELEM(NULL, lb, lb->first)) { BKE_displist_make_mball(scene, ob); lb = &ob->curve_cache->disp; } @@ -6357,7 +6361,7 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base, RegionView3D *rv3d = ar->regiondata; Object *ob = base->object; - glLineWidth(2.0); + glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); glDepthMask(0); if (ELEM3(ob->type, OB_FONT, OB_CURVE, OB_SURF)) { @@ -6644,6 +6648,8 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short char dt; short zbufoff = 0; const bool is_obact = (ob == OBACT); + const bool render_override = (v3d->flag2 & V3D_RENDER_OVERRIDE) != 0; + bool particle_skip_object = false; /* Draw particles but not their emitter object. */ /* only once set now, will be removed too, should become a global standard */ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -6652,16 +6658,30 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short if (ob->restrictflag & OB_RESTRICT_VIEW) { return; } - else if ((ob->restrictflag & OB_RESTRICT_RENDER) && - (v3d->flag2 & V3D_RENDER_OVERRIDE)) - { + else if ((ob->restrictflag & OB_RESTRICT_RENDER) && render_override) { return; } } - /* XXX particles are not safe for simultaneous threaded render */ - if (G.is_rendering && ob->particlesystem.first) - return; + if (ob->particlesystem.first) { + /* XXX particles are not safe for simultaneous threaded render */ + if (G.is_rendering) { + return; + } + + if (ob->mode == OB_MODE_OBJECT) { + ParticleSystem *psys; + + particle_skip_object = render_override; + for (psys = ob->particlesystem.first; psys; psys = psys->next) { + /* Once we have found a psys which renders its emitter object, we are done. */ + if (psys->part->draw & PART_DRAW_EMITTER) { + particle_skip_object = false; + break; + } + } + } + } /* xray delay? */ if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) { @@ -6687,7 +6707,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short view3d_cached_text_draw_begin(); /* draw motion paths (in view space) */ - if (ob->mpath && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { + if (ob->mpath && !render_override) { bAnimVizSettings *avs = &ob->avs; /* setup drawing environment for paths */ @@ -6728,7 +6748,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short /* faceselect exception: also draw solid when (dt == wire), except in editmode */ if (is_obact && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) { - if (ob->type == OB_MESH) { + if (ob->type == OB_MESH) { if (dt < OB_SOLID) { zbufoff = 1; dt = OB_SOLID; @@ -6760,240 +6780,240 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short } - /* bad exception, solve this! otherwise outline shows too late */ - if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { - /* still needed for curves hidden in other layers. depgraph doesnt handle that yet */ - if (ELEM(NULL, ob->curve_cache, ob->curve_cache->disp.first)) { - BKE_displist_make_curveTypes(scene, ob, 0); + if (!particle_skip_object) { + /* bad exception, solve this! otherwise outline shows too late */ + if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { + /* still needed for curves hidden in other layers. depgraph doesnt handle that yet */ + if (ELEM(NULL, ob->curve_cache, ob->curve_cache->disp.first)) { + BKE_displist_make_curveTypes(scene, ob, 0); + } } - } - - /* 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 && (dflag & DRAW_SCENESET) == 0) { - if (!(ob->dtx & OB_DRAWWIRE) && (ob->flag & SELECT) && !(dflag & (DRAW_PICKING | DRAW_CONSTCOLOR))) { - drawObjectSelect(scene, v3d, ar, base, ob_wire_col); + + /* draw outline for selected objects, mesh does itself */ + if ((v3d->flag & V3D_SELECT_OUTLINE) && !render_override && ob->type != OB_MESH) { + 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 | DRAW_CONSTCOLOR))) { + 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, ob_wire_col, dflag); - if (dflag != DRAW_CONSTCOLOR) dtx &= ~OB_DRAWWIRE; // mesh draws wire itself + switch (ob->type) { + case OB_MESH: + empty_object = draw_mesh_object(scene, ar, v3d, rv3d, base, dt, ob_wire_col, dflag); + if (dflag != DRAW_CONSTCOLOR) dtx &= ~OB_DRAWWIRE; // mesh draws wire itself - break; - case OB_FONT: - cu = ob->data; - if (cu->editfont) { - draw_textcurs(rv3d, cu->editfont->textcurs); - - if (cu->flag & CU_FAST) { - cpack(0xFFFFFF); - set_inverted_drawing(1); - drawDispList(scene, v3d, rv3d, base, OB_WIRE, dflag, ob_wire_col); - set_inverted_drawing(0); - } - else { - drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col); - } - - if (cu->linewidth != 0.0f) { - UI_ThemeColor(TH_WIRE_EDIT); - copy_v3_v3(vec1, ob->orig); - copy_v3_v3(vec2, ob->orig); - vec1[0] += cu->linewidth; - vec2[0] += cu->linewidth; - vec1[1] += cu->linedist * cu->fsize; - vec2[1] -= cu->lines * cu->linedist * cu->fsize; - setlinestyle(3); - glBegin(GL_LINE_STRIP); - glVertex2fv(vec1); - glVertex2fv(vec2); - glEnd(); - setlinestyle(0); - } + break; + case OB_FONT: + cu = ob->data; + if (cu->editfont) { + draw_textcurs(rv3d, cu->editfont->textcurs); + + if (cu->flag & CU_FAST) { + cpack(0xFFFFFF); + set_inverted_drawing(1); + drawDispList(scene, v3d, rv3d, base, OB_WIRE, dflag, ob_wire_col); + set_inverted_drawing(0); + } + else { + drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col); + } - setlinestyle(3); - for (i = 0; i < cu->totbox; i++) { - if (cu->tb[i].w != 0.0f) { - UI_ThemeColor(i == (cu->actbox - 1) ? TH_ACTIVE : TH_WIRE); - vec1[0] = (cu->xof * cu->fsize) + cu->tb[i].x; - vec1[1] = (cu->yof * cu->fsize) + cu->tb[i].y + cu->fsize; - vec1[2] = 0.001; + if (cu->linewidth != 0.0f) { + UI_ThemeColor(TH_WIRE_EDIT); + copy_v3_v3(vec1, ob->orig); + copy_v3_v3(vec2, ob->orig); + vec1[0] += cu->linewidth; + vec2[0] += cu->linewidth; + vec1[1] += cu->linedist * cu->fsize; + vec2[1] -= cu->lines * cu->linedist * cu->fsize; + setlinestyle(3); glBegin(GL_LINE_STRIP); - glVertex3fv(vec1); - vec1[0] += cu->tb[i].w; - glVertex3fv(vec1); - vec1[1] -= cu->tb[i].h; - glVertex3fv(vec1); - vec1[0] -= cu->tb[i].w; - glVertex3fv(vec1); - vec1[1] += cu->tb[i].h; - glVertex3fv(vec1); + glVertex2fv(vec1); + glVertex2fv(vec2); glEnd(); + setlinestyle(0); } - } - setlinestyle(0); + setlinestyle(3); + for (i = 0; i < cu->totbox; i++) { + if (cu->tb[i].w != 0.0f) { + UI_ThemeColor(i == (cu->actbox - 1) ? TH_ACTIVE : TH_WIRE); + vec1[0] = (cu->xof * cu->fsize) + cu->tb[i].x; + vec1[1] = (cu->yof * cu->fsize) + cu->tb[i].y + cu->fsize; + vec1[2] = 0.001; + glBegin(GL_LINE_STRIP); + glVertex3fv(vec1); + vec1[0] += cu->tb[i].w; + glVertex3fv(vec1); + vec1[1] -= cu->tb[i].h; + glVertex3fv(vec1); + vec1[0] -= cu->tb[i].w; + glVertex3fv(vec1); + vec1[1] += cu->tb[i].h; + glVertex3fv(vec1); + glEnd(); + } + } + setlinestyle(0); - if (BKE_vfont_select_get(ob, &selstart, &selend) && cu->selboxes) { - float selboxw; - cpack(0xffffff); - set_inverted_drawing(1); - for (i = 0; i <= (selend - selstart); i++) { - SelBox *sb = &(cu->selboxes[i]); + if (BKE_vfont_select_get(ob, &selstart, &selend) && cu->selboxes) { + float selboxw; - if (i < (selend - selstart)) { - if (cu->selboxes[i + 1].y == sb->y) - selboxw = cu->selboxes[i + 1].x - sb->x; - else + cpack(0xffffff); + set_inverted_drawing(1); + for (i = 0; i <= (selend - selstart); i++) { + SelBox *sb = &(cu->selboxes[i]); + + if (i < (selend - selstart)) { + if (cu->selboxes[i + 1].y == sb->y) + selboxw = cu->selboxes[i + 1].x - sb->x; + else + selboxw = sb->w; + } + else { selboxw = sb->w; + } + glBegin(GL_QUADS); + glVertex3f(sb->x, sb->y, 0.001); + glVertex3f(sb->x + selboxw, sb->y, 0.001); + glVertex3f(sb->x + selboxw, sb->y + sb->h, 0.001); + glVertex3f(sb->x, sb->y + sb->h, 0.001); + glEnd(); } - else { - selboxw = sb->w; - } - glBegin(GL_QUADS); - glVertex3f(sb->x, sb->y, 0.001); - glVertex3f(sb->x + selboxw, sb->y, 0.001); - glVertex3f(sb->x + selboxw, sb->y + sb->h, 0.001); - glVertex3f(sb->x, sb->y + sb->h, 0.001); - glEnd(); + set_inverted_drawing(0); } - set_inverted_drawing(0); } - } - else if (dt == OB_BOUNDBOX) { - if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_WIRE) == 0) { - draw_bounding_volume(scene, ob, ob->boundtype); + else if (dt == OB_BOUNDBOX) { + if ((render_override && v3d->drawtype >= OB_WIRE) == 0) { + draw_bounding_volume(scene, ob, ob->boundtype); + } + } + else if (ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb)) { + empty_object = drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col); } - } - else if (ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb)) { - empty_object = drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col); - } - break; - case OB_CURVE: - case OB_SURF: - cu = ob->data; + break; + case OB_CURVE: + case OB_SURF: + cu = ob->data; - if (cu->editnurb) { - ListBase *nurbs = BKE_curve_editNurbs_get(cu); - drawnurb(scene, v3d, rv3d, base, nurbs->first, dt, dflag, 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); + if (cu->editnurb) { + ListBase *nurbs = BKE_curve_editNurbs_get(cu); + drawnurb(scene, v3d, rv3d, base, nurbs->first, dt, dflag, ob_wire_col); } - } - else if (ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb)) { - empty_object = drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col); + else if (dt == OB_BOUNDBOX) { + if ((render_override && (v3d->drawtype >= OB_WIRE)) == 0) { + draw_bounding_volume(scene, ob, ob->boundtype); + } + } + else if (ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb)) { + empty_object = drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col); //XXX old animsys if (cu->path) // curve_draw_speed(scene, ob); - } - break; - case OB_MBALL: - { - MetaBall *mb = ob->data; - - if (mb->editelems) - drawmball(scene, v3d, rv3d, base, dt, dflag, 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); } + break; + case OB_MBALL: + { + MetaBall *mb = ob->data; + + if (mb->editelems) + drawmball(scene, v3d, rv3d, base, dt, dflag, ob_wire_col); + else if (dt == OB_BOUNDBOX) { + if ((render_override && (v3d->drawtype >= OB_WIRE)) == 0) { + draw_bounding_volume(scene, ob, ob->boundtype); + } + } + else + empty_object = drawmball(scene, v3d, rv3d, base, dt, dflag, ob_wire_col); + break; } - else - empty_object = drawmball(scene, v3d, rv3d, base, dt, dflag, ob_wire_col); - break; - } - case OB_EMPTY: - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - if (ob->empty_drawtype == OB_EMPTY_IMAGE) { - draw_empty_image(ob, dflag, ob_wire_col); + case OB_EMPTY: + if (!render_override) { + if (ob->empty_drawtype == OB_EMPTY_IMAGE) { + draw_empty_image(ob, dflag, ob_wire_col); + } + else { + drawaxes(ob->empty_drawsize, ob->empty_drawtype); + } } - else { - drawaxes(ob->empty_drawsize, ob->empty_drawtype); + break; + case OB_LAMP: + if (!render_override) { + drawlamp(scene, v3d, rv3d, base, dt, dflag, ob_wire_col); } - } - break; - case OB_LAMP: - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - drawlamp(scene, v3d, rv3d, base, dt, dflag, ob_wire_col); - if (dtx || (base->flag & SELECT)) glMultMatrixf(ob->obmat); - } - break; - case OB_CAMERA: - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0 || - (rv3d->persp == RV3D_CAMOB && v3d->camera == ob)) /* special exception for active camera */ - { - 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, dflag); - break; - case OB_LATTICE: - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - /* Do not allow boundbox in edit nor pose mode! */ - if ((dt == OB_BOUNDBOX) && (ob->mode & OB_MODE_EDIT)) - dt = OB_WIRE; - if (dt == OB_BOUNDBOX) { - draw_bounding_volume(scene, ob, ob->boundtype); + break; + case OB_CAMERA: + if (!render_override || + (rv3d->persp == RV3D_CAMOB && v3d->camera == ob)) /* special exception for active camera */ + { + drawcamera(scene, v3d, rv3d, base, dflag, ob_wire_col); } - else { - drawlattice(scene, v3d, ob); + break; + case OB_SPEAKER: + if (!render_override) + drawspeaker(scene, v3d, rv3d, ob, dflag); + break; + case OB_LATTICE: + if (!render_override) { + /* Do not allow boundbox in edit nor pose mode! */ + if ((dt == OB_BOUNDBOX) && (ob->mode & OB_MODE_EDIT)) + dt = OB_WIRE; + if (dt == OB_BOUNDBOX) { + draw_bounding_volume(scene, ob, ob->boundtype); + } + else { + drawlattice(scene, v3d, ob); + } } - } - break; - case OB_ARMATURE: - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - /* Do not allow boundbox in edit nor pose mode! */ - if ((dt == OB_BOUNDBOX) && (ob->mode & (OB_MODE_EDIT | OB_MODE_POSE))) - dt = OB_WIRE; - if (dt == OB_BOUNDBOX) { - draw_bounding_volume(scene, ob, ob->boundtype); + break; + case OB_ARMATURE: + if (!render_override) { + /* Do not allow boundbox in edit nor pose mode! */ + if ((dt == OB_BOUNDBOX) && (ob->mode & (OB_MODE_EDIT | OB_MODE_POSE))) + dt = OB_WIRE; + if (dt == OB_BOUNDBOX) { + draw_bounding_volume(scene, ob, ob->boundtype); + } + else { + if (dt > OB_WIRE) + GPU_enable_material(0, NULL); /* we use default material */ + empty_object = draw_armature(scene, v3d, ar, base, dt, dflag, ob_wire_col, false); + if (dt > OB_WIRE) + GPU_disable_material(); + } } - else { - if (dt > OB_WIRE) - GPU_enable_material(0, NULL); /* we use default material */ - empty_object = draw_armature(scene, v3d, ar, base, dt, dflag, ob_wire_col, false); - if (dt > OB_WIRE) - GPU_disable_material(); + break; + default: + if (!render_override) { + drawaxes(1.0, OB_ARROWS); } - } - break; - default: - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - drawaxes(1.0, OB_ARROWS); - } - break; - } - - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - - 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; - if ((sb = ob->soft)) { - if (sb->solverflags & SBSO_ESTIMATEIPO) { + break; + } - glLoadMatrixf(rv3d->viewmat); - copy_m3_m3(msc, sb->lscale); - copy_m3_m3(mrt, sb->lrot); - mul_m3_m3m3(mtr, mrt, msc); - ob_draw_RE_motion(sb->lcom, mtr, tipw, tiph, drawsize); - glMultMatrixf(ob->obmat); + if (!render_override) { + 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; + if ((sb = ob->soft)) { + if (sb->solverflags & SBSO_ESTIMATEIPO) { + + glLoadMatrixf(rv3d->viewmat); + copy_m3_m3(msc, sb->lscale); + copy_m3_m3(mrt, sb->lrot); + mul_m3_m3m3(mtr, mrt, msc); + ob_draw_RE_motion(sb->lcom, mtr, tipw, tiph, drawsize); + glMultMatrixf(ob->obmat); + } } } - } - if (ob->pd && ob->pd->forcefield) { - draw_forcefield(ob, rv3d, dflag, ob_wire_col); + if (ob->pd && ob->pd->forcefield) { + draw_forcefield(ob, rv3d, dflag, ob_wire_col); + } } } @@ -7156,7 +7176,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short } } - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { + if (!render_override) { if ((v3d->flag2 & V3D_NO_PHYSICS) == 0) { bConstraint *con; @@ -7213,9 +7233,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short } } - if ((dt <= OB_SOLID) && - ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0)) - { + if ((dt <= OB_SOLID) && !render_override) { if (((ob->gameflag & OB_DYNAMIC) && !ELEM(ob->collision_boundtype, OB_BOUND_TRIANGLE_MESH, OB_BOUND_CONVEX_HULL)) || @@ -7249,9 +7267,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short glDisable(GL_DEPTH_TEST); } - if ((base->flag & OB_FROMDUPLI) || - (v3d->flag2 & V3D_RENDER_OVERRIDE)) - { + if ((base->flag & OB_FROMDUPLI) || render_override) { ED_view3d_clear_mats_rv3d(rv3d); return; } @@ -7260,7 +7276,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short if (!is_obact || !(ob->mode & OB_MODE_ALL_PAINT)) { int do_draw_center = -1; /* defines below are zero or positive... */ - if (v3d->flag2 & V3D_RENDER_OVERRIDE) { + if (render_override) { /* don't draw */ } else if ((scene->basact) == base) @@ -7288,7 +7304,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short } /* not for sets, duplicators or picking */ - if (dflag == 0 && (v3d->flag & V3D_HIDE_HELPLINES) == 0 && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { + if (dflag == 0 && (v3d->flag & V3D_HIDE_HELPLINES) == 0 && !render_override) { ListBase *list; RigidBodyCon *rbc = ob->rigidbody_constraint; @@ -7437,7 +7453,7 @@ static void bbs_mesh_verts__mapFunc(void *userData, int index, const float co[3] { void **ptrs = userData; int offset = (intptr_t) ptrs[0]; - BMVert *eve = EDBM_vert_at_index(ptrs[1], index); + BMVert *eve = BM_vert_at_index(ptrs[1], index); if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { WM_framebuffer_index_set(offset + index); @@ -7446,7 +7462,7 @@ static void bbs_mesh_verts__mapFunc(void *userData, int index, const float co[3] } static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *dm, int offset) { - void *ptrs[2] = {(void *)(intptr_t) offset, em}; + void *ptrs[2] = {(void *)(intptr_t) offset, em->bm}; glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); bglBegin(GL_POINTS); @@ -7459,7 +7475,7 @@ static DMDrawOption bbs_mesh_wire__setDrawOptions(void *userData, int index) { void **ptrs = userData; int offset = (intptr_t) ptrs[0]; - BMEdge *eed = EDBM_edge_at_index(ptrs[1], index); + BMEdge *eed = BM_edge_at_index(ptrs[1], index); if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { WM_framebuffer_index_set(offset + index); @@ -7471,13 +7487,13 @@ static DMDrawOption bbs_mesh_wire__setDrawOptions(void *userData, int index) } static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *dm, int offset) { - void *ptrs[2] = {(void *)(intptr_t) offset, em}; + void *ptrs[2] = {(void *)(intptr_t) offset, em->bm}; dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOptions, ptrs); } static DMDrawOption bbs_mesh_solid__setSolidDrawOptions(void *userData, int index) { - BMFace *efa = EDBM_face_at_index(((void **)userData)[0], index); + BMFace *efa = BM_face_at_index(((void **)userData)[0], index); if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { if (((void **)userData)[1]) { @@ -7492,7 +7508,7 @@ static DMDrawOption bbs_mesh_solid__setSolidDrawOptions(void *userData, int inde static void bbs_mesh_solid__drawCenter(void *userData, int index, const float cent[3], const float UNUSED(no[3])) { - BMFace *efa = EDBM_face_at_index(((void **)userData)[0], index); + BMFace *efa = BM_face_at_index(((void **)userData)[0], index); if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { WM_framebuffer_index_set(index + 1); @@ -7505,7 +7521,7 @@ static void bbs_mesh_solid__drawCenter(void *userData, int index, const float ce static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d, Object *ob, DerivedMesh *dm, int facecol) { - void *ptrs[2] = {em, NULL}; //second one being null means to draw black + void *ptrs[2] = {em->bm, NULL}; //second one being null means to draw black cpack(0); if (facecol) { @@ -7603,7 +7619,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec DerivedMesh *dm = editbmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH); - EDBM_index_arrays_ensure(em, BM_VERT | BM_EDGE | BM_FACE); + BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE); bbs_mesh_solid_EM(em, scene, v3d, ob, dm, ts->selectmode & SCE_SELECT_FACE); if (ts->selectmode & SCE_SELECT_FACE) diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 58c0df6b6bd..b803a4a8473 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -62,6 +62,7 @@ #include "WM_types.h" #include "RE_engine.h" +#include "RE_pipeline.h" #include "RNA_access.h" @@ -271,6 +272,8 @@ void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *sa) if (rv3d && rv3d->render_engine) { WM_jobs_kill_type(wm, ar, WM_JOB_TYPE_RENDER_PREVIEW); + if (rv3d->render_engine->re) + RE_Database_Free(rv3d->render_engine->re); RE_engine_free(rv3d->render_engine); rv3d->render_engine = NULL; } @@ -840,14 +843,6 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN case ND_WORLD_DRAW: /* handled by space_view3d_listener() for v3d access */ break; - case ND_WORLD_STARS: - { - RegionView3D *rv3d = ar->regiondata; - if (rv3d->persp == RV3D_CAMOB) { - ED_region_tag_redraw(ar); - } - break; - } } break; case NC_LAMP: diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index eea084b4750..dc6f3a0274c 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -482,7 +482,15 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - add_v3_v3(eve->co, &median[LOC_X]); + if (tot == 1) { + /* In case we only have one element selected, copy directly the value instead of applying + * the diff. Avoids some glitches when going e.g. from 3 to 0.0001 (see [#37327]). + */ + copy_v3_v3(eve->co, &ve_median[LOC_X]); + } + else { + add_v3_v3(eve->co, &median[LOC_X]); + } } } @@ -623,10 +631,12 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float nu = nurbs->first; while (nu) { if (nu->type == CU_BEZIER) { - bezt = nu->bezt; - a = nu->pntsu; - while (a--) { + for (a = nu->pntsu, bezt = nu->bezt; a--; bezt++) { if (bezt->f2 & SELECT) { + /* Here we always have to use the diff... :/ + * Cannot avoid some glitches when going e.g. from 3 to 0.0001 (see [#37327]), + * unless we use doubles. + */ add_v3_v3(bezt->vec[0], &median[LOC_X]); add_v3_v3(bezt->vec[1], &median[LOC_X]); add_v3_v3(bezt->vec[2], &median[LOC_X]); @@ -647,22 +657,39 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } else { if (bezt->f1 & SELECT) { - add_v3_v3(bezt->vec[0], &median[LOC_X]); + if (tot == 1) { + copy_v3_v3(bezt->vec[0], &ve_median[LOC_X]); + } + else { + add_v3_v3(bezt->vec[0], &median[LOC_X]); + } } if (bezt->f3 & SELECT) { - add_v3_v3(bezt->vec[2], &median[LOC_X]); + if (tot == 1) { + copy_v3_v3(bezt->vec[2], &ve_median[LOC_X]); + } + else { + add_v3_v3(bezt->vec[2], &median[LOC_X]); + } } } - bezt++; } } else { - bp = nu->bp; - a = nu->pntsu * nu->pntsv; - while (a--) { + for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a--; bp++) { if (bp->f1 & SELECT) { - add_v3_v3(bp->vec, &median[LOC_X]); - bp->vec[3] += median[C_BWEIGHT]; + if (tot == 1) { + copy_v3_v3(bp->vec, &ve_median[LOC_X]); + bp->vec[3] = ve_median[C_BWEIGHT]; + bp->radius = ve_median[C_RADIUS]; + bp->alfa = ve_median[C_TILT]; + } + else { + add_v3_v3(bp->vec, &median[LOC_X]); + bp->vec[3] += median[C_BWEIGHT]; + bp->radius += median[C_RADIUS]; + bp->alfa += median[C_TILT]; + } if (median[C_WEIGHT] != 0.0f) { if (ELEM(scale_w, 0.0f, 1.0f)) { @@ -674,11 +701,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float CLAMP(bp->weight, 0.0f, 1.0f); } } - - bp->radius += median[C_RADIUS]; - bp->alfa += median[C_TILT]; } - bp++; } } BKE_nurb_test2D(nu); @@ -697,7 +720,12 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float bp = lt->editlatt->latt->def; while (a--) { if (bp->f1 & SELECT) { - add_v3_v3(bp->vec, &median[LOC_X]); + if (tot == 1) { + copy_v3_v3(bp->vec, &ve_median[LOC_X]); + } + else { + add_v3_v3(bp->vec, &median[LOC_X]); + } if (median[L_WEIGHT] != 0.0f) { if (ELEM(scale_w, 0.0f, 1.0f)) { @@ -831,7 +859,7 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) xco, yco, (x = UI_UNIT_X * 5), UI_UNIT_Y, ""); but_ptr = uiButGetOperatorPtrRNA(but); RNA_int_set(but_ptr, "weight_group", i); - uiButSetFlag(but, UI_TEXT_RIGHT); + uiButSetDrawFlag(but, UI_BUT_TEXT_RIGHT); if (ob->actdef != i + 1) { uiButSetFlag(but, UI_BUT_INACTIVE); } @@ -845,7 +873,7 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) but = uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + i, "", xco, yco, (x = UI_UNIT_X * 4), UI_UNIT_Y, &dw->weight, 0.0, 1.0, 1, 3, ""); - uiButSetFlag(but, UI_TEXT_LEFT); + uiButSetDrawFlag(but, UI_BUT_TEXT_LEFT); if (locked) { lock_count++; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index e8e4e75472f..a0943883efd 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -64,7 +64,6 @@ #include "BKE_movieclip.h" #include "RE_engine.h" -#include "RE_pipeline.h" /* make_stars */ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -107,21 +106,6 @@ extern void bl_debug_draw_quad_add(const float v0[3], const float v1[3], const f extern void bl_debug_draw_edge_add(const float v0[3], const float v1[3]); #endif -static void star_stuff_init_func(void) -{ - cpack(0xFFFFFF); - glPointSize(1.0); - glBegin(GL_POINTS); -} -static void star_stuff_vertex_func(const float vec[3]) -{ - glVertex3fv(vec); -} -static void star_stuff_term_func(void) -{ - glEnd(); -} - void circf(float x, float y, float rad) { GLUquadricObj *qobj = gluNewQuadric(); @@ -567,7 +551,7 @@ static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d) int co[2]; /* we don't want the clipping for cursor */ - if (ED_view3d_project_int_global(ar, give_cursor(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { + if (ED_view3d_project_int_global(ar, ED_view3d_cursor3d_get(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { const float f5 = 0.25f * U.widget_unit; const float f10 = 0.5f * U.widget_unit; const float f20 = U.widget_unit; @@ -2037,8 +2021,11 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas /* negative scale flag has to propagate */ transflag = tbase.object->transflag; - if (base->object->transflag & OB_NEG_SCALE) - tbase.object->transflag ^= OB_NEG_SCALE; + + if (is_negative_m4(dob->mat)) + tbase.object->transflag |= OB_NEG_SCALE; + else + tbase.object->transflag &= ~OB_NEG_SCALE; UI_ThemeColorBlend(color, TH_BACK, 0.5); @@ -2857,7 +2844,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w /* NOTE: the info that this uses is updated in ED_refresh_viewport_fps(), * which currently gets called during SCREEN_OT_animation_step. */ -static void draw_viewport_fps(Scene *scene, rcti *rect) +void ED_scene_draw_fps(Scene *scene, rcti *rect) { ScreenFrameRateInfo *fpsi = scene->fps_info; float fps; @@ -3276,14 +3263,6 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { drawfloor(scene, v3d, grid_unit); } - if (rv3d->persp == RV3D_CAMOB) { - if (scene->world) { - if (scene->world->mode & WO_STARS) { - RE_make_stars(NULL, scene, star_stuff_init_func, star_stuff_vertex_func, - star_stuff_term_func); - } - } - } } else { if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { @@ -3457,7 +3436,7 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_playing(wm)) { - draw_viewport_fps(scene, &rect); + ED_scene_draw_fps(scene, &rect); } else if (U.uiflag & USER_SHOW_VIEWPORTNAME) { draw_viewport_name(ar, v3d, &rect); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 67c9ea4599c..80e5d194d45 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -1062,11 +1062,9 @@ static int view3d_lock_poll(bContext *C) return false; } -static int viewrotate_cancel(bContext *C, wmOperator *op) +static void viewrotate_cancel(bContext *C, wmOperator *op) { viewops_data_free(C, op); - - return OPERATOR_CANCELLED; } void VIEW3D_OT_rotate(wmOperatorType *ot) @@ -1699,11 +1697,9 @@ static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event) } } -static int viewmove_cancel(bContext *C, wmOperator *op) +static void viewmove_cancel(bContext *C, wmOperator *op) { viewops_data_free(C, op); - - return OPERATOR_CANCELLED; } void VIEW3D_OT_move(wmOperatorType *ot) @@ -2091,11 +2087,9 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_FINISHED; } -static int viewzoom_cancel(bContext *C, wmOperator *op) +static void viewzoom_cancel(bContext *C, wmOperator *op) { viewops_data_free(C, op); - - return OPERATOR_CANCELLED; } void VIEW3D_OT_zoom(wmOperatorType *ot) @@ -2332,11 +2326,9 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_FINISHED; } -static int viewdolly_cancel(bContext *C, wmOperator *op) +static void viewdolly_cancel(bContext *C, wmOperator *op) { viewops_data_free(C, op); - - return OPERATOR_CANCELLED; } void VIEW3D_OT_dolly(wmOperatorType *ot) @@ -2476,7 +2468,7 @@ static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in if (center) { /* in 2.4x this also move the cursor to (0, 0, 0) (with shift+c). */ - curs = give_cursor(scene, v3d); + curs = ED_view3d_cursor3d_get(scene, v3d); zero_v3(min); zero_v3(max); zero_v3(curs); @@ -2757,7 +2749,7 @@ static int viewcenter_cursor_exec(bContext *C, wmOperator *op) /* non camera center */ float new_ofs[3]; - negate_v3_v3(new_ofs, give_cursor(scene, v3d)); + negate_v3_v3(new_ofs, ED_view3d_cursor3d_get(scene, v3d)); ED_view3d_smooth_view(C, v3d, ar, NULL, NULL, new_ofs, NULL, NULL, NULL, smooth_viewtx); @@ -3772,11 +3764,9 @@ static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_FINISHED; } -static int viewroll_cancel(bContext *C, wmOperator *op) +static void viewroll_cancel(bContext *C, wmOperator *op) { viewops_data_free(C, op); - - return OPERATOR_CANCELLED; } void VIEW3D_OT_view_roll(wmOperatorType *ot) @@ -4172,7 +4162,7 @@ static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), const wmE { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); - float *fp = give_cursor(scene, v3d); + float *fp = ED_view3d_cursor3d_get(scene, v3d); ED_view3d_cursor3d_position(C, fp, event->mval); diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index 9341ea9d3e6..373e57d5708 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -218,7 +218,7 @@ typedef struct FlyInfo { short persp_backup; /* remember if were ortho or not, only used for restoring the view if it was a ortho view */ /* are we flying an ortho camera in perspective view, - * which was originall in ortho view? + * which was originally in ortho view? * could probably figure it out but better be explicit */ bool is_ortho_cam; void *obtfm; /* backup the objects transform */ @@ -1254,15 +1254,13 @@ static int fly_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static int fly_cancel(bContext *C, wmOperator *op) +static void fly_cancel(bContext *C, wmOperator *op) { FlyInfo *fly = op->customdata; fly->state = FLY_CANCEL; flyEnd(C, fly); op->customdata = NULL; - - return OPERATOR_CANCELLED; } static int fly_modal(bContext *C, wmOperator *op, const wmEvent *event) diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index 094204f868b..204054b24cd 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -356,7 +356,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) /* masks aren't used for sculpt and particle painting */ PointerRNA meshptr; - RNA_pointer_create(&ob->id, &RNA_Mesh, ob->data, &meshptr); + RNA_pointer_create(ob->data, &RNA_Mesh, ob->data, &meshptr); if (ob->mode & (OB_MODE_TEXTURE_PAINT | OB_MODE_VERTEX_PAINT)) { uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); } diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c index 2023513ad92..4df8010be9d 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.c +++ b/source/blender/editors/space_view3d/view3d_iterators.c @@ -40,6 +40,7 @@ #include "BKE_curve.h" #include "BKE_DerivedMesh.h" #include "BKE_displist.h" +#include "BKE_editmesh.h" #include "bmesh.h" @@ -133,7 +134,7 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const flo const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) { foreachScreenVert_userData *data = userData; - BMVert *eve = EDBM_vert_at_index(data->vc.em, index); + BMVert *eve = BM_vert_at_index(data->vc.em->bm, index); if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { float screen_co[2]; @@ -165,7 +166,7 @@ void mesh_foreachScreenVert( ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ } - EDBM_index_arrays_ensure(vc->em, BM_VERT); + BM_mesh_elem_table_ensure(vc->em->bm, BM_VERT); dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data, DM_FOREACH_NOP); dm->release(dm); @@ -176,7 +177,7 @@ void mesh_foreachScreenVert( static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const float v0co[3], const float v1co[3]) { foreachScreenEdge_userData *data = userData; - BMEdge *eed = EDBM_edge_at_index(data->vc.em, index); + BMEdge *eed = BM_edge_at_index(data->vc.em->bm, index); if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { float screen_co_a[2]; @@ -225,7 +226,7 @@ void mesh_foreachScreenEdge( ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ } - EDBM_index_arrays_ensure(vc->em, BM_EDGE); + BM_mesh_elem_table_ensure(vc->em->bm, BM_EDGE); dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data); dm->release(dm); @@ -236,7 +237,7 @@ void mesh_foreachScreenEdge( static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3])) { foreachScreenFace_userData *data = userData; - BMFace *efa = EDBM_face_at_index(data->vc.em, index); + BMFace *efa = BM_face_at_index(data->vc.em->bm, index); if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { float screen_co[2]; @@ -261,7 +262,7 @@ void mesh_foreachScreenFace( data.userData = userData; data.clip_flag = clip_flag; - EDBM_index_arrays_ensure(vc->em, BM_FACE); + BM_mesh_elem_table_ensure(vc->em->bm, BM_FACE); dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data, DM_FOREACH_NOP); dm->release(dm); diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c index bca162d156b..288ada3f852 100644 --- a/source/blender/editors/space_view3d/view3d_ruler.c +++ b/source/blender/editors/space_view3d/view3d_ruler.c @@ -809,15 +809,13 @@ static int view3d_ruler_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE return OPERATOR_RUNNING_MODAL; } -static int view3d_ruler_cancel(bContext *C, wmOperator *op) +static void view3d_ruler_cancel(bContext *C, wmOperator *op) { RulerInfo *ruler_info = op->customdata; view3d_ruler_end(C, ruler_info); view3d_ruler_free(ruler_info); op->customdata = NULL; - - return OPERATOR_CANCELLED; } static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event) diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index c48ce8a2343..a6ef70a5e33 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -89,6 +89,7 @@ #include "ED_mesh.h" #include "ED_object.h" #include "ED_screen.h" +#include "ED_sculpt.h" #include "ED_mball.h" #include "UI_interface.h" @@ -272,9 +273,6 @@ static int view3d_selectable_data(bContext *C) } } else { - if (ob->mode & OB_MODE_SCULPT) { - return 0; - } if ((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) && !paint_facesel_test(ob) && !paint_vertsel_test(ob)) { @@ -1374,13 +1372,15 @@ static void deselect_all_tracks(MovieTracking *tracking) } /* mval is region coords */ -static bool mouse_select(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle, bool obcenter, short enumerate) +static bool mouse_select(bContext *C, const int mval[2], + bool extend, bool deselect, bool toggle, bool obcenter, bool enumerate, bool object) { ViewContext vc; ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); Base *base, *startbase = NULL, *basact = NULL, *oldbasact = NULL; + bool is_obedit; float dist = 100.0f; int retval = false; short hits; @@ -1389,6 +1389,12 @@ static bool mouse_select(bContext *C, const int mval[2], bool extend, bool desel /* setup view context for argument to callbacks */ view3d_set_viewcontext(C, &vc); + + is_obedit = (vc.obedit != NULL); + if (object) { + /* signal for view3d_opengl_select to skip editmode objects */ + vc.obedit = NULL; + } /* always start list from basact in wire mode */ startbase = FIRSTBASE; @@ -1564,7 +1570,7 @@ static bool mouse_select(bContext *C, const int mval[2], bool extend, bool desel ED_base_object_select(basact, BA_SELECT); } - if (oldbasact != basact) { + if ((oldbasact != basact) && (is_obedit == false)) { ED_base_object_activate(C, basact); /* adds notifier */ } } @@ -2117,7 +2123,7 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op) } else { /* no editmode, unified for bones and objects */ if (vc.obact && vc.obact->mode & OB_MODE_SCULPT) { - /* pass */ + ret = do_sculpt_mask_box_select(&vc, &rect, select, extend); } else if (vc.obact && paint_facesel_test(vc.obact)) { ret = do_paintface_box_select(&vc, &rect, select, extend); @@ -2256,7 +2262,7 @@ static int view3d_select_exec(bContext *C, wmOperator *op) else if (paint_vertsel_test(obact)) retval = mouse_weight_paint_vertex_select(C, location, extend, deselect, toggle, obact); else - retval = mouse_select(C, location, extend, deselect, toggle, center, enumerate); + retval = mouse_select(C, location, extend, deselect, toggle, center, enumerate, object); /* passthrough allows tweaks * FINISHED to signal one operator worked diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 7c29ab01c24..25458613842 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -30,35 +30,21 @@ */ -#include <math.h> -#include <string.h> - -#include "MEM_guardedalloc.h" - #include "DNA_armature_types.h" #include "DNA_curve_types.h" -#include "DNA_lattice_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meta_types.h" -#include "DNA_scene_types.h" #include "DNA_object_types.h" #include "BLI_blenlib.h" -#include "BLI_math.h" -#include "BLI_linklist.h" #include "BLI_utildefines.h" +#include "BLI_math.h" #include "BKE_armature.h" #include "BKE_context.h" -#include "BKE_curve.h" #include "BKE_depsgraph.h" #include "BKE_lattice.h" -#include "BKE_main.h" #include "BKE_mball.h" #include "BKE_object.h" #include "BKE_editmesh.h" -#include "BKE_DerivedMesh.h" -#include "BKE_scene.h" #include "BKE_tracking.h" #include "WM_api.h" @@ -67,468 +53,14 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "ED_armature.h" -#include "ED_mesh.h" +#include "ED_transverts.h" #include "ED_keyframing.h" #include "ED_screen.h" -#include "ED_curve.h" /* for curve_editnurbs */ #include "view3d_intern.h" -/* ************************************************** */ -/* ********************* old transform stuff ******** */ -/* *********** will get replaced with new transform * */ -/* ************************************************** */ - static bool snap_curs_to_sel_ex(bContext *C, float cursor[3]); -typedef struct TransVert { - float *loc; - float oldloc[3], maploc[3]; - float *val, oldval; - int flag; -} TransVert; - - /* SELECT == (1 << 0) */ -#define TX_VERT_USE_MAPLOC (1 << 1) - -static TransVert *transvmain = NULL; -static int tottrans = 0; - -/* copied from editobject.c, now uses (almost) proper depgraph */ -static void special_transvert_update(Object *obedit) -{ - if (obedit) { - DAG_id_tag_update(obedit->data, 0); - - if (obedit->type == OB_MESH) { - BMEditMesh *em = BKE_editmesh_from_object(obedit); - BM_mesh_normals_update(em->bm); - } - else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { - Curve *cu = obedit->data; - ListBase *nurbs = BKE_curve_editNurbs_get(cu); - Nurb *nu = nurbs->first; - - while (nu) { - /* keep handles' vectors unchanged */ - if (nu->bezt) { - int a = nu->pntsu; - TransVert *tv = transvmain; - BezTriple *bezt = nu->bezt; - - while (a--) { - if (bezt->f1 & SELECT) tv++; - - if (bezt->f2 & SELECT) { - float v[3]; - - if (bezt->f1 & SELECT) { - sub_v3_v3v3(v, (tv - 1)->oldloc, tv->oldloc); - add_v3_v3v3(bezt->vec[0], bezt->vec[1], v); - } - - if (bezt->f3 & SELECT) { - sub_v3_v3v3(v, (tv + 1)->oldloc, tv->oldloc); - add_v3_v3v3(bezt->vec[2], bezt->vec[1], v); - } - - tv++; - } - - if (bezt->f3 & SELECT) tv++; - - bezt++; - } - } - - BKE_nurb_test2D(nu); - BKE_nurb_handles_test(nu, true); /* test for bezier too */ - nu = nu->next; - } - } - else if (obedit->type == OB_ARMATURE) { - bArmature *arm = obedit->data; - EditBone *ebo; - TransVert *tv = transvmain; - int a = 0; - - /* Ensure all bone tails are correctly adjusted */ - for (ebo = arm->edbo->first; ebo; ebo = ebo->next) { - /* adjust tip if both ends selected */ - if ((ebo->flag & BONE_ROOTSEL) && (ebo->flag & BONE_TIPSEL)) { - if (tv) { - float diffvec[3]; - - sub_v3_v3v3(diffvec, tv->loc, tv->oldloc); - add_v3_v3(ebo->tail, diffvec); - - a++; - if (a < tottrans) tv++; - } - } - } - - /* Ensure all bones are correctly adjusted */ - for (ebo = arm->edbo->first; ebo; ebo = ebo->next) { - if ((ebo->flag & BONE_CONNECTED) && ebo->parent) { - /* If this bone has a parent tip that has been moved */ - if (ebo->parent->flag & BONE_TIPSEL) { - copy_v3_v3(ebo->head, ebo->parent->tail); - } - /* If this bone has a parent tip that has NOT been moved */ - else { - copy_v3_v3(ebo->parent->tail, ebo->head); - } - } - } - if (arm->flag & ARM_MIRROR_EDIT) - transform_armature_mirror_update(obedit); - } - else if (obedit->type == OB_LATTICE) { - Lattice *lt = obedit->data; - - if (lt->editlatt->latt->flag & LT_OUTSIDE) - outside_lattice(lt->editlatt->latt); - } - } -} - -/* currently only used for bmesh index values */ -enum { - TM_INDEX_ON = 1, /* tag to make trans verts */ - TM_INDEX_OFF = 0, /* don't make verts */ - TM_INDEX_SKIP = -1 /* dont make verts (when the index values point to trans-verts) */ -}; - -/* copied from editobject.c, needs to be replaced with new transform code still */ -/* mode flags: */ -enum { - TM_ALL_JOINTS = 1, /* all joints (for bones only) */ - TM_SKIP_HANDLES = 2 /* skip handles when control point is selected (for curves only) */ -}; - -static void set_mapped_co(void *vuserdata, int index, const float co[3], - const float UNUSED(no[3]), const short UNUSED(no_s[3])) -{ - void **userdata = vuserdata; - BMEditMesh *em = userdata[0]; - TransVert *tv = userdata[1]; - BMVert *eve = EDBM_vert_at_index(em, index); - - if (BM_elem_index_get(eve) != TM_INDEX_SKIP) { - tv = &tv[BM_elem_index_get(eve)]; - - /* be clever, get the closest vertex to the original, - * behaves most logically when the mirror modifier is used for eg [#33051]*/ - if ((tv->flag & TX_VERT_USE_MAPLOC) == 0) { - /* first time */ - copy_v3_v3(tv->maploc, co); - tv->flag |= TX_VERT_USE_MAPLOC; - } - else { - /* find best location to use */ - if (len_squared_v3v3(eve->co, co) < len_squared_v3v3(eve->co, tv->maploc)) { - copy_v3_v3(tv->maploc, co); - } - } - } -} - -static void make_trans_verts(Object *obedit, float min[3], float max[3], int mode) -{ - Nurb *nu; - BezTriple *bezt; - BPoint *bp; - TransVert *tv = NULL; - MetaElem *ml; - BMVert *eve; - EditBone *ebo; - float total, center[3], centroid[3]; - int a; - - tottrans = 0; /* global! */ - - INIT_MINMAX(min, max); - zero_v3(centroid); - - if (obedit->type == OB_MESH) { - BMEditMesh *em = BKE_editmesh_from_object(obedit); - BMesh *bm = em->bm; - BMIter iter; - void *userdata[2] = {em, NULL}; - /*int proptrans = 0; */ /*UNUSED*/ - - /* abuses vertex index all over, set, just set dirty here, - * perhaps this could use its own array instead? - campbell */ - - /* transform now requires awareness for select mode, so we tag the f1 flags in verts */ - tottrans = 0; - if (em->selectmode & SCE_SELECT_VERTEX) { - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - BM_elem_index_set(eve, TM_INDEX_ON); /* set_dirty! */ - tottrans++; - } - else { - BM_elem_index_set(eve, TM_INDEX_OFF); /* set_dirty! */ - } - } - } - else if (em->selectmode & SCE_SELECT_EDGE) { - BMEdge *eed; - - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - BM_elem_index_set(eve, TM_INDEX_OFF); /* set_dirty! */ - } - - BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - BM_elem_index_set(eed->v1, TM_INDEX_ON); /* set_dirty! */ - BM_elem_index_set(eed->v2, TM_INDEX_ON); /* set_dirty! */ - } - } - - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - if (BM_elem_index_get(eve) == TM_INDEX_ON) tottrans++; - } - } - else { - BMFace *efa; - - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - BM_elem_index_set(eve, TM_INDEX_OFF); /* set_dirty! */ - } - - BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { - if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && BM_elem_flag_test(efa, BM_ELEM_SELECT)) { - BMIter liter; - BMLoop *l; - - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - BM_elem_index_set(l->v, TM_INDEX_ON); /* set_dirty! */ - } - } - } - - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - if (BM_elem_index_get(eve) == TM_INDEX_ON) tottrans++; - } - } - /* for any of the 3 loops above which all dirty the indices */ - bm->elem_index_dirty |= BM_VERT; - - /* and now make transverts */ - if (tottrans) { - tv = transvmain = MEM_callocN(tottrans * sizeof(TransVert), "maketransverts"); - - a = 0; - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - if (BM_elem_index_get(eve)) { - BM_elem_index_set(eve, a); /* set_dirty! */ - copy_v3_v3(tv->oldloc, eve->co); - tv->loc = eve->co; - tv->flag = (BM_elem_index_get(eve) == TM_INDEX_ON) ? SELECT : 0; - tv++; - a++; - } - else { - BM_elem_index_set(eve, TM_INDEX_SKIP); /* set_dirty! */ - } - } - /* set dirty already, above */ - - userdata[1] = transvmain; - } - - if (transvmain && em->derivedCage) { - EDBM_index_arrays_ensure(em, BM_VERT); - em->derivedCage->foreachMappedVert(em->derivedCage, set_mapped_co, userdata, DM_FOREACH_NOP); - } - } - else if (obedit->type == OB_ARMATURE) { - bArmature *arm = obedit->data; - int totmalloc = BLI_countlist(arm->edbo); - - totmalloc *= 2; /* probably overkill but bones can have 2 trans verts each */ - - tv = transvmain = MEM_callocN(totmalloc * sizeof(TransVert), "maketransverts armature"); - - for (ebo = arm->edbo->first; ebo; ebo = ebo->next) { - if (ebo->layer & arm->layer) { - short tipsel = (ebo->flag & BONE_TIPSEL); - short rootsel = (ebo->flag & BONE_ROOTSEL); - short rootok = (!(ebo->parent && (ebo->flag & BONE_CONNECTED) && (ebo->parent->flag & BONE_TIPSEL))); - - if ((tipsel && rootsel) || (rootsel)) { - /* Don't add the tip (unless mode & TM_ALL_JOINTS, for getting all joints), - * otherwise we get zero-length bones as tips will snap to the same - * location as heads. - */ - if (rootok) { - copy_v3_v3(tv->oldloc, ebo->head); - tv->loc = ebo->head; - tv->flag = SELECT; - tv++; - tottrans++; - } - - if ((mode & TM_ALL_JOINTS) && (tipsel)) { - copy_v3_v3(tv->oldloc, ebo->tail); - tv->loc = ebo->tail; - tv->flag = SELECT; - tv++; - tottrans++; - } - } - else if (tipsel) { - copy_v3_v3(tv->oldloc, ebo->tail); - tv->loc = ebo->tail; - tv->flag = SELECT; - tv++; - tottrans++; - } - } - } - } - else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { - Curve *cu = obedit->data; - int totmalloc = 0; - ListBase *nurbs = BKE_curve_editNurbs_get(cu); - - for (nu = nurbs->first; nu; nu = nu->next) { - if (nu->type == CU_BEZIER) - totmalloc += 3 * nu->pntsu; - else - totmalloc += nu->pntsu * nu->pntsv; - } - tv = transvmain = MEM_callocN(totmalloc * sizeof(TransVert), "maketransverts curve"); - - nu = nurbs->first; - while (nu) { - if (nu->type == CU_BEZIER) { - a = nu->pntsu; - bezt = nu->bezt; - while (a--) { - if (bezt->hide == 0) { - int skip_handle = 0; - if (bezt->f2 & SELECT) - skip_handle = mode & TM_SKIP_HANDLES; - - if ((bezt->f1 & SELECT) && !skip_handle) { - copy_v3_v3(tv->oldloc, bezt->vec[0]); - tv->loc = bezt->vec[0]; - tv->flag = bezt->f1 & SELECT; - tv++; - tottrans++; - } - if (bezt->f2 & SELECT) { - copy_v3_v3(tv->oldloc, bezt->vec[1]); - tv->loc = bezt->vec[1]; - tv->val = &(bezt->alfa); - tv->oldval = bezt->alfa; - tv->flag = bezt->f2 & SELECT; - tv++; - tottrans++; - } - if ((bezt->f3 & SELECT) && !skip_handle) { - copy_v3_v3(tv->oldloc, bezt->vec[2]); - tv->loc = bezt->vec[2]; - tv->flag = bezt->f3 & SELECT; - tv++; - tottrans++; - } - } - bezt++; - } - } - else { - a = nu->pntsu * nu->pntsv; - bp = nu->bp; - while (a--) { - if (bp->hide == 0) { - if (bp->f1 & SELECT) { - copy_v3_v3(tv->oldloc, bp->vec); - tv->loc = bp->vec; - tv->val = &(bp->alfa); - tv->oldval = bp->alfa; - tv->flag = bp->f1 & SELECT; - tv++; - tottrans++; - } - } - bp++; - } - } - nu = nu->next; - } - } - else if (obedit->type == OB_MBALL) { - MetaBall *mb = obedit->data; - int totmalloc = BLI_countlist(mb->editelems); - - tv = transvmain = MEM_callocN(totmalloc * sizeof(TransVert), "maketransverts mball"); - - ml = mb->editelems->first; - while (ml) { - if (ml->flag & SELECT) { - tv->loc = &ml->x; - copy_v3_v3(tv->oldloc, tv->loc); - tv->val = &(ml->rad); - tv->oldval = ml->rad; - tv->flag = SELECT; - tv++; - tottrans++; - } - ml = ml->next; - } - } - else if (obedit->type == OB_LATTICE) { - Lattice *lt = obedit->data; - - bp = lt->editlatt->latt->def; - - a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; - - tv = transvmain = MEM_callocN(a * sizeof(TransVert), "maketransverts latt"); - - while (a--) { - if (bp->f1 & SELECT) { - if (bp->hide == 0) { - copy_v3_v3(tv->oldloc, bp->vec); - tv->loc = bp->vec; - tv->flag = bp->f1 & SELECT; - tv++; - tottrans++; - } - } - bp++; - } - } - - if (!tottrans && transvmain) { - /* prevent memory leak. happens for curves/latticies due to */ - /* difficult condition of adding points to trans data */ - MEM_freeN(transvmain); - transvmain = NULL; - } - - /* cent etc */ - tv = transvmain; - total = 0.0; - for (a = 0; a < tottrans; a++, tv++) { - if (tv->flag & SELECT) { - add_v3_v3(centroid, tv->oldloc); - total += 1.0f; - minmax_v3v3_v3(min, max, tv->oldloc); - } - } - if (total != 0.0f) { - mul_v3_fl(centroid, 1.0f / total); - } - - mid_v3_v3v3(center, min, max); -} /* *********************** operators ******************** */ @@ -537,6 +69,7 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) Object *obedit = CTX_data_edit_object(C); Scene *scene = CTX_data_scene(C); RegionView3D *rv3d = CTX_wm_region_data(C); + TransVertStore tvs = {NULL}; TransVert *tv; float gridf, imat[3][3], bmat[3][3], vec[3]; int a; @@ -544,17 +77,16 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) gridf = rv3d->gridview; if (obedit) { - tottrans = 0; - - if (ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL)) - make_trans_verts(obedit, bmat[0], bmat[1], 0); - if (tottrans == 0) return OPERATOR_CANCELLED; - + if (ED_transverts_check_obedit(obedit)) + ED_transverts_create_from_obedit(&tvs, obedit, 0); + if (tvs.transverts_tot == 0) + return OPERATOR_CANCELLED; + copy_m3_m4(bmat, obedit->obmat); invert_m3_m3(imat, bmat); - tv = transvmain; - for (a = 0; a < tottrans; a++, tv++) { + tv = tvs.transverts; + for (a = 0; a < tvs.transverts_tot; a++, tv++) { copy_v3_v3(vec, tv->loc); mul_m3_v3(bmat, vec); add_v3_v3(vec, obedit->obmat[3]); @@ -567,10 +99,8 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) copy_v3_v3(tv->loc, vec); } - special_transvert_update(obedit); - - MEM_freeN(transvmain); - transvmain = NULL; + ED_transverts_update_obedit(&tvs, obedit); + ED_transverts_free(&tvs); } else { struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID); @@ -593,9 +123,9 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) copy_v3_v3(nLoc, pchan->pose_mat[3]); /* We must operate in world space! */ mul_m4_v3(ob->obmat, nLoc); - vec[0] = gridf * (float)(floor(0.5f + nLoc[0] / gridf)); - vec[1] = gridf * (float)(floor(0.5f + nLoc[1] / gridf)); - vec[2] = gridf * (float)(floor(0.5f + nLoc[2] / gridf)); + vec[0] = gridf * floorf(0.5f + nLoc[0] / gridf); + vec[1] = gridf * floorf(0.5f + nLoc[1] / gridf); + vec[2] = gridf * floorf(0.5f + nLoc[2] / gridf); /* Back in object space... */ mul_m4_v3(ob->imat, vec); @@ -678,6 +208,7 @@ static int snap_sel_to_curs_exec(bContext *C, wmOperator *op) Object *obedit = CTX_data_edit_object(C); Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); + TransVertStore tvs = {NULL}; TransVert *tv; float imat[3][3], bmat[3][3]; const float *cursor_global; @@ -687,7 +218,7 @@ static int snap_sel_to_curs_exec(bContext *C, wmOperator *op) const bool use_offset = RNA_boolean_get(op->ptr, "use_offset"); - cursor_global = give_cursor(scene, v3d); + cursor_global = ED_view3d_cursor3d_get(scene, v3d); if (use_offset) { snap_curs_to_sel_ex(C, center_global); @@ -696,13 +227,12 @@ static int snap_sel_to_curs_exec(bContext *C, wmOperator *op) if (obedit) { float cursor_local[3]; - - tottrans = 0; - - if (ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL)) - make_trans_verts(obedit, bmat[0], bmat[1], 0); - if (tottrans == 0) return OPERATOR_CANCELLED; + if (ED_transverts_check_obedit(obedit)) + ED_transverts_create_from_obedit(&tvs, obedit, 0); + if (tvs.transverts_tot == 0) + return OPERATOR_CANCELLED; + copy_m3_m4(bmat, obedit->obmat); invert_m3_m3(imat, bmat); @@ -715,22 +245,20 @@ static int snap_sel_to_curs_exec(bContext *C, wmOperator *op) mul_v3_m3v3(offset_local, imat, offset_global); - tv = transvmain; - for (a = 0; a < tottrans; a++, tv++) { + tv = tvs.transverts; + for (a = 0; a < tvs.transverts_tot; a++, tv++) { add_v3_v3(tv->loc, offset_local); } } else { - tv = transvmain; - for (a = 0; a < tottrans; a++, tv++) { + tv = tvs.transverts; + for (a = 0; a < tvs.transverts_tot; a++, tv++) { copy_v3_v3(tv->loc, cursor_local); } } - special_transvert_update(obedit); - - MEM_freeN(transvmain); - transvmain = NULL; + ED_transverts_update_obedit(&tvs, obedit); + ED_transverts_free(&tvs); } else { struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID); @@ -852,7 +380,7 @@ static int snap_curs_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) float gridf, *curs; gridf = rv3d->gridview; - curs = give_cursor(scene, v3d); + curs = ED_view3d_cursor3d_get(scene, v3d); curs[0] = gridf * floorf(0.5f + curs[0] / gridf); curs[1] = gridf * floorf(0.5f + curs[1] / gridf); @@ -937,6 +465,7 @@ static bool snap_curs_to_sel_ex(bContext *C, float cursor[3]) Object *obedit = CTX_data_edit_object(C); Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); + TransVertStore tvs = {NULL}; TransVert *tv; float bmat[3][3], vec[3], min[3], max[3], centroid[3]; int count, a; @@ -946,19 +475,18 @@ static bool snap_curs_to_sel_ex(bContext *C, float cursor[3]) zero_v3(centroid); if (obedit) { - tottrans = 0; - if (ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL)) - make_trans_verts(obedit, bmat[0], bmat[1], TM_ALL_JOINTS | TM_SKIP_HANDLES); + if (ED_transverts_check_obedit(obedit)) + ED_transverts_create_from_obedit(&tvs, obedit, TM_ALL_JOINTS | TM_SKIP_HANDLES); - if (tottrans == 0) { + if (tvs.transverts_tot == 0) { return false; } copy_m3_m4(bmat, obedit->obmat); - tv = transvmain; - for (a = 0; a < tottrans; a++, tv++) { + tv = tvs.transverts; + for (a = 0; a < tvs.transverts_tot; a++, tv++) { copy_v3_v3(vec, tv->loc); mul_m3_v3(bmat, vec); add_v3_v3(vec, obedit->obmat[3]); @@ -967,14 +495,14 @@ static bool snap_curs_to_sel_ex(bContext *C, float cursor[3]) } if (v3d->around == V3D_CENTROID) { - mul_v3_fl(centroid, 1.0f / (float)tottrans); + mul_v3_fl(centroid, 1.0f / (float)tvs.transverts_tot); copy_v3_v3(cursor, centroid); } else { mid_v3_v3v3(cursor, min, max); } - MEM_freeN(transvmain); - transvmain = NULL; + + ED_transverts_free(&tvs); } else { Object *obact = CTX_data_active_object(C); @@ -1035,7 +563,7 @@ static int snap_curs_to_sel_exec(bContext *C, wmOperator *UNUSED(op)) View3D *v3d = CTX_wm_view3d(C); float *curs; - curs = give_cursor(scene, v3d); + curs = ED_view3d_cursor3d_get(scene, v3d); if (snap_curs_to_sel_ex(C, curs)) { WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); @@ -1072,7 +600,7 @@ static int snap_curs_to_active_exec(bContext *C, wmOperator *UNUSED(op)) View3D *v3d = CTX_wm_view3d(C); float *curs; - curs = give_cursor(scene, v3d); + curs = ED_view3d_cursor3d_get(scene, v3d); if (obedit) { if (obedit->type == OB_MESH) { @@ -1127,7 +655,7 @@ static int snap_curs_to_center_exec(bContext *C, wmOperator *UNUSED(op)) Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); float *curs; - curs = give_cursor(scene, v3d); + curs = ED_view3d_cursor3d_get(scene, v3d); zero_v3(curs); @@ -1156,6 +684,7 @@ void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot) bool ED_view3d_minmax_verts(Object *obedit, float min[3], float max[3]) { + TransVertStore tvs = {NULL}; TransVert *tv; float centroid[3], vec[3], bmat[3][3]; int a; @@ -1173,16 +702,16 @@ bool ED_view3d_minmax_verts(Object *obedit, float min[3], float max[3]) return change; } - tottrans = 0; - if (ELEM5(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE)) - make_trans_verts(obedit, bmat[0], bmat[1], TM_ALL_JOINTS); + if (ED_transverts_check_obedit(obedit)) + ED_transverts_create_from_obedit(&tvs, obedit, TM_ALL_JOINTS); - if (tottrans == 0) return false; + if (tvs.transverts_tot == 0) + return false; copy_m3_m4(bmat, obedit->obmat); - tv = transvmain; - for (a = 0; a < tottrans; a++, tv++) { + tv = tvs.transverts; + for (a = 0; a < tvs.transverts_tot; a++, tv++) { copy_v3_v3(vec, (tv->flag & TX_VERT_USE_MAPLOC) ? tv->maploc : tv->loc); mul_m3_v3(bmat, vec); add_v3_v3(vec, obedit->obmat[3]); @@ -1190,8 +719,7 @@ bool ED_view3d_minmax_verts(Object *obedit, float min[3], float max[3]) minmax_v3v3_v3(min, max, vec); } - MEM_freeN(transvmain); - transvmain = NULL; + ED_transverts_free(&tvs); return true; } diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 74d72061995..e321e7c9c4b 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -104,7 +104,7 @@ void view3d_region_operator_needs_opengl(wmWindow *win, ARegion *ar) } } -float *give_cursor(Scene *scene, View3D *v3d) +float *ED_view3d_cursor3d_get(Scene *scene, View3D *v3d) { if (v3d && v3d->localvd) return v3d->cursor; else return scene->cursor; @@ -774,33 +774,31 @@ static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob) mat3_to_quat(rv3d->viewquat, tmat); } -#define QUATSET(a, b, c, d, e) { a[0] = b; a[1] = c; a[2] = d; a[3] = e; } (void)0 - bool ED_view3d_lock(RegionView3D *rv3d) { switch (rv3d->view) { case RV3D_VIEW_BOTTOM: - QUATSET(rv3d->viewquat, 0.0, -1.0, 0.0, 0.0); + copy_v4_fl4(rv3d->viewquat, 0.0, -1.0, 0.0, 0.0); break; case RV3D_VIEW_BACK: - QUATSET(rv3d->viewquat, 0.0, 0.0, -M_SQRT1_2, -M_SQRT1_2); + copy_v4_fl4(rv3d->viewquat, 0.0, 0.0, -M_SQRT1_2, -M_SQRT1_2); break; case RV3D_VIEW_LEFT: - QUATSET(rv3d->viewquat, 0.5, -0.5, 0.5, 0.5); + copy_v4_fl4(rv3d->viewquat, 0.5, -0.5, 0.5, 0.5); break; case RV3D_VIEW_TOP: - QUATSET(rv3d->viewquat, 1.0, 0.0, 0.0, 0.0); + copy_v4_fl4(rv3d->viewquat, 1.0, 0.0, 0.0, 0.0); break; case RV3D_VIEW_FRONT: - QUATSET(rv3d->viewquat, M_SQRT1_2, -M_SQRT1_2, 0.0, 0.0); + copy_v4_fl4(rv3d->viewquat, M_SQRT1_2, -M_SQRT1_2, 0.0, 0.0); break; case RV3D_VIEW_RIGHT: - QUATSET(rv3d->viewquat, 0.5, -0.5, -0.5, -0.5); + copy_v4_fl4(rv3d->viewquat, 0.5, -0.5, -0.5, -0.5); break; default: return false; @@ -849,7 +847,7 @@ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d) } else if (v3d->ob_centre_cursor) { float vec[3]; - copy_v3_v3(vec, give_cursor(scene, v3d)); + copy_v3_v3(vec, ED_view3d_cursor3d_get(scene, v3d)); translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]); use_lock_ofs = true; } @@ -876,10 +874,12 @@ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d) } } -/* IGLuint-> GLuint */ -/* Warning: be sure to account for a negative return value - * This is an error, "Too many objects in select buffer" - * and no action should be taken (can crash blender) if this happens +/** + * \warning be sure to account for a negative return value + * This is an error, "Too many objects in select buffer" + * and no action should be taken (can crash blender) if this happens + * + * \note (vc->obedit == NULL) can be set to explicitly skip edit-object selection. */ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int bufsize, rcti *input) { @@ -890,6 +890,7 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b short code, hits; char dt; short dtx; + const bool use_obedit_skip = (scene->obedit != NULL) && (vc->obedit == NULL); G.f |= G_PICKSEL; @@ -937,8 +938,11 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b for (base = scene->base.first; base; base = base->next) { if (base->lay & v3d->lay) { - if (base->object->restrictflag & OB_RESTRICT_SELECT) + if ((base->object->restrictflag & OB_RESTRICT_SELECT) || + (use_obedit_skip && (scene->obedit->data == base->object->data))) + { base->selcol = 0; + } else { base->selcol = code; glLoadName(code); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index ea039c15be4..2756685e9f6 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -82,6 +82,7 @@ #include "ED_mesh.h" #include "ED_clip.h" #include "ED_mask.h" +#include "ED_node.h" #include "WM_types.h" #include "WM_api.h" @@ -108,6 +109,95 @@ static void drawVertSlide(const struct bContext *C, TransInfo *t); static void len_v3_ensure(float v[3], const float length); static void postInputRotation(TransInfo *t, float values[3]); + +/* Transform Callbacks */ +static void initBend(TransInfo *t); +static eRedrawFlag handleEventBend(TransInfo *t, const struct wmEvent *event); +static void Bend(TransInfo *t, const int mval[2]); + +static void initShear(TransInfo *t); +static eRedrawFlag handleEventShear(TransInfo *t, const struct wmEvent *event); +static void applyShear(TransInfo *t, const int mval[2]); + +static void initResize(TransInfo *t); +static void applyResize(TransInfo *t, const int mval[2]); + +static void initSkinResize(TransInfo *t); +static void applySkinResize(TransInfo *t, const int mval[2]); + +static void initTranslation(TransInfo *t); +static void applyTranslation(TransInfo *t, const int mval[2]); + +static void initToSphere(TransInfo *t); +static void applyToSphere(TransInfo *t, const int mval[2]); + +static void initRotation(TransInfo *t); +static void applyRotation(TransInfo *t, const int mval[2]); + +static void initShrinkFatten(TransInfo *t); +static void applyShrinkFatten(TransInfo *t, const int mval[2]); + +static void initTilt(TransInfo *t); +static void applyTilt(TransInfo *t, const int mval[2]); + +static void initCurveShrinkFatten(TransInfo *t); +static void applyCurveShrinkFatten(TransInfo *t, const int mval[2]); + +static void initMaskShrinkFatten(TransInfo *t); +static void applyMaskShrinkFatten(TransInfo *t, const int mval[2]); + +static void initTrackball(TransInfo *t); +static void applyTrackball(TransInfo *t, const int mval[2]); + +static void initPushPull(TransInfo *t); +static void applyPushPull(TransInfo *t, const int mval[2]); + +static void initBevelWeight(TransInfo *t); +static void applyBevelWeight(TransInfo *t, const int mval[2]); + +static void initCrease(TransInfo *t); +static void applyCrease(TransInfo *t, const int mval[2]); + +static void initBoneSize(TransInfo *t); +static void applyBoneSize(TransInfo *t, const int mval[2]); + +static void initBoneEnvelope(TransInfo *t); +static void applyBoneEnvelope(TransInfo *t, const int mval[2]); + +static void initBoneRoll(TransInfo *t); +static void applyBoneRoll(TransInfo *t, const int mval[2]); + +static void initEdgeSlide(TransInfo *t); +static eRedrawFlag handleEventEdgeSlide(TransInfo *t, const struct wmEvent *event); +static void applyEdgeSlide(TransInfo *t, const int mval[2]); + +static void initVertSlide(TransInfo *t); +static eRedrawFlag handleEventVertSlide(TransInfo *t, const struct wmEvent *event); +static void applyVertSlide(TransInfo *t, const int mval[2]); + +static void initTimeTranslate(TransInfo *t); +static void applyTimeTranslate(TransInfo *t, const int mval[2]); + +static void initTimeSlide(TransInfo *t); +static void applyTimeSlide(TransInfo *t, const int mval[2]); + +static void initTimeScale(TransInfo *t); +static void applyTimeScale(TransInfo *t, const int mval[2]); + +static void initBakeTime(TransInfo *t); +static void applyBakeTime(TransInfo *t, const int mval[2]); + +static void initMirror(TransInfo *t); +static void applyMirror(TransInfo *t, const int mval[2]); + +static void initAlign(TransInfo *t); +static void applyAlign(TransInfo *t, const int mval[2]); + +static void initSeqSlide(TransInfo *t); +static void applySeqSlide(TransInfo *t, const int mval[2]); +/* end transform callbacks */ + + static bool transdata_check_local_center(TransInfo *t) { return ((t->around == V3D_LOCAL) && ( @@ -1131,8 +1221,10 @@ int transformEvent(TransInfo *t, const wmEvent *event) break; } - // Modal numinput events - t->redraw |= handleNumInput(&(t->num), event); + /* Modal numinput events */ + if (handleNumInput(&(t->num), event)) { + t->redraw |= TREDRAW_HARD; + } } /* else do non-mapped events */ else if (event->val == KM_PRESS) { @@ -1236,7 +1328,7 @@ int transformEvent(TransInfo *t, const wmEvent *event) t->flag ^= T_PROP_CONNECTED; sort_trans_data_dist(t); calculatePropRatio(t); - t->redraw = 1; + t->redraw = TREDRAW_HARD; } else { stopConstraint(t); @@ -1262,7 +1354,7 @@ int transformEvent(TransInfo *t, const wmEvent *event) t->prop_size = min_ff(t->prop_size, ((View3D *)t->view)->far); calculatePropRatio(t); } - t->redraw = 1; + t->redraw = TREDRAW_HARD; break; case PAGEUPKEY: case WHEELDOWNMOUSE: @@ -1272,14 +1364,14 @@ int transformEvent(TransInfo *t, const wmEvent *event) else { view_editmove(event->type); } - t->redraw = 1; + t->redraw = TREDRAW_HARD; break; case PADMINUS: if (event->alt && t->flag & T_PROP_EDIT) { t->prop_size *= 0.90909090f; calculatePropRatio(t); } - t->redraw = 1; + t->redraw = TREDRAW_HARD; break; case PAGEDOWNKEY: case WHEELUPMOUSE: @@ -1289,7 +1381,7 @@ int transformEvent(TransInfo *t, const wmEvent *event) else { view_editmove(event->type); } - t->redraw = 1; + t->redraw = TREDRAW_HARD; break; case LEFTALTKEY: case RIGHTALTKEY: @@ -1304,10 +1396,12 @@ int transformEvent(TransInfo *t, const wmEvent *event) break; } - // Numerical input events - t->redraw |= handleNumInput(&(t->num), event); + /* Numerical input events */ + if (handleNumInput(&(t->num), event)) { + t->redraw |= TREDRAW_HARD; + } - // Snapping key events + /* Snapping key events */ t->redraw |= handleSnapping(t, event); } @@ -1975,8 +2069,8 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *even case TFM_SHEAR: initShear(t); break; - case TFM_WARP: - initWarp(t); + case TFM_BEND: + initBend(t); break; case TFM_SHRINKFATTEN: initShrinkFatten(t); @@ -2197,7 +2291,7 @@ int transformEnd(bContext *C, TransInfo *t) /* ************************** TRANSFORM LOCKS **************************** */ -static void protectedTransBits(short protectflag, float *vec) +static void protectedTransBits(short protectflag, float vec[3]) { if (protectflag & OB_LOCK_LOCX) vec[0] = 0.0f; @@ -2207,7 +2301,7 @@ static void protectedTransBits(short protectflag, float *vec) vec[2] = 0.0f; } -static void protectedSizeBits(short protectflag, float *size) +static void protectedSizeBits(short protectflag, float size[3]) { if (protectflag & OB_LOCK_SCALEX) size[0] = 1.0f; @@ -2217,7 +2311,7 @@ static void protectedSizeBits(short protectflag, float *size) size[2] = 1.0f; } -static void protectedRotateBits(short protectflag, float *eul, float *oldeul) +static void protectedRotateBits(short protectflag, float eul[3], const float oldeul[3]) { if (protectflag & OB_LOCK_ROTX) eul[0] = oldeul[0]; @@ -2272,7 +2366,7 @@ static void protectedAxisAngleBits(short protectflag, float axis[3], float *angl } /* this function only does the delta rotation */ -static void protectedQuaternionBits(short protectflag, float *quat, float *oldquat) +static void protectedQuaternionBits(short protectflag, float quat[4], const float oldquat[4]) { /* check that protection flags are set */ if ((protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) == 0) @@ -2576,9 +2670,14 @@ static void constraintSizeLim(TransInfo *t, TransData *td) } } -/* ************************** WARP *************************** */ -struct WarpCustomData { +/* -------------------------------------------------------------------- */ +/* Transform (Bend) */ + +/** \name Transform Bend + * \{ */ + +struct BendCustomData { float warp_sta[3]; float warp_end[3]; @@ -2589,16 +2688,16 @@ struct WarpCustomData { float warp_init_dist; }; -void initWarp(TransInfo *t) +static void initBend(TransInfo *t) { const float mval_fl[2] = {UNPACK2(t->mval)}; const float *curs; float tvec[3]; - struct WarpCustomData *data; + struct BendCustomData *data; - t->mode = TFM_WARP; - t->transform = Warp; - t->handleEvent = handleEventWarp; + t->mode = TFM_BEND; + t->transform = Bend; + t->handleEvent = handleEventBend; setInputPostFct(&t->mouse, postInputRotation); initMouseInputMode(t, &t->mouse, INPUT_ANGLE_SPRING); @@ -2613,14 +2712,14 @@ void initWarp(TransInfo *t) t->flag |= T_NO_CONSTRAINT; - //copy_v3_v3(t->center, give_cursor(t->scene, t->view)); + //copy_v3_v3(t->center, ED_view3d_cursor3d_get(t->scene, t->view)); calculateCenterCursor(t); t->val = 0.0f; data = MEM_callocN(sizeof(*data), __func__); - curs = give_cursor(t->scene, t->view); + curs = ED_view3d_cursor3d_get(t->scene, t->view); copy_v3_v3(data->warp_sta, curs); ED_view3d_win_to_3d(t->ar, curs, mval_fl, data->warp_end); @@ -2641,20 +2740,18 @@ void initWarp(TransInfo *t) t->customData = data; } -int handleEventWarp(TransInfo *t, const wmEvent *event) +static eRedrawFlag handleEventBend(TransInfo *UNUSED(t), const wmEvent *event) { - int status = 0; + eRedrawFlag status = TREDRAW_NOTHING; if (event->type == MIDDLEMOUSE && event->val == KM_PRESS) { - (void)t; - - status = 1; + status = TREDRAW_HARD; } return status; } -int Warp(TransInfo *t, const int UNUSED(mval[2])) +static void Bend(TransInfo *t, const int UNUSED(mval[2])) { TransData *td = t->data; float vec[3]; @@ -2662,7 +2759,7 @@ int Warp(TransInfo *t, const int UNUSED(mval[2])) float warp_end_radius[3]; int i; char str[MAX_INFO_LEN]; - const struct WarpCustomData *data = t->customData; + const struct BendCustomData *data = t->customData; const bool is_clamp = (t->flag & T_ALT_TRANSFORM) == 0; union { @@ -2670,7 +2767,7 @@ int Warp(TransInfo *t, const int UNUSED(mval[2])) float vector[2]; } values; - /* amount of radians for warp */ + /* amount of radians for bend */ copy_v2_v2(values.vector, t->values); #if 0 @@ -2682,7 +2779,7 @@ int Warp(TransInfo *t, const int UNUSED(mval[2])) const float radius_snap = 0.1f; const float snap_hack = (t->snap[1] * data->warp_init_dist) / radius_snap; values.scale *= snap_hack; - snapGrid(t, values.vector); + snapGridIncrement(t, values.vector); values.scale /= snap_hack; } #endif @@ -2695,7 +2792,7 @@ int Warp(TransInfo *t, const int UNUSED(mval[2])) outputNumInput(&(t->num), c); - BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Warp Angle: %s Radius: %s Alt, Clamp %s"), + BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Bend Angle: %s Radius: %s Alt, Clamp %s"), &c[0], &c[NUM_STR_REP_LEN], WM_bool_as_string(is_clamp)); @@ -2704,7 +2801,7 @@ int Warp(TransInfo *t, const int UNUSED(mval[2])) } else { /* default header print */ - BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Warp Angle: %.3f Radius: %.4f, Alt, Clamp %s"), + BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Bend Angle: %.3f Radius: %.4f, Alt, Clamp %s"), RAD2DEGF(values.angle), values.scale * data->warp_init_dist, WM_bool_as_string(is_clamp)); } @@ -2771,21 +2868,25 @@ int Warp(TransInfo *t, const int UNUSED(mval[2])) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ + -/* ************************** SHEAR *************************** */ +/* -------------------------------------------------------------------- */ +/* Transform (Shear) */ + +/** \name Transform Shear + * \{ */ static void postInputShear(TransInfo *UNUSED(t), float values[3]) { mul_v3_fl(values, 0.05f); } -void initShear(TransInfo *t) +static void initShear(TransInfo *t) { t->mode = TFM_SHEAR; - t->transform = Shear; + t->transform = applyShear; t->handleEvent = handleEventShear; setInputPostFct(&t->mouse, postInputShear); @@ -2802,9 +2903,9 @@ void initShear(TransInfo *t) t->flag |= T_NO_CONSTRAINT; } -int handleEventShear(TransInfo *t, const wmEvent *event) +static eRedrawFlag handleEventShear(TransInfo *t, const wmEvent *event) { - int status = 0; + eRedrawFlag status = TREDRAW_NOTHING; if (event->type == MIDDLEMOUSE && event->val == KM_PRESS) { // Use customData pointer to signal Shear direction @@ -2817,26 +2918,26 @@ int handleEventShear(TransInfo *t, const wmEvent *event) t->customData = NULL; } - status = 1; + status = TREDRAW_HARD; } else if (event->type == XKEY && event->val == KM_PRESS) { initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE); t->customData = NULL; - status = 1; + status = TREDRAW_HARD; } else if (event->type == YKEY && event->val == KM_PRESS) { initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE); t->customData = (void *)1; - status = 1; + status = TREDRAW_HARD; } return status; } -int Shear(TransInfo *t, const int UNUSED(mval[2])) +static void applyShear(TransInfo *t, const int UNUSED(mval[2])) { TransData *td = t->data; float vec[3]; @@ -2850,7 +2951,7 @@ int Shear(TransInfo *t, const int UNUSED(mval[2])) value = t->values[0]; - snapGrid(t, &value); + snapGridIncrement(t, &value); applyNumInput(&t->num, &value); @@ -2910,16 +3011,20 @@ int Shear(TransInfo *t, const int UNUSED(mval[2])) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ + + +/* -------------------------------------------------------------------- */ +/* Transform (Resize) */ -/* ************************** RESIZE *************************** */ +/** \name Transform Resize + * \{ */ -void initResize(TransInfo *t) +static void initResize(TransInfo *t) { t->mode = TFM_RESIZE; - t->transform = Resize; + t->transform = applyResize; initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP); @@ -2940,8 +3045,7 @@ void initResize(TransInfo *t) t->num.increment = t->snap[1]; } -/* We assume str is MAX_INFO_LEN long. */ -static void headerResize(TransInfo *t, float vec[3], char *str) +static void headerResize(TransInfo *t, float vec[3], char str[MAX_INFO_LEN]) { char tvec[NUM_STR_REP_LEN * 3]; size_t ofs = 0; @@ -3117,7 +3221,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) constraintTransLim(t, td); } -int Resize(TransInfo *t, const int mval[2]) +static void applyResize(TransInfo *t, const int mval[2]) { TransData *td; float size[3], mat[3][3]; @@ -3135,7 +3239,7 @@ int Resize(TransInfo *t, const int mval[2]) size[0] = size[1] = size[2] = ratio; - snapGrid(t, size); + snapGridIncrement(t, size); if (hasNumInput(&t->num)) { applyNumInput(&t->num, size); @@ -3192,16 +3296,20 @@ int Resize(TransInfo *t, const int mval[2]) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ + + +/* -------------------------------------------------------------------- */ +/* Transform (Skin) */ -/* ************************** SKIN *************************** */ +/** \name Transform Skin + * \{ */ -void initSkinResize(TransInfo *t) +static void initSkinResize(TransInfo *t) { t->mode = TFM_SKIN_RESIZE; - t->transform = SkinResize; + t->transform = applySkinResize; initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP); @@ -3222,7 +3330,7 @@ void initSkinResize(TransInfo *t) t->num.increment = t->snap[1]; } -int SkinResize(TransInfo *t, const int UNUSED(mval[2])) +static void applySkinResize(TransInfo *t, const int UNUSED(mval[2])) { TransData *td; float size[3], mat[3][3]; @@ -3233,7 +3341,7 @@ int SkinResize(TransInfo *t, const int UNUSED(mval[2])) ratio = t->values[0]; size[0] = size[1] = size[2] = ratio; - snapGrid(t, size); + snapGridIncrement(t, size); if (hasNumInput(&t->num)) { applyNumInput(&t->num, size); @@ -3282,19 +3390,23 @@ int SkinResize(TransInfo *t, const int UNUSED(mval[2])) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ + -/* ************************** TOSPHERE *************************** */ +/* -------------------------------------------------------------------- */ +/* Transform (ToSphere) */ -void initToSphere(TransInfo *t) +/** \name Transform ToSphere + * \{ */ + +static void initToSphere(TransInfo *t) { TransData *td = t->data; int i; t->mode = TFM_TOSPHERE; - t->transform = ToSphere; + t->transform = applyToSphere; initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO); @@ -3317,7 +3429,7 @@ void initToSphere(TransInfo *t) t->val /= (float)t->total; } -int ToSphere(TransInfo *t, const int UNUSED(mval[2])) +static void applyToSphere(TransInfo *t, const int UNUSED(mval[2])) { float vec[3]; float ratio, radius; @@ -3327,7 +3439,7 @@ int ToSphere(TransInfo *t, const int UNUSED(mval[2])) ratio = t->values[0]; - snapGrid(t, &ratio); + snapGridIncrement(t, &ratio); applyNumInput(&t->num, &ratio); @@ -3375,12 +3487,15 @@ int ToSphere(TransInfo *t, const int UNUSED(mval[2])) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ + -/* ************************** ROTATION *************************** */ +/* -------------------------------------------------------------------- */ +/* Transform (Rotation) */ +/** \name Transform Rotation + * \{ */ static void postInputRotation(TransInfo *t, float values[3]) { @@ -3389,10 +3504,10 @@ static void postInputRotation(TransInfo *t, float values[3]) } } -void initRotation(TransInfo *t) +static void initRotation(TransInfo *t) { t->mode = TFM_ROTATION; - t->transform = Rotation; + t->transform = applyRotation; setInputPostFct(&t->mouse, postInputRotation); initMouseInputMode(t, &t->mouse, INPUT_ANGLE); @@ -3638,7 +3753,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short } } -static void applyRotation(TransInfo *t, float angle, float axis[3]) +static void applyRotationValue(TransInfo *t, float angle, float axis[3]) { TransData *td = t->data; float mat[3][3]; @@ -3666,7 +3781,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) } } -int Rotation(TransInfo *t, const int UNUSED(mval[2])) +static void applyRotation(TransInfo *t, const int UNUSED(mval[2])) { char str[MAX_INFO_LEN]; size_t ofs = 0; @@ -3675,7 +3790,7 @@ int Rotation(TransInfo *t, const int UNUSED(mval[2])) final = t->values[0]; - snapGrid(t, &final); + snapGridIncrement(t, &final); if ((t->con.mode & CON_APPLY) && t->con.applyRot) { t->con.applyRot(t, NULL, t->axis, NULL); @@ -3710,22 +3825,25 @@ int Rotation(TransInfo *t, const int UNUSED(mval[2])) t->values[0] = final; - applyRotation(t, final, t->axis); + applyRotationValue(t, final, t->axis); recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ -/* ************************** TRACKBALL *************************** */ +/* -------------------------------------------------------------------- */ +/* Transform (Rotation - Trackball) */ -void initTrackball(TransInfo *t) +/** \name Transform Rotation - Trackball + * \{ */ + +static void initTrackball(TransInfo *t) { t->mode = TFM_TRACKBALL; - t->transform = Trackball; + t->transform = applyTrackball; initMouseInputMode(t, &t->mouse, INPUT_TRACKBALL); @@ -3740,7 +3858,7 @@ void initTrackball(TransInfo *t) t->flag |= T_NO_CONSTRAINT; } -static void applyTrackball(TransInfo *t, const float axis1[3], const float axis2[3], float angles[2]) +static void applyTrackballValue(TransInfo *t, const float axis1[3], const float axis2[3], float angles[2]) { TransData *td = t->data; float mat[3][3], smat[3][3], totmat[3][3]; @@ -3769,7 +3887,7 @@ static void applyTrackball(TransInfo *t, const float axis1[3], const float axis2 } } -int Trackball(TransInfo *t, const int UNUSED(mval[2])) +static void applyTrackball(TransInfo *t, const int UNUSED(mval[2])) { char str[MAX_INFO_LEN]; size_t ofs = 0; @@ -3785,7 +3903,7 @@ int Trackball(TransInfo *t, const int UNUSED(mval[2])) phi[0] = t->values[0]; phi[1] = t->values[1]; - snapGrid(t, phi); + snapGridIncrement(t, phi); if (hasNumInput(&t->num)) { char c[NUM_STR_REP_LEN * 2]; @@ -3817,18 +3935,22 @@ int Trackball(TransInfo *t, const int UNUSED(mval[2])) // TRANSFORM_FIX_ME //copy_m3_m3(t->mat, mat); // used in manipulator - applyTrackball(t, axis1, axis2, phi); + applyTrackballValue(t, axis1, axis2, phi); recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ + + +/* -------------------------------------------------------------------- */ +/* Transform (Translation) */ -/* ************************** TRANSLATION *************************** */ +/** \name Transform Translation + * \{ */ -void initTranslation(TransInfo *t) +static void initTranslation(TransInfo *t) { if (t->spacetype == SPACE_ACTION) { /* this space uses time translate */ @@ -3836,7 +3958,7 @@ void initTranslation(TransInfo *t) } t->mode = TFM_TRANSLATION; - t->transform = Translation; + t->transform = applyTranslation; initMouseInputMode(t, &t->mouse, INPUT_VECTOR); @@ -3860,8 +3982,8 @@ void initTranslation(TransInfo *t) } else if (t->spacetype == SPACE_NODE) { t->snap[0] = 0.0f; - t->snap[1] = 125.0f; - t->snap[2] = 25.0f; + t->snap[1] = ED_node_grid_size() * NODE_GRID_STEPS; + t->snap[2] = ED_node_grid_size(); } else { t->snap[0] = 0.0f; @@ -3871,8 +3993,7 @@ void initTranslation(TransInfo *t) t->num.increment = t->snap[1]; } -/* We assume str is MAX_INFO_LEN long. */ -static void headerTranslation(TransInfo *t, float vec[3], char *str) +static void headerTranslation(TransInfo *t, float vec[3], char str[MAX_INFO_LEN]) { size_t ofs = 0; char tvec[NUM_STR_REP_LEN * 3]; @@ -3959,7 +4080,7 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) } } -static void applyTranslation(TransInfo *t, float vec[3]) +static void applyTranslationValue(TransInfo *t, float vec[3]) { TransData *td = t->data; float tvec[3]; @@ -4026,7 +4147,7 @@ static void applyTranslation(TransInfo *t, float vec[3]) } /* uses t->vec to store actual translation in */ -int Translation(TransInfo *t, const int UNUSED(mval[2])) +static void applyTranslation(TransInfo *t, const int UNUSED(mval[2])) { char str[MAX_INFO_LEN]; @@ -4042,7 +4163,7 @@ int Translation(TransInfo *t, const int UNUSED(mval[2])) headerTranslation(t, pvec, str); } else { - snapGrid(t, t->values); + snapGridIncrement(t, t->values); applyNumInput(&t->num, t->values); if (hasNumInput(&t->num)) { removeAspectRatio(t, t->values); @@ -4051,11 +4172,11 @@ int Translation(TransInfo *t, const int UNUSED(mval[2])) headerTranslation(t, t->values, str); } - applyTranslation(t, t->values); + applyTranslationValue(t, t->values); /* evil hack - redo translation if clipping needed */ if (t->flag & T_CLIP_UV && clipUVTransform(t, t->values, 0)) { - applyTranslation(t, t->values); + applyTranslationValue(t, t->values); /* In proportional edit it can happen that */ /* vertices in the radius of the brush end */ @@ -4069,13 +4190,17 @@ int Translation(TransInfo *t, const int UNUSED(mval[2])) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ + + +/* -------------------------------------------------------------------- */ +/* Transform (Shrink-Fatten) */ -/* ************************** SHRINK/FATTEN *************************** */ +/** \name Transform Shrink-Fatten + * \{ */ -void initShrinkFatten(TransInfo *t) +static void initShrinkFatten(TransInfo *t) { // If not in mesh edit mode, fallback to Resize if (t->obedit == NULL || t->obedit->type != OB_MESH) { @@ -4083,7 +4208,7 @@ void initShrinkFatten(TransInfo *t) } else { t->mode = TFM_SHRINKFATTEN; - t->transform = ShrinkFatten; + t->transform = applyShrinkFatten; initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE); @@ -4100,7 +4225,7 @@ void initShrinkFatten(TransInfo *t) } -int ShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) +static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) { float distance; int i; @@ -4110,7 +4235,7 @@ int ShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) distance = -t->values[0]; - snapGrid(t, &distance); + snapGridIncrement(t, &distance); applyNumInput(&t->num, &distance); @@ -4138,7 +4263,7 @@ int ShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) } } BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" or Alt) Even Thickness %s"), - WM_bool_as_string(t->flag & T_ALT_TRANSFORM)); + WM_bool_as_string((t->flag & T_ALT_TRANSFORM) != 0)); /* done with header string */ @@ -4164,16 +4289,20 @@ int ShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ + -/* ************************** TILT *************************** */ +/* -------------------------------------------------------------------- */ +/* Transform (Tilt) */ -void initTilt(TransInfo *t) +/** \name Transform Tilt + * \{ */ + +static void initTilt(TransInfo *t) { t->mode = TFM_TILT; - t->transform = Tilt; + t->transform = applyTilt; initMouseInputMode(t, &t->mouse, INPUT_ANGLE); @@ -4189,8 +4318,7 @@ void initTilt(TransInfo *t) } - -int Tilt(TransInfo *t, const int UNUSED(mval[2])) +static void applyTilt(TransInfo *t, const int UNUSED(mval[2])) { TransData *td = t->data; int i; @@ -4200,7 +4328,7 @@ int Tilt(TransInfo *t, const int UNUSED(mval[2])) final = t->values[0]; - snapGrid(t, &final); + snapGridIncrement(t, &final); if (hasNumInput(&t->num)) { char c[NUM_STR_REP_LEN]; @@ -4235,17 +4363,20 @@ int Tilt(TransInfo *t, const int UNUSED(mval[2])) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ -/* ******************** Curve Shrink/Fatten *************** */ +/* -------------------------------------------------------------------- */ +/* Transform (Curve Shrink/Fatten) */ -void initCurveShrinkFatten(TransInfo *t) +/** \name Transform Curve Shrink/Fatten + * \{ */ + +static void initCurveShrinkFatten(TransInfo *t) { t->mode = TFM_CURVE_SHRINKFATTEN; - t->transform = CurveShrinkFatten; + t->transform = applyCurveShrinkFatten; initMouseInputMode(t, &t->mouse, INPUT_SPRING); @@ -4263,7 +4394,7 @@ void initCurveShrinkFatten(TransInfo *t) t->flag |= T_NO_CONSTRAINT; } -int CurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) +static void applyCurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) { TransData *td = t->data; float ratio; @@ -4272,7 +4403,7 @@ int CurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) ratio = t->values[0]; - snapGrid(t, &ratio); + snapGridIncrement(t, &ratio); applyNumInput(&t->num, &ratio); @@ -4305,15 +4436,20 @@ int CurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ + + +/* -------------------------------------------------------------------- */ +/* Transform (Mask Shrink/Fatten) */ +/** \name Transform Mask Shrink/Fatten + * \{ */ -void initMaskShrinkFatten(TransInfo *t) +static void initMaskShrinkFatten(TransInfo *t) { t->mode = TFM_MASK_SHRINKFATTEN; - t->transform = MaskShrinkFatten; + t->transform = applyMaskShrinkFatten; initMouseInputMode(t, &t->mouse, INPUT_SPRING); @@ -4331,7 +4467,7 @@ void initMaskShrinkFatten(TransInfo *t) t->flag |= T_NO_CONSTRAINT; } -int MaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) +static void applyMaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) { TransData *td; float ratio; @@ -4340,7 +4476,7 @@ int MaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) ratio = t->values[0]; - snapGrid(t, &ratio); + snapGridIncrement(t, &ratio); applyNumInput(&t->num, &ratio); @@ -4394,16 +4530,20 @@ int MaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ -/* ************************** PUSH/PULL *************************** */ -void initPushPull(TransInfo *t) +/* -------------------------------------------------------------------- */ +/* Transform (Push/Pull) */ + +/** \name Transform Push/Pull + * \{ */ + +static void initPushPull(TransInfo *t) { t->mode = TFM_PUSHPULL; - t->transform = PushPull; + t->transform = applyPushPull; initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE); @@ -4417,7 +4557,7 @@ void initPushPull(TransInfo *t) } -int PushPull(TransInfo *t, const int UNUSED(mval[2])) +static void applyPushPull(TransInfo *t, const int UNUSED(mval[2])) { float vec[3], axis[3]; float distance; @@ -4427,7 +4567,7 @@ int PushPull(TransInfo *t, const int UNUSED(mval[2])) distance = t->values[0]; - snapGrid(t, &distance); + snapGridIncrement(t, &distance); applyNumInput(&t->num, &distance); @@ -4479,16 +4619,20 @@ int PushPull(TransInfo *t, const int UNUSED(mval[2])) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ + -/* ************************** BEVEL WEIGHT *************************** */ +/* -------------------------------------------------------------------- */ +/* Transform (Bevel Weight) */ -void initBevelWeight(TransInfo *t) +/** \name Transform Bevel Weight + * \{ */ + +static void initBevelWeight(TransInfo *t) { t->mode = TFM_BWEIGHT; - t->transform = BevelWeight; + t->transform = applyBevelWeight; initMouseInputMode(t, &t->mouse, INPUT_SPRING); @@ -4503,7 +4647,7 @@ void initBevelWeight(TransInfo *t) t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT; } -int BevelWeight(TransInfo *t, const int UNUSED(mval[2])) +static void applyBevelWeight(TransInfo *t, const int UNUSED(mval[2])) { TransData *td = t->data; float weight; @@ -4515,7 +4659,7 @@ int BevelWeight(TransInfo *t, const int UNUSED(mval[2])) weight -= 1.0f; if (weight > 1.0f) weight = 1.0f; - snapGrid(t, &weight); + snapGridIncrement(t, &weight); applyNumInput(&t->num, &weight); @@ -4552,16 +4696,20 @@ int BevelWeight(TransInfo *t, const int UNUSED(mval[2])) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ + + +/* -------------------------------------------------------------------- */ +/* Transform (Crease) */ -/* ************************** CREASE *************************** */ +/** \name Transform Crease + * \{ */ -void initCrease(TransInfo *t) +static void initCrease(TransInfo *t) { t->mode = TFM_CREASE; - t->transform = Crease; + t->transform = applyCrease; initMouseInputMode(t, &t->mouse, INPUT_SPRING); @@ -4576,7 +4724,7 @@ void initCrease(TransInfo *t) t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT; } -int Crease(TransInfo *t, const int UNUSED(mval[2])) +static void applyCrease(TransInfo *t, const int UNUSED(mval[2])) { TransData *td = t->data; float crease; @@ -4588,7 +4736,7 @@ int Crease(TransInfo *t, const int UNUSED(mval[2])) crease -= 1.0f; if (crease > 1.0f) crease = 1.0f; - snapGrid(t, &crease); + snapGridIncrement(t, &crease); applyNumInput(&t->num, &crease); @@ -4628,16 +4776,20 @@ int Crease(TransInfo *t, const int UNUSED(mval[2])) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ + + +/* -------------------------------------------------------------------- */ +/* Transform (EditBone (B-bone) width scaling) */ -/* ******************** EditBone (B-bone) width scaling *************** */ +/** \name Transform B-bone width scaling + * \{ */ -void initBoneSize(TransInfo *t) +static void initBoneSize(TransInfo *t) { t->mode = TFM_BONESIZE; - t->transform = BoneSize; + t->transform = applyBoneSize; initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP); @@ -4652,8 +4804,7 @@ void initBoneSize(TransInfo *t) t->num.increment = t->snap[1]; } -/* We assume str is MAX_INFO_LEN long. */ -static void headerBoneSize(TransInfo *t, float vec[3], char *str) +static void headerBoneSize(TransInfo *t, float vec[3], char str[MAX_INFO_LEN]) { char tvec[NUM_STR_REP_LEN * 3]; if (hasNumInput(&t->num)) { @@ -4699,7 +4850,7 @@ static void ElementBoneSize(TransInfo *t, TransData *td, float mat[3][3]) td->loc[1] = oldy; } -int BoneSize(TransInfo *t, const int mval[2]) +static void applyBoneSize(TransInfo *t, const int mval[2]) { TransData *td = t->data; float size[3], mat[3][3]; @@ -4718,7 +4869,7 @@ int BoneSize(TransInfo *t, const int mval[2]) size[0] = size[1] = size[2] = ratio; - snapGrid(t, size); + snapGridIncrement(t, size); if (hasNumInput(&t->num)) { applyNumInput(&t->num, size); @@ -4748,17 +4899,20 @@ int BoneSize(TransInfo *t, const int mval[2]) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/* Transform (Bone Envelope) */ -/* ******************** EditBone envelope *************** */ +/** \name Transform Bone Envelope + * \{ */ -void initBoneEnvelope(TransInfo *t) +static void initBoneEnvelope(TransInfo *t) { t->mode = TFM_BONE_ENVELOPE; - t->transform = BoneEnvelope; + t->transform = applyBoneEnvelope; initMouseInputMode(t, &t->mouse, INPUT_SPRING); @@ -4773,7 +4927,7 @@ void initBoneEnvelope(TransInfo *t) t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT; } -int BoneEnvelope(TransInfo *t, const int UNUSED(mval[2])) +static void applyBoneEnvelope(TransInfo *t, const int UNUSED(mval[2])) { TransData *td = t->data; float ratio; @@ -4782,7 +4936,7 @@ int BoneEnvelope(TransInfo *t, const int UNUSED(mval[2])) ratio = t->values[0]; - snapGrid(t, &ratio); + snapGridIncrement(t, &ratio); applyNumInput(&t->num, &ratio); @@ -4816,11 +4970,16 @@ int BoneEnvelope(TransInfo *t, const int UNUSED(mval[2])) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ + + +/* -------------------------------------------------------------------- */ +/* Transform (Edge Slide) */ + +/** \name Transform Edge Slide + * \{ */ -/* ******************** Edge Slide *************** */ static BMEdge *get_other_edge(BMVert *v, BMEdge *e) { BMIter iter; @@ -5343,7 +5502,7 @@ static bool createEdgeSlideVerts(TransInfo *t) use_btree_disp = (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE); if (use_btree_disp) { - btree = BKE_bmbvh_new(em, BMBVH_RESPECT_HIDDEN, NULL, false); + btree = BKE_bmbvh_new_from_editmesh(em, BMBVH_RESPECT_HIDDEN, NULL, false); } else { btree = NULL; @@ -5678,12 +5837,12 @@ void freeEdgeSlideVerts(TransInfo *t) recalcData(t); } -void initEdgeSlide(TransInfo *t) +static void initEdgeSlide(TransInfo *t) { EdgeSlideData *sld; t->mode = TFM_EDGE_SLIDE; - t->transform = EdgeSlide; + t->transform = applyEdgeSlide; t->handleEvent = handleEventEdgeSlide; if (!createEdgeSlideVerts(t)) { @@ -5713,7 +5872,7 @@ void initEdgeSlide(TransInfo *t) t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT; } -int handleEventEdgeSlide(struct TransInfo *t, const struct wmEvent *event) +static eRedrawFlag handleEventEdgeSlide(struct TransInfo *t, const struct wmEvent *event) { if (t->mode == TFM_EDGE_SLIDE) { EdgeSlideData *sld = t->customData; @@ -5723,7 +5882,7 @@ int handleEventEdgeSlide(struct TransInfo *t, const struct wmEvent *event) case EKEY: if (event->val == KM_PRESS) { sld->is_proportional = !sld->is_proportional; - return 1; + return TREDRAW_HARD; } break; case FKEY: @@ -5732,7 +5891,7 @@ int handleEventEdgeSlide(struct TransInfo *t, const struct wmEvent *event) if (sld->is_proportional == FALSE) { sld->flipped_vtx = !sld->flipped_vtx; } - return 1; + return TREDRAW_HARD; } break; } @@ -5757,7 +5916,7 @@ int handleEventEdgeSlide(struct TransInfo *t, const struct wmEvent *event) } } } - return 0; + return TREDRAW_NOTHING; } static void drawEdgeSlide(const struct bContext *C, TransInfo *t) @@ -5898,7 +6057,7 @@ static int doEdgeSlide(TransInfo *t, float perc) return 1; } -int EdgeSlide(TransInfo *t, const int UNUSED(mval[2])) +static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2])) { char str[MAX_INFO_LEN]; float final; @@ -5908,7 +6067,7 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2])) final = t->values[0]; - snapGrid(t, &final); + snapGridIncrement(t, &final); /* only do this so out of range values are not displayed */ CLAMP(final, -1.0f, 1.0f); @@ -5938,12 +6097,16 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2])) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/* Transform (Vert Slide) */ + +/** \name Transform Vert Slide + * \{ */ -/* ******************** Vert Slide *************** */ static void calcVertSlideCustomPoints(struct TransInfo *t) { VertSlideData *sld = t->customData; @@ -6180,12 +6343,12 @@ void freeVertSlideVerts(TransInfo *t) recalcData(t); } -void initVertSlide(TransInfo *t) +static void initVertSlide(TransInfo *t) { VertSlideData *sld; t->mode = TFM_VERT_SLIDE; - t->transform = VertSlide; + t->transform = applyVertSlide; t->handleEvent = handleEventVertSlide; if (!createVertSlideVerts(t)) { @@ -6215,7 +6378,7 @@ void initVertSlide(TransInfo *t) t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT; } -int handleEventVertSlide(struct TransInfo *t, const struct wmEvent *event) +static eRedrawFlag handleEventVertSlide(struct TransInfo *t, const struct wmEvent *event) { if (t->mode == TFM_VERT_SLIDE) { VertSlideData *sld = t->customData; @@ -6228,7 +6391,7 @@ int handleEventVertSlide(struct TransInfo *t, const struct wmEvent *event) if (sld->flipped_vtx) { calcVertSlideCustomPoints(t); } - return 1; + return TREDRAW_HARD; } break; case FKEY: @@ -6236,7 +6399,7 @@ int handleEventVertSlide(struct TransInfo *t, const struct wmEvent *event) if (event->val == KM_PRESS) { sld->flipped_vtx = !sld->flipped_vtx; calcVertSlideCustomPoints(t); - return 1; + return TREDRAW_HARD; } break; } @@ -6246,7 +6409,7 @@ int handleEventVertSlide(struct TransInfo *t, const struct wmEvent *event) if (event->val == KM_PRESS) { t->flag ^= T_ALT_TRANSFORM; calcVertSlideCustomPoints(t); - return 1; + return TREDRAW_HARD; } break; } @@ -6282,7 +6445,7 @@ int handleEventVertSlide(struct TransInfo *t, const struct wmEvent *event) } } } - return 0; + return TREDRAW_NOTHING; } static void drawVertSlide(const struct bContext *C, TransInfo *t) @@ -6399,7 +6562,7 @@ static int doVertSlide(TransInfo *t, float perc) return 1; } -int VertSlide(TransInfo *t, const int UNUSED(mval[2])) +static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2])) { char str[MAX_INFO_LEN]; size_t ofs = 0; @@ -6412,7 +6575,7 @@ int VertSlide(TransInfo *t, const int UNUSED(mval[2])) final = t->values[0]; - snapGrid(t, &final); + snapGridIncrement(t, &final); /* only do this so out of range values are not displayed */ if (is_constrained) { @@ -6443,17 +6606,20 @@ int VertSlide(TransInfo *t, const int UNUSED(mval[2])) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ -/* ******************** EditBone roll *************** */ +/* -------------------------------------------------------------------- */ +/* Transform (EditBone Roll) */ -void initBoneRoll(TransInfo *t) +/** \name Transform EditBone Roll + * \{ */ + +static void initBoneRoll(TransInfo *t) { t->mode = TFM_BONE_ROLL; - t->transform = BoneRoll; + t->transform = applyBoneRoll; initMouseInputMode(t, &t->mouse, INPUT_ANGLE); @@ -6468,7 +6634,7 @@ void initBoneRoll(TransInfo *t) t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT; } -int BoneRoll(TransInfo *t, const int UNUSED(mval[2])) +static void applyBoneRoll(TransInfo *t, const int UNUSED(mval[2])) { TransData *td = t->data; int i; @@ -6478,7 +6644,7 @@ int BoneRoll(TransInfo *t, const int UNUSED(mval[2])) final = t->values[0]; - snapGrid(t, &final); + snapGridIncrement(t, &final); if (hasNumInput(&t->num)) { char c[NUM_STR_REP_LEN]; @@ -6509,15 +6675,19 @@ int BoneRoll(TransInfo *t, const int UNUSED(mval[2])) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ + + +/* -------------------------------------------------------------------- */ +/* Transform (Bake-Time) */ -/* ************************** BAKE TIME ******************* */ +/** \name Transform Bake-Time + * \{ */ -void initBakeTime(TransInfo *t) +static void initBakeTime(TransInfo *t) { - t->transform = BakeTime; + t->transform = applyBakeTime; initMouseInputMode(t, &t->mouse, INPUT_NONE); t->idx_max = 0; @@ -6529,7 +6699,7 @@ void initBakeTime(TransInfo *t) t->num.increment = t->snap[1]; } -int BakeTime(TransInfo *t, const int mval[2]) +static void applyBakeTime(TransInfo *t, const int mval[2]) { TransData *td = t->data; float time; @@ -6547,7 +6717,7 @@ int BakeTime(TransInfo *t, const int mval[2]) time = (float)(t->center2d[0] - mval[0]) * fac; } - snapGrid(t, &time); + snapGridIncrement(t, &time); applyNumInput(&t->num, &time); @@ -6587,15 +6757,19 @@ int BakeTime(TransInfo *t, const int mval[2]) recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ -/* ************************** MIRROR *************************** */ -void initMirror(TransInfo *t) +/* -------------------------------------------------------------------- */ +/* Transform (Mirror) */ + +/** \name Transform Mirror + * \{ */ + +static void initMirror(TransInfo *t) { - t->transform = Mirror; + t->transform = applyMirror; initMouseInputMode(t, &t->mouse, INPUT_NONE); t->flag |= T_NULL_ONE; @@ -6604,7 +6778,7 @@ void initMirror(TransInfo *t) } } -int Mirror(TransInfo *t, const int UNUSED(mval[2])) +static void applyMirror(TransInfo *t, const int UNUSED(mval[2])) { TransData *td; float size[3], mat[3][3]; @@ -6665,22 +6839,26 @@ int Mirror(TransInfo *t, const int UNUSED(mval[2])) else ED_area_headerprint(t->sa, IFACE_("Select a mirror axis (X, Y, Z)")); } - - return 1; } +/** \} */ -/* ************************** ALIGN *************************** */ -void initAlign(TransInfo *t) +/* -------------------------------------------------------------------- */ +/* Transform (Align) */ + +/** \name Transform Align + * \{ */ + +static void initAlign(TransInfo *t) { t->flag |= T_NO_CONSTRAINT; - t->transform = Align; + t->transform = applyAlign; initMouseInputMode(t, &t->mouse, INPUT_NONE); } -int Align(TransInfo *t, const int UNUSED(mval[2])) +static void applyAlign(TransInfo *t, const int UNUSED(mval[2])) { TransData *td = t->data; float center[3]; @@ -6721,15 +6899,19 @@ int Align(TransInfo *t, const int UNUSED(mval[2])) recalcData(t); ED_area_headerprint(t->sa, IFACE_("Align")); - - return 1; } +/** \} */ + -/* ************************** SEQ SLIDE *************************** */ +/* -------------------------------------------------------------------- */ +/* Transform (Sequencer Slide) */ -void initSeqSlide(TransInfo *t) +/** \name Transform Sequencer Slide + * \{ */ + +static void initSeqSlide(TransInfo *t) { - t->transform = SeqSlide; + t->transform = applySeqSlide; initMouseInputMode(t, &t->mouse, INPUT_VECTOR); @@ -6744,8 +6926,7 @@ void initSeqSlide(TransInfo *t) t->num.increment = t->snap[1]; } -/* We assume str is MAX_INFO_LEN long. */ -static void headerSeqSlide(TransInfo *t, float val[2], char *str) +static void headerSeqSlide(TransInfo *t, float val[2], char str[MAX_INFO_LEN]) { char tvec[NUM_STR_REP_LEN * 3]; size_t ofs = 0; @@ -6766,10 +6947,10 @@ static void headerSeqSlide(TransInfo *t, float val[2], char *str) } } ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" or Alt) Expand to fit %s"), - WM_bool_as_string(t->flag & T_ALT_TRANSFORM)); + WM_bool_as_string((t->flag & T_ALT_TRANSFORM) != 0)); } -static void applySeqSlide(TransInfo *t, const float val[2]) +static void applySeqSlideValue(TransInfo *t, const float val[2]) { TransData *td = t->data; int i; @@ -6792,7 +6973,7 @@ static void applySeqSlide(TransInfo *t, const float val[2]) } } -int SeqSlide(TransInfo *t, const int UNUSED(mval[2])) +static void applySeqSlide(TransInfo *t, const int UNUSED(mval[2])) { char str[MAX_INFO_LEN]; @@ -6803,7 +6984,7 @@ int SeqSlide(TransInfo *t, const int UNUSED(mval[2])) copy_v3_v3(t->values, tvec); } else { - snapGrid(t, t->values); + snapGridIncrement(t, t->values); applyNumInput(&t->num, t->values); } @@ -6811,19 +6992,23 @@ int SeqSlide(TransInfo *t, const int UNUSED(mval[2])) t->values[1] = floor(t->values[1] + 0.5f); headerSeqSlide(t, t->values, str); - applySeqSlide(t, t->values); + applySeqSlideValue(t, t->values); recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ -/* ************************** ANIM EDITORS - TRANSFORM TOOLS *************************** */ -/* ---------------- Special Helpers for Various Settings ------------- */ +/* -------------------------------------------------------------------- */ +/* Animation Editors - Transform Utils + * + * Special Helpers for Various Settings + */ +/** \name Animation Editor Utils + * \{ */ /* This function returns the snapping 'mode' for Animation Editors only * We cannot use the standard snapping due to NLA-strip scaling complexities. @@ -6975,10 +7160,16 @@ static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, TransData2D *td2d, td2d->h2[0] = td2d->ih2[0] + *td->val - td->ival; } } +/** \} */ + + +/* -------------------------------------------------------------------- */ +/* Transform (Animation Translation) */ -/* ----------------- Translation ----------------------- */ +/** \name Transform Animation Translation + * \{ */ -void initTimeTranslate(TransInfo *t) +static void initTimeTranslate(TransInfo *t) { /* this tool is only really available in the Action Editor... */ if (!ELEM(t->spacetype, SPACE_ACTION, SPACE_SEQ)) { @@ -6986,7 +7177,7 @@ void initTimeTranslate(TransInfo *t) } t->mode = TFM_TIME_TRANSLATE; - t->transform = TimeTranslate; + t->transform = applyTimeTranslate; initMouseInputMode(t, &t->mouse, INPUT_NONE); @@ -7002,8 +7193,7 @@ void initTimeTranslate(TransInfo *t) t->num.increment = t->snap[1]; } -/* We assume str is MAX_INFO_LEN long. */ -static void headerTimeTranslate(TransInfo *t, char *str) +static void headerTimeTranslate(TransInfo *t, char str[MAX_INFO_LEN]) { char tvec[NUM_STR_REP_LEN * 3]; @@ -7039,7 +7229,7 @@ static void headerTimeTranslate(TransInfo *t, char *str) BLI_snprintf(str, MAX_INFO_LEN, IFACE_("DeltaX: %s"), &tvec[0]); } -static void applyTimeTranslate(TransInfo *t, float UNUSED(sval)) +static void applyTimeTranslateValue(TransInfo *t, float UNUSED(sval)) { TransData *td = t->data; TransData2D *td2d = t->data2d; @@ -7096,7 +7286,7 @@ static void applyTimeTranslate(TransInfo *t, float UNUSED(sval)) } } -int TimeTranslate(TransInfo *t, const int mval[2]) +static void applyTimeTranslate(TransInfo *t, const int mval[2]) { View2D *v2d = (View2D *)t->view; float cval[2], sval[2]; @@ -7115,18 +7305,22 @@ int TimeTranslate(TransInfo *t, const int mval[2]) t->values[0] = t->vec[0]; headerTimeTranslate(t, str); - applyTimeTranslate(t, sval[0]); + applyTimeTranslateValue(t, sval[0]); recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ -/* ----------------- Time Slide ----------------------- */ -void initTimeSlide(TransInfo *t) +/* -------------------------------------------------------------------- */ +/* Transform (Animation Time Slide) */ + +/** \name Transform Animation Time Slide + * \{ */ + +static void initTimeSlide(TransInfo *t) { /* this tool is only really available in the Action Editor... */ if (t->spacetype == SPACE_ACTION) { @@ -7141,7 +7335,7 @@ void initTimeSlide(TransInfo *t) t->mode = TFM_TIME_SLIDE; - t->transform = TimeSlide; + t->transform = applyTimeSlide; t->flag |= T_FREE_CUSTOMDATA; initMouseInputMode(t, &t->mouse, INPUT_NONE); @@ -7158,8 +7352,7 @@ void initTimeSlide(TransInfo *t) t->num.increment = t->snap[1]; } -/* We assume str is MAX_INFO_LEN long. */ -static void headerTimeSlide(TransInfo *t, float sval, char *str) +static void headerTimeSlide(TransInfo *t, float sval, char str[MAX_INFO_LEN]) { char tvec[NUM_STR_REP_LEN * 3]; @@ -7181,7 +7374,7 @@ static void headerTimeSlide(TransInfo *t, float sval, char *str) BLI_snprintf(str, MAX_INFO_LEN, IFACE_("TimeSlide: %s"), &tvec[0]); } -static void applyTimeSlide(TransInfo *t, float sval) +static void applyTimeSlideValue(TransInfo *t, float sval) { TransData *td = t->data; int i; @@ -7228,7 +7421,7 @@ static void applyTimeSlide(TransInfo *t, float sval) } } -int TimeSlide(TransInfo *t, const int mval[2]) +static void applyTimeSlide(TransInfo *t, const int mval[2]) { View2D *v2d = (View2D *)t->view; float cval[2], sval[2]; @@ -7250,18 +7443,22 @@ int TimeSlide(TransInfo *t, const int mval[2]) t->values[0] = (maxx - minx) * t->vec[0] / 2.0f + sval[0]; headerTimeSlide(t, sval[0], str); - applyTimeSlide(t, sval[0]); + applyTimeSlideValue(t, sval[0]); recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; } +/** \} */ -/* ----------------- Scaling ----------------------- */ -void initTimeScale(TransInfo *t) +/* -------------------------------------------------------------------- */ +/* Transform (Animation Time Scale) */ + +/** \name Transform Animation Time Scale + * \{ */ + +static void initTimeScale(TransInfo *t) { float center[2]; @@ -7273,7 +7470,7 @@ void initTimeScale(TransInfo *t) } t->mode = TFM_TIME_SCALE; - t->transform = TimeScale; + t->transform = applyTimeScale; /* recalculate center2d to use CFRA and mouse Y, since that's * what is used in time scale */ @@ -7301,8 +7498,7 @@ void initTimeScale(TransInfo *t) t->num.increment = t->snap[1]; } -/* We assume str is MAX_INFO_LEN long. */ -static void headerTimeScale(TransInfo *t, char *str) +static void headerTimeScale(TransInfo *t, char str[MAX_INFO_LEN]) { char tvec[NUM_STR_REP_LEN * 3]; @@ -7314,7 +7510,7 @@ static void headerTimeScale(TransInfo *t, char *str) BLI_snprintf(str, MAX_INFO_LEN, IFACE_("ScaleX: %s"), &tvec[0]); } -static void applyTimeScale(TransInfo *t) +static void applyTimeScaleValue(TransInfo *t) { Scene *scene = t->scene; TransData *td = t->data; @@ -7354,7 +7550,7 @@ static void applyTimeScale(TransInfo *t) } } -int TimeScale(TransInfo *t, const int UNUSED(mval[2])) +static void applyTimeScale(TransInfo *t, const int UNUSED(mval[2])) { char str[MAX_INFO_LEN]; @@ -7364,22 +7560,13 @@ int TimeScale(TransInfo *t, const int UNUSED(mval[2])) t->values[0] = t->vec[0]; headerTimeScale(t, str); - applyTimeScale(t); + applyTimeScaleValue(t); recalcData(t); ED_area_headerprint(t->sa, str); - - return 1; -} - -/* ************************************ */ - -void BIF_TransformSetUndo(const char *UNUSED(str)) -{ - // TRANSFORM_FIX_ME - //Trans.undostr = str; } +/** \} */ /* TODO, move to: transform_queries.c */ diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index b32ba5ad527..ab5f034c836 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -62,6 +62,13 @@ struct wmTimer; struct ARegion; struct ReportList; +/* transinfo->redraw */ +typedef enum { + TREDRAW_NOTHING = 0, + TREDRAW_HARD = 1, + TREDRAW_SOFT = 2, +} eRedrawFlag; + typedef struct TransSnapPoint { struct TransSnapPoint *next, *prev; float co[3]; @@ -284,9 +291,9 @@ typedef struct TransInfo { int options; /* current context/options for transform */ float val; /* init value for some transformations (and rotation angle) */ float fac; /* factor for distance based transform */ - int (*transform)(struct TransInfo *, const int *); + void (*transform)(struct TransInfo *, const int[2]); /* transform function pointer */ - int (*handleEvent)(struct TransInfo *, const struct wmEvent *); + eRedrawFlag (*handleEvent)(struct TransInfo *, const struct wmEvent *); /* event handler function pointer RETURN 1 if redraw is needed */ int total; /* total number of transformed data */ TransData *data; /* transformed data (array) */ @@ -296,7 +303,7 @@ typedef struct TransInfo { TransSnap tsnap; NumInput num; /* numerical input */ MouseInput mouse; /* mouse input */ - char redraw; /* redraw flag */ + eRedrawFlag redraw; /* redraw flag */ float prop_size; /* proportional circle radius */ char proptext[20]; /* proportional falloff text */ float center[3]; /* center of transformation */ @@ -342,7 +349,7 @@ typedef struct TransInfo { float axis[3]; float axis_orig[3]; /* TransCon can change 'axis', store the original value here */ - short remove_on_cancel; /* remove elements if operator is cancelled */ + short remove_on_cancel; /* remove elements if operator is canceled */ void *view; struct bContext *context; /* Only valid (non null) during an operator called function. */ @@ -372,12 +379,6 @@ typedef struct TransInfo { #define TRANS_CONFIRM 2 #define TRANS_CANCEL 3 -/* transinfo->redraw */ -#define TREDRAW_NOTHING 0 -#define TREDRAW_HARD 1 -#define TREDRAW_SOFT 2 - - /* transinfo->flag */ #define T_OBJECT (1 << 0) #define T_EDIT (1 << 1) @@ -494,91 +495,6 @@ void projectFloatView(TransInfo *t, const float vec[3], float adr[2]); void applyAspectRatio(TransInfo *t, float *vec); void removeAspectRatio(TransInfo *t, float *vec); -void initWarp(TransInfo *t); -int handleEventWarp(TransInfo *t, const struct wmEvent *event); -int Warp(TransInfo *t, const int mval[2]); - -void initShear(TransInfo *t); -int handleEventShear(TransInfo *t, const struct wmEvent *event); -int Shear(TransInfo *t, const int mval[2]); - -void initResize(TransInfo *t); -int Resize(TransInfo *t, const int mval[2]); - -void initSkinResize(TransInfo *t); -int SkinResize(TransInfo *t, const int mval[2]); - -void initTranslation(TransInfo *t); -int Translation(TransInfo *t, const int mval[2]); - -void initToSphere(TransInfo *t); -int ToSphere(TransInfo *t, const int mval[2]); - -void initRotation(TransInfo *t); -int Rotation(TransInfo *t, const int mval[2]); - -void initShrinkFatten(TransInfo *t); -int ShrinkFatten(TransInfo *t, const int mval[2]); - -void initTilt(TransInfo *t); -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]); - -void initPushPull(TransInfo *t); -int PushPull(TransInfo *t, const int mval[2]); - -void initBevelWeight(TransInfo *t); -int BevelWeight(TransInfo *t, const int mval[2]); - -void initCrease(TransInfo *t); -int Crease(TransInfo *t, const int mval[2]); - -void initBoneSize(TransInfo *t); -int BoneSize(TransInfo *t, const int mval[2]); - -void initBoneEnvelope(TransInfo *t); -int BoneEnvelope(TransInfo *t, const int mval[2]); - -void initBoneRoll(TransInfo *t); -int BoneRoll(TransInfo *t, const int mval[2]); - -void initEdgeSlide(TransInfo *t); -int handleEventEdgeSlide(TransInfo *t, const struct wmEvent *event); -int EdgeSlide(TransInfo *t, const int mval[2]); - -void initVertSlide(TransInfo *t); -int handleEventVertSlide(TransInfo *t, const struct wmEvent *event); -int VertSlide(TransInfo *t, const int mval[2]); - -void initTimeTranslate(TransInfo *t); -int TimeTranslate(TransInfo *t, const int mval[2]); - -void initTimeSlide(TransInfo *t); -int TimeSlide(TransInfo *t, const int mval[2]); - -void initTimeScale(TransInfo *t); -int TimeScale(TransInfo *t, const int mval[2]); - -void initBakeTime(TransInfo *t); -int BakeTime(TransInfo *t, const int mval[2]); - -void initMirror(TransInfo *t); -int Mirror(TransInfo *t, const int mval[2]); - -void initAlign(TransInfo *t); -int Align(TransInfo *t, const int mval[2]); - -void initSeqSlide(TransInfo *t); -int SeqSlide(TransInfo *t, const int mval[2]); - void drawPropCircle(const struct bContext *C, TransInfo *t); struct wmKeyMap *transform_modal_keymap(struct wmKeyConfig *keyconf); @@ -650,24 +566,25 @@ typedef enum { SMALL_GEARS = 2 } GearsType; -void snapGrid(TransInfo *t, float *val); -void snapGridAction(TransInfo *t, float *val, GearsType action); +void snapGridIncrement(TransInfo *t, float *val); +void snapGridIncrementAction(TransInfo *t, float *val, GearsType action); bool activeSnap(TransInfo *t); bool validSnap(TransInfo *t); void initSnapping(struct TransInfo *t, struct wmOperator *op); void applyProject(TransInfo *t); +void applyGridAbsolute(TransInfo *t); void applySnapping(TransInfo *t, float *vec); void resetSnapping(TransInfo *t); -bool handleSnapping(TransInfo *t, const struct wmEvent *event); +eRedrawFlag handleSnapping(TransInfo *t, const struct wmEvent *event); void drawSnapping(const struct bContext *C, TransInfo *t); bool usingSnappingNormal(TransInfo *t); bool validSnappingNormal(TransInfo *t); void getSnapPoint(TransInfo *t, float vec[3]); void addSnapPoint(TransInfo *t); -bool updateSelectedSnapPoint(TransInfo *t); +eRedrawFlag updateSelectedSnapPoint(TransInfo *t); void removeSnapPoint(TransInfo *t); /********************** Mouse Input ******************************/ @@ -690,7 +607,7 @@ typedef enum { void initMouseInput(TransInfo *t, MouseInput *mi, const float center[2], const int mval[2]); void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode); -int handleMouseInput(struct TransInfo *t, struct MouseInput *mi, const struct wmEvent *event); +eRedrawFlag handleMouseInput(struct TransInfo *t, struct MouseInput *mi, const struct wmEvent *event); void applyMouseInput(struct TransInfo *t, struct MouseInput *mi, const int mval[2], float output[3]); void setCustomPoints(TransInfo *t, MouseInput *mi, const int start[2], const int end[2]); diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index a73bf86feb1..4ba87eb8c39 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -135,7 +135,7 @@ static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3]) mul_m3_v3(t->con.imtx, vec); - snapGrid(t, vec); + snapGridIncrement(t, vec); if (t->num.flag & T_NULL_ONE) { if (!(t->con.mode & CON_AXIS0)) @@ -569,7 +569,7 @@ void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[]) t->con.applyVec = applyAxisConstraintVec; t->con.applySize = applyAxisConstraintSize; t->con.applyRot = applyAxisConstraintRot; - t->redraw = 1; + t->redraw = TREDRAW_HARD; } /* applies individual td->axismtx constraints */ @@ -590,7 +590,7 @@ void setAxisMatrixConstraint(TransInfo *t, int mode, const char text[]) t->con.applyVec = applyObjectConstraintVec; t->con.applySize = applyObjectConstraintSize; t->con.applyRot = applyObjectConstraintRot; - t->redraw = 1; + t->redraw = TREDRAW_HARD; } } @@ -792,6 +792,13 @@ static void drawObjectConstraint(TransInfo *t) float co[3]; float (*axismtx)[3]; + if (t->flag & T_PROP_EDIT) { + /* we're sorted, so skip the rest */ + if (td->factor == 0.0f) { + break; + } + } + if (t->flag & T_OBJECT) { copy_v3_v3(co, td->ob->obmat[3]); axismtx = td->axismtx; @@ -904,7 +911,7 @@ void postSelectConstraint(TransInfo *t) setNearestAxis(t); startConstraint(t); - t->redraw = 1; + t->redraw = TREDRAW_HARD; } static void setNearestAxis2d(TransInfo *t) @@ -923,9 +930,9 @@ static void setNearestAxis2d(TransInfo *t) static void setNearestAxis3d(TransInfo *t) { float zfac; - float mvec[3], axis[3], proj[3]; + float mvec[3], proj[3]; float len[3]; - int i, icoord[2]; + int i; /* calculate mouse movement */ mvec[0] = (float)(t->mval[0] - t->con.imval[0]); @@ -943,15 +950,16 @@ static void setNearestAxis3d(TransInfo *t) zfac = len_v3(t->persinv[0]) * 2.0f / t->ar->winx * zfac * 30.0f; for (i = 0; i < 3; i++) { + float axis[3], axis_2d[2]; + copy_v3_v3(axis, t->con.mtx[i]); mul_v3_fl(axis, zfac); /* now we can project to get window coordinate */ add_v3_v3(axis, t->con.center); - projectIntView(t, axis, icoord); + projectFloatView(t, axis, axis_2d); - axis[0] = (float)(icoord[0] - t->center2d[0]); - axis[1] = (float)(icoord[1] - t->center2d[1]); + sub_v2_v2v2(axis, axis_2d, t->center2d); axis[2] = 0.0f; if (normalize_v3(axis) != 0.0f) { diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index f5a12fed076..06da1edbcdc 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -2008,8 +2008,8 @@ static struct TransIslandData *editmesh_islands_info_calc(BMEditMesh *em, int *r * its possible we have a selected vertex thats not in a face, for now best not crash in that case. */ fill_vn_i(vert_map, bm->totvert, -1); - EDBM_index_arrays_ensure(em, htype); - ele_array = (htype == BM_FACE) ? (void **)em->face_index : (void **)em->edge_index; + BM_mesh_elem_table_ensure(bm, htype); + ele_array = (htype == BM_FACE) ? (void **)bm->ftable : (void **)bm->etable; BM_mesh_elem_index_ensure(bm, BM_VERT); @@ -2098,9 +2098,7 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx } else if (t->around == V3D_LOCAL) { copy_v3_v3(td->center, td->loc); - - axis_dominant_v3_to_m3(td->axismtx, eve->no); - invert_m3(td->axismtx); + createSpaceNormal(td->axismtx, eve->no); } else { copy_v3_v3(td->center, td->loc); @@ -2383,16 +2381,16 @@ void flushTransNodes(TransInfo *t) int a; TransData *td; TransData2D *td2d; - + + applyGridAbsolute(t); + /* flush to 2d vector from internally used 3d vector */ for (a = 0, td = t->data, td2d = t->data2d; a < t->total; a++, td++, td2d++) { bNode *node = td->extra; - float vec[2]; /* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */ - add_v2_v2v2(vec, td2d->loc, td2d->ih1); - node->locx = vec[0] / UI_DPI_FAC; - node->locy = vec[1] / UI_DPI_FAC; + node->locx = td2d->loc[0] / UI_DPI_FAC; + node->locy = td2d->loc[1] / UI_DPI_FAC; } /* handle intersection with noodles */ @@ -2578,10 +2576,10 @@ static void createTransUVs(bContext *C, TransInfo *t) if (propconnected) { /* create element map with island information */ if (ts->uv_flag & UV_SYNC_SELECTION) { - elementmap = EDBM_uv_element_map_create(em, false, true); + elementmap = BM_uv_element_map_create(em->bm, false, true); } else { - elementmap = EDBM_uv_element_map_create(em, true, true); + elementmap = BM_uv_element_map_create(em->bm, true, true); } island_enabled = MEM_callocN(sizeof(*island_enabled) * elementmap->totalIslands, "TransIslandData(UV Editing)"); } @@ -2600,7 +2598,7 @@ static void createTransUVs(bContext *C, TransInfo *t) countsel++; if (propconnected) { - UvElement *element = ED_uv_element_get(elementmap, efa, l); + UvElement *element = BM_uv_element_get(elementmap, efa, l); island_enabled[element->island] = TRUE; } @@ -2636,7 +2634,7 @@ static void createTransUVs(bContext *C, TransInfo *t) continue; if (propconnected) { - UvElement *element = ED_uv_element_get(elementmap, efa, l); + UvElement *element = BM_uv_element_get(elementmap, efa, l); if (!island_enabled[element->island]) { count_rejected++; continue; @@ -2650,7 +2648,7 @@ static void createTransUVs(bContext *C, TransInfo *t) if (propconnected) { t->total -= count_rejected; - EDBM_uv_element_map_free(elementmap); + BM_uv_element_map_free(elementmap); MEM_freeN(island_enabled); } @@ -3716,12 +3714,14 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) float mtx[3][3], smtx[3][3]; const bool use_handle = !(sipo->flag & SIPO_NOHANDLES); const bool use_local_center = checkUseLocalCenter_GraphEdit(t); - const short anim_map_flag = ANIM_UNITCONV_ONLYSEL | ANIM_UNITCONV_SELVERTS; + short anim_map_flag = ANIM_UNITCONV_ONLYSEL | ANIM_UNITCONV_SELVERTS; /* determine what type of data we are operating on */ if (ANIM_animdata_get_context(C, &ac) == 0) return; - + + anim_map_flag |= ANIM_get_normalization_flags(&ac); + /* filter data */ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); @@ -3837,7 +3837,9 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) AnimData *adt = ANIM_nla_mapping_get(&ac, ale); FCurve *fcu = (FCurve *)ale->key_data; short intvals = (fcu->flag & FCURVE_INT_VALUES); - + float unit_scale; + float scaled_mtx[3][3], scaled_smtx[3][3]; + /* convert current-frame to action-time (slightly less accurate, especially under * higher scaling ratios, but is faster than converting all points) */ @@ -3850,8 +3852,13 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) if (fcu->bezt == NULL) continue; - ANIM_unit_mapping_apply_fcurve(ac.scene, ale->id, ale->key_data, anim_map_flag); - + unit_scale = ANIM_unit_mapping_get_factor(ac.scene, ale->id, ale->key_data, anim_map_flag); + + copy_m3_m3(scaled_mtx, mtx); + copy_m3_m3(scaled_smtx, smtx); + mul_v3_fl(scaled_mtx[1], unit_scale); + mul_v3_fl(scaled_smtx[1], 1.0f / unit_scale); + /* only include BezTriples whose 'keyframe' occurs on the same side of the current frame as mouse (if applicable) */ for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) { if (FrameOnMouseSide(t->frame_side, bezt->vec[1][0], cfra)) { @@ -3868,7 +3875,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) if (!ELEM3(t->mode, TFM_TRANSLATION, TFM_TIME_TRANSLATE, TFM_TIME_SLIDE) || !(sel2)) { if (sel1) { hdata = initTransDataCurveHandles(td, bezt); - bezt_to_transdata(td++, td2d++, adt, bezt, 0, 1, 1, intvals, mtx, smtx); + bezt_to_transdata(td++, td2d++, adt, bezt, 0, 1, 1, intvals, scaled_mtx, scaled_smtx); } else { /* h1 = 0; */ /* UNUSED */ @@ -3877,7 +3884,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) if (sel3) { if (hdata == NULL) hdata = initTransDataCurveHandles(td, bezt); - bezt_to_transdata(td++, td2d++, adt, bezt, 2, 1, 1, intvals, mtx, smtx); + bezt_to_transdata(td++, td2d++, adt, bezt, 2, 1, 1, intvals, scaled_mtx, scaled_smtx); } else { /* h2 = 0; */ /* UNUSED */ @@ -3899,7 +3906,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) hdata = initTransDataCurveHandles(td, bezt); } - bezt_to_transdata(td++, td2d++, adt, bezt, 1, 1, 0, intvals, mtx, smtx); + bezt_to_transdata(td++, td2d++, adt, bezt, 1, 1, 0, intvals, scaled_mtx, scaled_smtx); } /* special hack (must be done after initTransDataCurveHandles(), as that stores handle settings to restore...): @@ -3921,13 +3928,6 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) /* Sets handles based on the selection */ testhandles_fcurve(fcu, use_handle); - - /* even though transform values are written back right after during transform, - * using individual center's with rotation means the center point wont - * be touched again see: [#34303] */ - if (use_local_center) { - ANIM_unit_mapping_apply_fcurve(ac.scene, ale->id, ale->key_data, anim_map_flag | ANIM_UNITCONV_RESTORE); - } } /* cleanup temp list */ @@ -4591,7 +4591,7 @@ static void freeSeqData(TransInfo *t) BKE_sequencer_sort(t->scene); } else { - /* Cancelled, need to update the strips display */ + /* Canceled, need to update the strips display */ for (a = 0; a < t->total; a++, td++) { seq = ((TransDataSeq *)td->extra)->seq; if ((seq != seq_prev) && (seq->depth == 0)) { @@ -4715,13 +4715,12 @@ static bool constraints_list_needinv(TransInfo *t, ListBase *list) if ((con->flag & CONSTRAINT_DISABLE) == 0 && (con->enforce != 0.0f)) { /* (affirmative) returns for specific constraints here... */ /* constraints that require this regardless */ - if (ELEM6(con->type, + if (ELEM5(con->type, CONSTRAINT_TYPE_CHILDOF, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO, CONSTRAINT_TYPE_OBJECTSOLVER, - CONSTRAINT_TYPE_FOLLOWTRACK, - CONSTRAINT_TYPE_TRANSFORM)) + CONSTRAINT_TYPE_FOLLOWTRACK)) { return true; } @@ -4734,6 +4733,15 @@ static bool constraints_list_needinv(TransInfo *t, ListBase *list) if ((data->flag & ROTLIKE_OFFSET) && (t->mode == TFM_ROTATION)) return true; } + else if (con->type == CONSTRAINT_TYPE_TRANSFORM) { + /* Transform constraint needs it for rotation at least (r.57309), + * but doing so when translating may also mess things up [#36203] + */ + + if (t->mode == TFM_ROTATION) + return true; + /* ??? (t->mode == TFM_SCALE) ? */ + } } } } @@ -5863,6 +5871,9 @@ int special_transform_moving(TransInfo *t) if (t->spacetype == SPACE_SEQ) { return G_TRANSFORM_SEQ; } + else if (t->spacetype == SPACE_IPO) { + return G_TRANSFORM_FCURVES; + } else if (t->obedit || ((t->flag & T_POSE) && (t->poseobj))) { return G_TRANSFORM_EDIT; } @@ -5951,12 +5962,10 @@ static void createTransObject(bContext *C, TransInfo *t) /* transcribe given node into TransData2D for Transforming */ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node) { - /* hold original location */ - float locxy[2] = {BLI_rctf_cent_x(&node->totr), - BLI_rctf_cent_y(&node->totr)}; - float nodeloc[2]; - - copy_v2_v2(td2d->loc, locxy); + /* use top-left corner as the transform origin for nodes */ + /* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */ + td2d->loc[0] = UI_DPI_FAC * node->locx; + td2d->loc[1] = UI_DPI_FAC * node->locy; td2d->loc[2] = 0.0f; td2d->loc2d = td2d->loc; /* current location */ @@ -5965,8 +5974,8 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node) td->loc = td2d->loc; copy_v3_v3(td->iloc, td->loc); /* use node center instead of origin (top-left corner) */ - td->center[0] = locxy[0]; - td->center[1] = locxy[1]; + td->center[0] = td2d->loc[0] + BLI_rctf_size_x(&node->totr); + td->center[1] = td2d->loc[1] + BLI_rctf_size_y(&node->totr); td->center[2] = 0.0f; memset(td->axismtx, 0, sizeof(td->axismtx)); @@ -5980,11 +5989,6 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node) unit_m3(td->mtx); unit_m3(td->smtx); - /* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */ - nodeloc[0] = UI_DPI_FAC * node->locx; - nodeloc[1] = UI_DPI_FAC * node->locy; - sub_v2_v2v2(td2d->ih1, nodeloc, locxy); - td->extra = node; } @@ -6821,8 +6825,11 @@ void flushTransMasking(TransInfo *t) td->loc2d[1] = td->loc[1] * inv[1]; mul_m3_v2(tdm->parent_inverse_matrix, td->loc2d); - if (tdm->is_handle) - BKE_mask_point_set_handle(tdm->point, td->loc2d, t->flag & T_ALT_TRANSFORM, tdm->orig_handle, tdm->vec); + if (tdm->is_handle) { + BKE_mask_point_set_handle(tdm->point, td->loc2d, + (t->flag & T_ALT_TRANSFORM) != 0, + tdm->orig_handle, tdm->vec); + } } } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 94f481d8dfc..95b6067f2c4 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -381,9 +381,6 @@ static void recalcData_graphedit(TransInfo *t) bAnimListElem *ale; int dosort = 0; - const bool use_local_center = checkUseLocalCenter_GraphEdit(t); - - /* initialize relevant anim-context 'context' data from TransInfo data */ /* NOTE: sync this with the code in ANIM_animdata_get_context() */ scene = ac.scene = t->scene; @@ -411,11 +408,6 @@ static void recalcData_graphedit(TransInfo *t) if (!fcu_test_selected(fcu)) continue; - ANIM_unit_mapping_apply_fcurve(ac.scene, ale->id, ale->key_data, - ANIM_UNITCONV_ONLYSEL | ANIM_UNITCONV_SELVERTS | ANIM_UNITCONV_RESTORE | - (use_local_center ? ANIM_UNITCONV_SKIPKNOTS : 0)); - - /* watch it: if the time is wrong: do not correct handles yet */ if (test_time_fcurve(fcu)) dosort++; @@ -1066,7 +1058,7 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *even t->flag = 0; - t->redraw = 1; /* redraw first time */ + t->redraw = TREDRAW_HARD; /* redraw first time */ if (event) { copy_v2_v2_int(t->imval, event->mval); @@ -1145,8 +1137,8 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *even if (v3d->flag & V3D_ALIGN) t->flag |= T_V3D_ALIGN; t->around = v3d->around; - /* warp always uses the cursor */ - if (t->mode == TFM_WARP) { + /* bend always uses the cursor */ + if (t->mode == TFM_BEND) { t->around = V3D_CURSOR; } @@ -1500,7 +1492,7 @@ void calculateCenterCursor(TransInfo *t) { const float *cursor; - cursor = give_cursor(t->scene, t->view); + cursor = ED_view3d_cursor3d_get(t->scene, t->view); copy_v3_v3(t->center, cursor); /* If edit or pose mode, move cursor in local space */ diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c index ee993129303..39c7b4b5c1c 100644 --- a/source/blender/editors/transform/transform_input.c +++ b/source/blender/editors/transform/transform_input.c @@ -407,9 +407,9 @@ void applyMouseInput(TransInfo *t, MouseInput *mi, const int mval[2], float outp } } -int handleMouseInput(TransInfo *t, MouseInput *mi, const wmEvent *event) +eRedrawFlag handleMouseInput(TransInfo *t, MouseInput *mi, const wmEvent *event) { - int redraw = TREDRAW_NOTHING; + eRedrawFlag redraw = TREDRAW_NOTHING; switch (event->type) { case LEFTSHIFTKEY: diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index f667a98812b..132a46441e6 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -1635,7 +1635,7 @@ void BIF_draw_manipulator(const bContext *C) copy_v3_v3(rv3d->twmat[3], scene->twcent); break; case V3D_CURSOR: - copy_v3_v3(rv3d->twmat[3], give_cursor(scene, v3d)); + copy_v3_v3(rv3d->twmat[3], ED_view3d_cursor3d_get(scene, v3d)); break; } diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 2904b37c2e5..106024cd3e2 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -68,7 +68,7 @@ static char OP_TOSPHERE[] = "TRANSFORM_OT_tosphere"; static char OP_RESIZE[] = "TRANSFORM_OT_resize"; static char OP_SKIN_RESIZE[] = "TRANSFORM_OT_skin_resize"; static char OP_SHEAR[] = "TRANSFORM_OT_shear"; -static char OP_WARP[] = "TRANSFORM_OT_warp"; +static char OP_BEND[] = "TRANSFORM_OT_bend"; static char OP_SHRINK_FATTEN[] = "TRANSFORM_OT_shrink_fatten"; static char OP_PUSH_PULL[] = "TRANSFORM_OT_push_pull"; static char OP_TILT[] = "TRANSFORM_OT_tilt"; @@ -86,7 +86,7 @@ static void TRANSFORM_OT_tosphere(struct wmOperatorType *ot); static void TRANSFORM_OT_resize(struct wmOperatorType *ot); static void TRANSFORM_OT_skin_resize(struct wmOperatorType *ot); static void TRANSFORM_OT_shear(struct wmOperatorType *ot); -static void TRANSFORM_OT_warp(struct wmOperatorType *ot); +static void TRANSFORM_OT_bend(struct wmOperatorType *ot); static void TRANSFORM_OT_shrink_fatten(struct wmOperatorType *ot); static void TRANSFORM_OT_push_pull(struct wmOperatorType *ot); static void TRANSFORM_OT_tilt(struct wmOperatorType *ot); @@ -106,7 +106,7 @@ static TransformModeItem transform_modes[] = {OP_RESIZE, TFM_RESIZE, TRANSFORM_OT_resize}, {OP_SKIN_RESIZE, TFM_SKIN_RESIZE, TRANSFORM_OT_skin_resize}, {OP_SHEAR, TFM_SHEAR, TRANSFORM_OT_shear}, - {OP_WARP, TFM_WARP, TRANSFORM_OT_warp}, + {OP_BEND, TFM_BEND, TRANSFORM_OT_bend}, {OP_SHRINK_FATTEN, TFM_SHRINKFATTEN, TRANSFORM_OT_shrink_fatten}, {OP_PUSH_PULL, TFM_PUSHPULL, TRANSFORM_OT_push_pull}, {OP_TILT, TFM_TILT, TRANSFORM_OT_tilt}, @@ -130,7 +130,7 @@ EnumPropertyItem transform_mode_types[] = {TFM_SKIN_RESIZE, "SKIN_RESIZE", 0, "Skin Resize", ""}, {TFM_TOSPHERE, "TOSPHERE", 0, "Tosphere", ""}, {TFM_SHEAR, "SHEAR", 0, "Shear", ""}, - {TFM_WARP, "WARP", 0, "Warp", ""}, + {TFM_BEND, "BEND", 0, "Bend", ""}, {TFM_SHRINKFATTEN, "SHRINKFATTEN", 0, "Shrinkfatten", ""}, {TFM_TILT, "TILT", 0, "Tilt", ""}, {TFM_TRACKBALL, "TRACKBALL", 0, "Trackball", ""}, @@ -426,15 +426,13 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event) return exit_code; } -static int transform_cancel(bContext *C, wmOperator *op) +static void transform_cancel(bContext *C, wmOperator *op) { TransInfo *t = op->customdata; t->state = TRANS_CANCEL; transformEnd(C, t); transformops_exit(C, op); - - return OPERATOR_CANCELLED; } static int transform_exec(bContext *C, wmOperator *op) @@ -695,12 +693,12 @@ static void TRANSFORM_OT_tilt(struct wmOperatorType *ot) Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP); } -static void TRANSFORM_OT_warp(struct wmOperatorType *ot) +static void TRANSFORM_OT_bend(struct wmOperatorType *ot) { /* identifiers */ - ot->name = "Warp"; - ot->description = "Warp selected items around the cursor"; - ot->idname = OP_WARP; + ot->name = "Bend"; + ot->description = "Bend selected items between the 3D cursor and the mouse"; + ot->idname = OP_BEND; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* api callbacks */ @@ -708,12 +706,11 @@ static void TRANSFORM_OT_warp(struct wmOperatorType *ot) ot->exec = transform_exec; ot->modal = transform_modal; ot->cancel = transform_cancel; - ot->poll = ED_operator_screenactive; + ot->poll = ED_operator_region_view3d_active; RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP); - // XXX Warp axis? } static void TRANSFORM_OT_shear(struct wmOperatorType *ot) @@ -984,7 +981,7 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, OP_WARP, WKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, OP_BEND, WKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, OP_TOSPHERE, SKEY, KM_PRESS, KM_ALT | KM_SHIFT, 0); diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 04bccac2a15..4cda56028ca 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -37,6 +37,7 @@ #include "PIL_time.h" #include "DNA_armature_types.h" +#include "DNA_curve_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" #include "DNA_mesh_types.h" @@ -117,7 +118,7 @@ int BIF_snappingSupported(Object *obedit) { int status = 0; - if (obedit == NULL || ELEM4(obedit->type, OB_MESH, OB_ARMATURE, OB_CURVE, OB_LATTICE)) /* only support object mesh, armature, curves */ + if (obedit == NULL || ELEM5(obedit->type, OB_MESH, OB_ARMATURE, OB_CURVE, OB_LATTICE, OB_MBALL)) /* only support object mesh, armature, curves */ { status = 1; } @@ -267,16 +268,16 @@ void drawSnapping(const struct bContext *C, TransInfo *t) } } -bool handleSnapping(TransInfo *t, const wmEvent *event) +eRedrawFlag handleSnapping(TransInfo *t, const wmEvent *event) { - bool status = false; + eRedrawFlag status = TREDRAW_NOTHING; #if 0 // XXX need a proper selector for all snap mode if (BIF_snappingSupported(t->obedit) && event->type == TABKEY && event->shift) { /* toggle snap and reinit */ t->settings->snap_flag ^= SCE_SNAP; initSnapping(t, NULL); - status = 1; + status = TREDRAW_HARD; } #endif if (event->type == MOUSEMOVE) { @@ -344,6 +345,70 @@ void applyProject(TransInfo *t) } } +void applyGridAbsolute(TransInfo *t) +{ + float grid_size = 0.0f; + GearsType grid_action; + TransData *td; + float imat[4][4]; + int i; + + if (!(activeSnap(t) && (t->tsnap.mode == SCE_SNAP_MODE_GRID))) + return; + + grid_action = BIG_GEARS; + if (t->modifiers & MOD_PRECISION) + grid_action = SMALL_GEARS; + + switch (grid_action) { + case NO_GEARS: grid_size = t->snap[0]; break; + case BIG_GEARS: grid_size = t->snap[1]; break; + case SMALL_GEARS: grid_size = t->snap[2]; break; + } + /* early exit on unusable grid size */ + if (grid_size == 0.0f) + return; + + if (t->flag & (T_EDIT | T_POSE)) { + Object *ob = t->obedit ? t->obedit : t->poseobj; + invert_m4_m4(imat, ob->obmat); + } + + for (i = 0, td = t->data; i < t->total; i++, td++) { + float iloc[3], loc[3], tvec[3]; + + if (td->flag & TD_NOACTION) + break; + + if (td->flag & TD_SKIP) + continue; + + if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f)) + continue; + + copy_v3_v3(iloc, td->loc); + if (t->flag & (T_EDIT | T_POSE)) { + Object *ob = t->obedit ? t->obedit : t->poseobj; + mul_m4_v3(ob->obmat, iloc); + } + else if (t->flag & T_OBJECT) { + td->ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; + BKE_object_handle_update(t->scene, td->ob); + copy_v3_v3(iloc, td->ob->obmat[3]); + } + + mul_v3_v3fl(loc, iloc, 1.0f / grid_size); + loc[0] = floorf(loc[0]); + loc[1] = floorf(loc[1]); + loc[2] = floorf(loc[2]); + mul_v3_fl(loc, grid_size); + + sub_v3_v3v3(tvec, loc, iloc); + mul_m3_v3(td->smtx, tvec); + add_v3_v3(td->loc, tvec); + } +} + void applySnapping(TransInfo *t, float *vec) { /* project is not applied this way */ @@ -440,7 +505,7 @@ static void initSnappingMode(TransInfo *t) /* Edit mode */ if (t->tsnap.applySnap != NULL && // A snapping function actually exist - (obedit != NULL && ELEM4(obedit->type, OB_MESH, OB_ARMATURE, OB_CURVE, OB_LATTICE)) ) // Temporary limited to edit mode meshes, armature, curves + (obedit != NULL && ELEM5(obedit->type, OB_MESH, OB_ARMATURE, OB_CURVE, OB_LATTICE, OB_MBALL)) ) // Temporary limited to edit mode meshes, armature, curves, mballs { /* Exclude editmesh if using proportional edit */ if ((obedit->type == OB_MESH) && (t->flag & T_PROP_EDIT)) { @@ -606,9 +671,10 @@ void addSnapPoint(TransInfo *t) } } -bool updateSelectedSnapPoint(TransInfo *t) +eRedrawFlag updateSelectedSnapPoint(TransInfo *t) { - bool status = false; + eRedrawFlag status = TREDRAW_NOTHING; + if (t->tsnap.status & MULTI_POINTS) { TransSnapPoint *p, *closest_p = NULL; float closest_dist = TRANSFORM_SNAP_MAX_PX; @@ -631,7 +697,10 @@ bool updateSelectedSnapPoint(TransInfo *t) } if (closest_p) { - status = (t->tsnap.selectedPoint != closest_p); + if (t->tsnap.selectedPoint != closest_p) { + status = TREDRAW_HARD; + } + t->tsnap.selectedPoint = closest_p; } } @@ -814,7 +883,7 @@ static float ResizeBetween(TransInfo *t, float p1[3], float p2[3]) static void UNUSED_FUNCTION(CalcSnapGrid) (TransInfo *t, float *UNUSED(vec)) { - snapGridAction(t, t->tsnap.snapPoint, BIG_GEARS); + snapGridIncrementAction(t, t->tsnap.snapPoint, BIG_GEARS); } static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec)) @@ -1347,6 +1416,79 @@ static bool snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *ar return retval; } +static bool snapCurve(short snap_mode, ARegion *ar, Object *ob, Curve *cu, float obmat[4][4], + const float ray_start[3], const float ray_normal[3], const float mval[2], + float r_loc[3], float *UNUSED(r_no), float *r_dist_px, float *r_depth) +{ + float imat[4][4]; + float ray_start_local[3], ray_normal_local[3]; + bool retval = false; + int u; + + Nurb *nu; + + /* only vertex snapping mode (eg control points and handles) supported for now) */ + if (snap_mode != SCE_SNAP_MODE_VERTEX) { + return retval; + } + + invert_m4_m4(imat, obmat); + + copy_v3_v3(ray_start_local, ray_start); + copy_v3_v3(ray_normal_local, ray_normal); + + mul_m4_v3(imat, ray_start_local); + mul_mat3_m4_v3(imat, ray_normal_local); + + for (nu = (ob->mode == OB_MODE_EDIT ? cu->editnurb->nurbs.first : cu->nurb.first); nu; nu = nu->next) { + for (u = 0; u < nu->pntsu; u++) { + switch (snap_mode) { + case SCE_SNAP_MODE_VERTEX: + { + if (ob->mode == OB_MODE_EDIT) { + if (nu->bezt) { + /* don't snap to selected (moving) or hidden */ + if (nu->bezt[u].f2 & SELECT || nu->bezt[u].hide != 0) { + break; + } + retval |= snapVertex(ar, nu->bezt[u].vec[1], NULL, obmat, NULL, ray_start, ray_start_local, ray_normal_local, mval, r_loc, NULL, r_dist_px, r_depth); + /* don't snap if handle is selected (moving), or if it is aligning to a moving handle */ + if (!(nu->bezt[u].f1 & SELECT) && !(nu->bezt[u].h1 & HD_ALIGN && nu->bezt[u].f3 & SELECT)) { + retval |= snapVertex(ar, nu->bezt[u].vec[0], NULL, obmat, NULL, ray_start, ray_start_local, ray_normal_local, mval, r_loc, NULL, r_dist_px, r_depth); + } + if (!(nu->bezt[u].f3 & SELECT) && !(nu->bezt[u].h2 & HD_ALIGN && nu->bezt[u].f1 & SELECT)) { + retval |= snapVertex(ar, nu->bezt[u].vec[2], NULL, obmat, NULL, ray_start, ray_start_local, ray_normal_local, mval, r_loc, NULL, r_dist_px, r_depth); + } + } + else { + /* don't snap to selected (moving) or hidden */ + if (nu->bp[u].f1 & SELECT || nu->bp[u].hide != 0) { + break; + } + retval |= snapVertex(ar, nu->bp[u].vec, NULL, obmat, NULL, ray_start, ray_start_local, ray_normal_local, mval, r_loc, NULL, r_dist_px, r_depth); + } + } + else { + /* curve is not visible outside editmode if nurb length less than two */ + if (nu->pntsu > 1) { + if (nu->bezt) { + retval |= snapVertex(ar, nu->bezt[u].vec[1], NULL, obmat, NULL, ray_start, ray_start_local, ray_normal_local, mval, r_loc, NULL, r_dist_px, r_depth); + } + else { + retval |= snapVertex(ar, nu->bp[u].vec, NULL, obmat, NULL, ray_start, ray_start_local, ray_normal_local, mval, r_loc, NULL, r_dist_px, r_depth); + } + } + } + break; + } + default: + break; + } + } + } + return retval; +} + static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, BMEditMesh *em, float obmat[4][4], const float ray_start[3], const float ray_normal[3], const float mval[2], float r_loc[3], float r_no[3], float *r_dist_px, float *r_depth) @@ -1425,7 +1567,7 @@ static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMes if (em != NULL) { index_array = dm->getVertDataArray(dm, CD_ORIGINDEX); - EDBM_index_arrays_ensure(em, BM_VERT); + BM_mesh_elem_table_ensure(em->bm, BM_VERT); } for (i = 0; i < totvert; i++) { @@ -1446,7 +1588,7 @@ static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMes test = 0; } else { - eve = EDBM_vert_at_index(em, index); + eve = BM_vert_at_index(em->bm, index); if ((BM_elem_flag_test(eve, BM_ELEM_HIDDEN) || BM_elem_flag_test(eve, BM_ELEM_SELECT))) @@ -1475,7 +1617,7 @@ static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMes if (em != NULL) { index_array = dm->getEdgeDataArray(dm, CD_ORIGINDEX); - EDBM_index_arrays_ensure(em, BM_EDGE); + BM_mesh_elem_table_ensure(em->bm, BM_EDGE); } for (i = 0; i < totedge; i++) { @@ -1495,7 +1637,7 @@ static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMes test = 0; } else { - BMEdge *eed = EDBM_edge_at_index(em, index); + BMEdge *eed = BM_edge_at_index(em->bm, index); if ((BM_elem_flag_test(eed, BM_ELEM_HIDDEN) || BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) || @@ -1670,6 +1812,9 @@ static bool snapObject(Scene *scene, short snap_mode, ARegion *ar, Object *ob, f else if (ob->type == OB_ARMATURE) { retval = snapArmature(snap_mode, ar, ob, ob->data, obmat, ray_start, ray_normal, mval, r_loc, r_no, r_dist_px, r_depth); } + else if (ob->type == OB_CURVE) { + retval = snapCurve(snap_mode, ar, ob, ob->data, obmat, ray_start, ray_normal, mval, r_loc, r_no, r_dist_px, r_depth); + } else if (ob->type == OB_EMPTY) { retval = snapEmpty(snap_mode, ar, ob, obmat, ray_start, ray_normal, mval, r_loc, r_no, r_dist_px, r_depth); } @@ -2165,10 +2310,10 @@ bool snapNodesContext(bContext *C, const int mval[2], float *r_dist_px, float r_ /*================================================================*/ -static void applyGrid(TransInfo *t, float *val, int max_index, float fac[3], GearsType action); +static void applyGridIncrement(TransInfo *t, float *val, int max_index, float fac[3], GearsType action); -void snapGridAction(TransInfo *t, float *val, GearsType action) +void snapGridIncrementAction(TransInfo *t, float *val, GearsType action) { float fac[3]; @@ -2176,11 +2321,11 @@ void snapGridAction(TransInfo *t, float *val, GearsType action) fac[BIG_GEARS] = t->snap[1]; fac[SMALL_GEARS] = t->snap[2]; - applyGrid(t, val, t->idx_max, fac, action); + applyGridIncrement(t, val, t->idx_max, fac, action); } -void snapGrid(TransInfo *t, float *val) +void snapGridIncrement(TransInfo *t, float *val) { GearsType action; @@ -2194,17 +2339,17 @@ void snapGrid(TransInfo *t, float *val) action = SMALL_GEARS; } - snapGridAction(t, val, action); + snapGridIncrementAction(t, val, action); } -static void applyGrid(TransInfo *t, float *val, int max_index, float fac[3], GearsType action) +static void applyGridIncrement(TransInfo *t, float *val, int max_index, float fac[3], GearsType action) { int i; float asp[3] = {1.0f, 1.0f, 1.0f}; // TODO: Remove hard coded limit here (3) if (max_index > 2) { - printf("applyGrid: invalid index %d, clamping\n", max_index); + printf("applyGridIncrement: invalid index %d, clamping\n", max_index); max_index = 2; } diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt index e72385b311d..6c0bf92a484 100644 --- a/source/blender/editors/util/CMakeLists.txt +++ b/source/blender/editors/util/CMakeLists.txt @@ -35,6 +35,7 @@ set(INC_SYS ) set(SRC + ed_transverts.c ed_util.c editmode_undo.c numinput.c @@ -79,6 +80,7 @@ set(SRC ../include/ED_space_api.h ../include/ED_text.h ../include/ED_transform.h + ../include/ED_transverts.h ../include/ED_types.h ../include/ED_util.h ../include/ED_uvedit.h diff --git a/source/blender/editors/util/ed_transverts.c b/source/blender/editors/util/ed_transverts.c new file mode 100644 index 00000000000..4123132ad03 --- /dev/null +++ b/source/blender/editors/util/ed_transverts.c @@ -0,0 +1,462 @@ +/* + * ***** 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) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_view3d/ed_transverts.c + * \ingroup edutil + */ + +#include "MEM_guardedalloc.h" + +#include "DNA_armature_types.h" +#include "DNA_curve_types.h" +#include "DNA_lattice_types.h" +#include "DNA_meta_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" + +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" +#include "BLI_math.h" + +#include "BKE_curve.h" +#include "BKE_depsgraph.h" +#include "BKE_lattice.h" +#include "BKE_editmesh.h" +#include "BKE_DerivedMesh.h" + +#include "ED_armature.h" + +#include "ED_transverts.h" /* own include */ + + +/* copied from editobject.c, now uses (almost) proper depgraph */ +void ED_transverts_update_obedit(TransVertStore *tvs, Object *obedit) +{ + BLI_assert(ED_transverts_check_obedit(obedit) == true); + + DAG_id_tag_update(obedit->data, 0); + + if (obedit->type == OB_MESH) { + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BM_mesh_normals_update(em->bm); + } + else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { + Curve *cu = obedit->data; + ListBase *nurbs = BKE_curve_editNurbs_get(cu); + Nurb *nu = nurbs->first; + + while (nu) { + /* keep handles' vectors unchanged */ + if (nu->bezt) { + int a = nu->pntsu; + TransVert *tv = tvs->transverts; + BezTriple *bezt = nu->bezt; + + while (a--) { + if (bezt->f1 & SELECT) tv++; + + if (bezt->f2 & SELECT) { + float v[3]; + + if (bezt->f1 & SELECT) { + sub_v3_v3v3(v, (tv - 1)->oldloc, tv->oldloc); + add_v3_v3v3(bezt->vec[0], bezt->vec[1], v); + } + + if (bezt->f3 & SELECT) { + sub_v3_v3v3(v, (tv + 1)->oldloc, tv->oldloc); + add_v3_v3v3(bezt->vec[2], bezt->vec[1], v); + } + + tv++; + } + + if (bezt->f3 & SELECT) tv++; + + bezt++; + } + } + + BKE_nurb_test2D(nu); + BKE_nurb_handles_test(nu, true); /* test for bezier too */ + nu = nu->next; + } + } + else if (obedit->type == OB_ARMATURE) { + bArmature *arm = obedit->data; + EditBone *ebo; + TransVert *tv = tvs->transverts; + int a = 0; + + /* Ensure all bone tails are correctly adjusted */ + for (ebo = arm->edbo->first; ebo; ebo = ebo->next) { + /* adjust tip if both ends selected */ + if ((ebo->flag & BONE_ROOTSEL) && (ebo->flag & BONE_TIPSEL)) { + if (tv) { + float diffvec[3]; + + sub_v3_v3v3(diffvec, tv->loc, tv->oldloc); + add_v3_v3(ebo->tail, diffvec); + + a++; + if (a < tvs->transverts_tot) tv++; + } + } + } + + /* Ensure all bones are correctly adjusted */ + for (ebo = arm->edbo->first; ebo; ebo = ebo->next) { + if ((ebo->flag & BONE_CONNECTED) && ebo->parent) { + /* If this bone has a parent tip that has been moved */ + if (ebo->parent->flag & BONE_TIPSEL) { + copy_v3_v3(ebo->head, ebo->parent->tail); + } + /* If this bone has a parent tip that has NOT been moved */ + else { + copy_v3_v3(ebo->parent->tail, ebo->head); + } + } + } + if (arm->flag & ARM_MIRROR_EDIT) + transform_armature_mirror_update(obedit); + } + else if (obedit->type == OB_LATTICE) { + Lattice *lt = obedit->data; + + if (lt->editlatt->latt->flag & LT_OUTSIDE) + outside_lattice(lt->editlatt->latt); + } +} + +static void set_mapped_co(void *vuserdata, int index, const float co[3], + const float UNUSED(no[3]), const short UNUSED(no_s[3])) +{ + void **userdata = vuserdata; + BMEditMesh *em = userdata[0]; + TransVert *tv = userdata[1]; + BMVert *eve = BM_vert_at_index(em->bm, index); + + if (BM_elem_index_get(eve) != TM_INDEX_SKIP) { + tv = &tv[BM_elem_index_get(eve)]; + + /* be clever, get the closest vertex to the original, + * behaves most logically when the mirror modifier is used for eg [#33051]*/ + if ((tv->flag & TX_VERT_USE_MAPLOC) == 0) { + /* first time */ + copy_v3_v3(tv->maploc, co); + tv->flag |= TX_VERT_USE_MAPLOC; + } + else { + /* find best location to use */ + if (len_squared_v3v3(eve->co, co) < len_squared_v3v3(eve->co, tv->maploc)) { + copy_v3_v3(tv->maploc, co); + } + } + } +} + +bool ED_transverts_check_obedit(Object *obedit) +{ + return (ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL)); +} + +void ED_transverts_create_from_obedit(TransVertStore *tvs, Object *obedit, const int mode) +{ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + TransVert *tv = NULL; + MetaElem *ml; + BMVert *eve; + EditBone *ebo; + int a; + + tvs->transverts_tot = 0; + + if (obedit->type == OB_MESH) { + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; + BMIter iter; + void *userdata[2] = {em, NULL}; + /*int proptrans = 0; */ /*UNUSED*/ + + /* abuses vertex index all over, set, just set dirty here, + * perhaps this could use its own array instead? - campbell */ + + /* transform now requires awareness for select mode, so we tag the f1 flags in verts */ + tvs->transverts_tot = 0; + if (em->selectmode & SCE_SELECT_VERTEX) { + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + BM_elem_index_set(eve, TM_INDEX_ON); /* set_dirty! */ + tvs->transverts_tot++; + } + else { + BM_elem_index_set(eve, TM_INDEX_OFF); /* set_dirty! */ + } + } + } + else if (em->selectmode & SCE_SELECT_EDGE) { + BMEdge *eed; + + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + BM_elem_index_set(eve, TM_INDEX_OFF); /* set_dirty! */ + } + + BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { + if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && BM_elem_flag_test(eed, BM_ELEM_SELECT)) { + BM_elem_index_set(eed->v1, TM_INDEX_ON); /* set_dirty! */ + BM_elem_index_set(eed->v2, TM_INDEX_ON); /* set_dirty! */ + } + } + + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_index_get(eve) == TM_INDEX_ON) tvs->transverts_tot++; + } + } + else { + BMFace *efa; + + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + BM_elem_index_set(eve, TM_INDEX_OFF); /* set_dirty! */ + } + + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && BM_elem_flag_test(efa, BM_ELEM_SELECT)) { + BMIter liter; + BMLoop *l; + + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + BM_elem_index_set(l->v, TM_INDEX_ON); /* set_dirty! */ + } + } + } + + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_index_get(eve) == TM_INDEX_ON) tvs->transverts_tot++; + } + } + /* for any of the 3 loops above which all dirty the indices */ + bm->elem_index_dirty |= BM_VERT; + + /* and now make transverts */ + if (tvs->transverts_tot) { + tv = tvs->transverts = MEM_callocN(tvs->transverts_tot * sizeof(TransVert), __func__); + + a = 0; + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_index_get(eve)) { + BM_elem_index_set(eve, a); /* set_dirty! */ + copy_v3_v3(tv->oldloc, eve->co); + tv->loc = eve->co; + tv->flag = (BM_elem_index_get(eve) == TM_INDEX_ON) ? SELECT : 0; + tv++; + a++; + } + else { + BM_elem_index_set(eve, TM_INDEX_SKIP); /* set_dirty! */ + } + } + /* set dirty already, above */ + + userdata[1] = tvs->transverts; + } + + if (tvs->transverts && em->derivedCage) { + BM_mesh_elem_table_ensure(bm, BM_VERT); + em->derivedCage->foreachMappedVert(em->derivedCage, set_mapped_co, userdata, DM_FOREACH_NOP); + } + } + else if (obedit->type == OB_ARMATURE) { + bArmature *arm = obedit->data; + int totmalloc = BLI_countlist(arm->edbo); + + totmalloc *= 2; /* probably overkill but bones can have 2 trans verts each */ + + tv = tvs->transverts = MEM_callocN(totmalloc * sizeof(TransVert), __func__); + + for (ebo = arm->edbo->first; ebo; ebo = ebo->next) { + if (ebo->layer & arm->layer) { + short tipsel = (ebo->flag & BONE_TIPSEL); + short rootsel = (ebo->flag & BONE_ROOTSEL); + short rootok = (!(ebo->parent && (ebo->flag & BONE_CONNECTED) && (ebo->parent->flag & BONE_TIPSEL))); + + if ((tipsel && rootsel) || (rootsel)) { + /* Don't add the tip (unless mode & TM_ALL_JOINTS, for getting all joints), + * otherwise we get zero-length bones as tips will snap to the same + * location as heads. + */ + if (rootok) { + copy_v3_v3(tv->oldloc, ebo->head); + tv->loc = ebo->head; + tv->flag = SELECT; + tv++; + tvs->transverts_tot++; + } + + if ((mode & TM_ALL_JOINTS) && (tipsel)) { + copy_v3_v3(tv->oldloc, ebo->tail); + tv->loc = ebo->tail; + tv->flag = SELECT; + tv++; + tvs->transverts_tot++; + } + } + else if (tipsel) { + copy_v3_v3(tv->oldloc, ebo->tail); + tv->loc = ebo->tail; + tv->flag = SELECT; + tv++; + tvs->transverts_tot++; + } + } + } + } + else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { + Curve *cu = obedit->data; + int totmalloc = 0; + ListBase *nurbs = BKE_curve_editNurbs_get(cu); + + for (nu = nurbs->first; nu; nu = nu->next) { + if (nu->type == CU_BEZIER) + totmalloc += 3 * nu->pntsu; + else + totmalloc += nu->pntsu * nu->pntsv; + } + tv = tvs->transverts = MEM_callocN(totmalloc * sizeof(TransVert), __func__); + + nu = nurbs->first; + while (nu) { + if (nu->type == CU_BEZIER) { + a = nu->pntsu; + bezt = nu->bezt; + while (a--) { + if (bezt->hide == 0) { + int skip_handle = 0; + if (bezt->f2 & SELECT) + skip_handle = mode & TM_SKIP_HANDLES; + + if ((bezt->f1 & SELECT) && !skip_handle) { + copy_v3_v3(tv->oldloc, bezt->vec[0]); + tv->loc = bezt->vec[0]; + tv->flag = bezt->f1 & SELECT; + tv++; + tvs->transverts_tot++; + } + if (bezt->f2 & SELECT) { + copy_v3_v3(tv->oldloc, bezt->vec[1]); + tv->loc = bezt->vec[1]; + tv->val = &(bezt->alfa); + tv->oldval = bezt->alfa; + tv->flag = bezt->f2 & SELECT; + tv++; + tvs->transverts_tot++; + } + if ((bezt->f3 & SELECT) && !skip_handle) { + copy_v3_v3(tv->oldloc, bezt->vec[2]); + tv->loc = bezt->vec[2]; + tv->flag = bezt->f3 & SELECT; + tv++; + tvs->transverts_tot++; + } + } + bezt++; + } + } + else { + a = nu->pntsu * nu->pntsv; + bp = nu->bp; + while (a--) { + if (bp->hide == 0) { + if (bp->f1 & SELECT) { + copy_v3_v3(tv->oldloc, bp->vec); + tv->loc = bp->vec; + tv->val = &(bp->alfa); + tv->oldval = bp->alfa; + tv->flag = bp->f1 & SELECT; + tv++; + tvs->transverts_tot++; + } + } + bp++; + } + } + nu = nu->next; + } + } + else if (obedit->type == OB_MBALL) { + MetaBall *mb = obedit->data; + int totmalloc = BLI_countlist(mb->editelems); + + tv = tvs->transverts = MEM_callocN(totmalloc * sizeof(TransVert), __func__); + + ml = mb->editelems->first; + while (ml) { + if (ml->flag & SELECT) { + tv->loc = &ml->x; + copy_v3_v3(tv->oldloc, tv->loc); + tv->val = &(ml->rad); + tv->oldval = ml->rad; + tv->flag = SELECT; + tv++; + tvs->transverts_tot++; + } + ml = ml->next; + } + } + else if (obedit->type == OB_LATTICE) { + Lattice *lt = obedit->data; + + bp = lt->editlatt->latt->def; + + a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; + + tv = tvs->transverts = MEM_callocN(a * sizeof(TransVert), __func__); + + while (a--) { + if (bp->f1 & SELECT) { + if (bp->hide == 0) { + copy_v3_v3(tv->oldloc, bp->vec); + tv->loc = bp->vec; + tv->flag = bp->f1 & SELECT; + tv++; + tvs->transverts_tot++; + } + } + bp++; + } + } + + if (!tvs->transverts_tot && tvs->transverts) { + /* prevent memory leak. happens for curves/latticies due to */ + /* difficult condition of adding points to trans data */ + MEM_freeN(tvs->transverts); + tvs->transverts = NULL; + } +} + +void ED_transverts_free(TransVertStore *tvs) +{ + MEM_SAFE_FREE(tvs->transverts); + tvs->transverts_tot = 0; +} diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index 3e5f879aa3c..0feaf936172 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -114,16 +114,16 @@ void outputNumInput(NumInput *n, char *str) } } -short hasNumInput(NumInput *n) +bool hasNumInput(const NumInput *n) { short i; for (i = 0; i <= n->idx_max; i++) { if (n->ctrl[i]) - return 1; + return true; } - return 0; + return false; } /** @@ -159,7 +159,7 @@ void applyNumInput(NumInput *n, float *vec) } } -char handleNumInput(NumInput *n, const wmEvent *event) +bool handleNumInput(NumInput *n, const wmEvent *event) { float Val = 0; short idx = n->idx, idx_max = n->idx_max; diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 8c299cccbc2..474348e84bc 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -924,7 +924,7 @@ static void uv_select_edgeloop_vertex_loop_flag(UvMapVert *first) static UvMapVert *uv_select_edgeloop_vertex_map_get(UvVertMap *vmap, BMFace *efa, BMLoop *l) { UvMapVert *iterv, *first; - first = EDBM_uv_vert_map_at_index(vmap, BM_elem_index_get(l->v)); + first = BM_uv_vert_map_at_index(vmap, BM_elem_index_get(l->v)); for (iterv = first; iterv; iterv = iterv->next) { if (iterv->separate) @@ -953,7 +953,7 @@ static bool uv_select_edgeloop_edge_tag_faces(BMEditMesh *em, UvMapVert *first1, if (iterv1->f == iterv2->f) { /* if face already tagged, don't do this edge */ - efa = EDBM_face_at_index(em, iterv1->f); + efa = BM_face_at_index(em->bm, iterv1->f); if (BM_elem_flag_test(efa, BM_ELEM_TAG)) return false; @@ -978,7 +978,7 @@ static bool uv_select_edgeloop_edge_tag_faces(BMEditMesh *em, UvMapVert *first1, break; if (iterv1->f == iterv2->f) { - efa = EDBM_face_at_index(em, iterv1->f); + efa = BM_face_at_index(em->bm, iterv1->f); BM_elem_flag_enable(efa, BM_ELEM_TAG); break; } @@ -1005,8 +1005,8 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY); /* setup */ - EDBM_index_arrays_ensure(em, BM_FACE); - vmap = EDBM_uv_vert_map_create(em, 0, limit); + BM_mesh_elem_table_ensure(em->bm, BM_FACE); + vmap = BM_uv_vert_map_create(em->bm, 0, limit); BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE); @@ -1085,7 +1085,7 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH } /* cleanup */ - EDBM_uv_vert_map_free(vmap); + BM_uv_vert_map_free(vmap); return (select) ? 1 : -1; } @@ -1108,8 +1108,8 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY); - EDBM_index_arrays_ensure(em, BM_FACE); /* we can use this too */ - vmap = EDBM_uv_vert_map_create(em, 1, limit); + BM_mesh_elem_table_ensure(em->bm, BM_FACE); /* we can use this too */ + vmap = BM_uv_vert_map_create(em->bm, 1, limit); if (vmap == NULL) return; @@ -1152,12 +1152,12 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo stacksize--; a = stack[stacksize]; - efa = EDBM_face_at_index(em, a); + efa = BM_face_at_index(em->bm, a); BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { /* make_uv_vert_map_EM sets verts tmp.l to the indices */ - vlist = EDBM_uv_vert_map_at_index(vmap, BM_elem_index_get(l->v)); + vlist = BM_uv_vert_map_at_index(vmap, BM_elem_index_get(l->v)); startv = vlist; @@ -1241,7 +1241,7 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo MEM_freeN(stack); MEM_freeN(flag); - EDBM_uv_vert_map_free(vmap); + BM_uv_vert_map_free(vmap); } /* WATCH IT: this returns first selected UV, @@ -2567,7 +2567,7 @@ static void uv_select_flush_from_tag_sticky_loc_internal(Scene *scene, BMEditMes uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset); - vlist_iter = EDBM_uv_vert_map_at_index(vmap, BM_elem_index_get(l->v)); + vlist_iter = BM_uv_vert_map_at_index(vmap, BM_elem_index_get(l->v)); while (vlist_iter) { if (vlist_iter->separate) @@ -2587,7 +2587,7 @@ static void uv_select_flush_from_tag_sticky_loc_internal(Scene *scene, BMEditMes if (efa_index != vlist_iter->f) { BMLoop *l_other; - efa_vlist = EDBM_face_at_index(em, vlist_iter->f); + efa_vlist = BM_face_at_index(em->bm, vlist_iter->f); /* tf_vlist = BM_ELEM_CD_GET_VOID_P(efa_vlist, cd_poly_tex_offset); */ /* UNUSED */ l_other = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex); @@ -2657,8 +2657,8 @@ static void uv_select_flush_from_tag_face(SpaceImage *sima, Scene *scene, Object uvedit_pixel_to_float(sima, limit, 0.05); - EDBM_index_arrays_ensure(em, BM_FACE); - vmap = EDBM_uv_vert_map_create(em, 0, limit); + BM_mesh_elem_table_ensure(em->bm, BM_FACE); + vmap = BM_uv_vert_map_create(em->bm, 0, limit); if (vmap == NULL) { return; } @@ -2673,7 +2673,7 @@ static void uv_select_flush_from_tag_face(SpaceImage *sima, Scene *scene, Object } } } - EDBM_uv_vert_map_free(vmap); + BM_uv_vert_map_free(vmap); } else { /* SI_STICKY_DISABLE or ts->uv_flag & UV_SYNC_SELECTION */ @@ -2748,8 +2748,8 @@ static void uv_select_flush_from_tag_loop(SpaceImage *sima, Scene *scene, Object uvedit_pixel_to_float(sima, limit, 0.05); - EDBM_index_arrays_ensure(em, BM_FACE); - vmap = EDBM_uv_vert_map_create(em, 0, limit); + BM_mesh_elem_table_ensure(em->bm, BM_FACE); + vmap = BM_uv_vert_map_create(em->bm, 0, limit); if (vmap == NULL) { return; } @@ -2764,7 +2764,7 @@ static void uv_select_flush_from_tag_loop(SpaceImage *sima, Scene *scene, Object } } } - EDBM_uv_vert_map_free(vmap); + BM_uv_vert_map_free(vmap); } else { /* SI_STICKY_DISABLE or ts->uv_flag & UV_SYNC_SELECTION */ @@ -3963,8 +3963,8 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op) } /* This code sets editvert->tmp.l to the index. This will be useful later on. */ - EDBM_index_arrays_ensure(em, BM_FACE); - vmap = EDBM_uv_vert_map_create(em, 0, limit); + BM_mesh_elem_table_ensure(bm, BM_FACE); + vmap = BM_uv_vert_map_create(bm, 0, limit); BM_ITER_MESH (editedge, &iter, bm, BM_EDGES_OF_MESH) { /* flags to determine if we uv is separated from first editface match */ @@ -3992,14 +3992,14 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op) v1coincident = 0; separated2 = 0; - efa1 = EDBM_face_at_index(em, mv1->f); + efa1 = BM_face_at_index(bm, mv1->f); mvinit2 = vmap->vert[BM_elem_index_get(editedge->v2)]; for (mv2 = mvinit2; mv2; mv2 = mv2->next) { if (mv2->separate) mv2sep = mv2; - efa2 = EDBM_face_at_index(em, mv2->f); + efa2 = BM_face_at_index(bm, mv2->f); if (efa1 == efa2) { /* if v1 is not coincident no point in comparing */ if (v1coincident) { @@ -4042,7 +4042,7 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op) me->drawflag |= ME_DRAWSEAMS; - EDBM_uv_vert_map_free(vmap); + BM_uv_vert_map_free(vmap); DAG_id_tag_update(&me->id, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, me); diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index f788c6a772c..28e28238ca9 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -600,7 +600,7 @@ static void state_delete(StitchState *state) { if (state) { if (state->element_map) { - EDBM_uv_element_map_free(state->element_map); + BM_uv_element_map_free(state->element_map); } if (state->uvs) { MEM_freeN(state->uvs); @@ -661,9 +661,9 @@ static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState * /* check to see if other vertex of edge belongs to same vertex as */ if (BM_elem_index_get(iter1->l->next->v) == elemindex2) - iter2 = ED_uv_element_get(element_map, iter1->l->f, iter1->l->next); + iter2 = BM_uv_element_get(element_map, iter1->l->f, iter1->l->next); else if (BM_elem_index_get(iter1->l->prev->v) == elemindex2) - iter2 = ED_uv_element_get(element_map, iter1->l->f, iter1->l->prev); + iter2 = BM_uv_element_get(element_map, iter1->l->f, iter1->l->prev); if (iter2) { int index1 = map[iter1 - first_element]; @@ -1017,7 +1017,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) /* copy data from MLoopUVs to the preview display buffers */ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { /* just to test if face was added for processing. uvs of inselected vertices will return NULL */ - UvElement *element = ED_uv_element_get(state->element_map, efa, BM_FACE_FIRST_LOOP(efa)); + UvElement *element = BM_uv_element_get(state->element_map, efa, BM_FACE_FIRST_LOOP(efa)); if (element) { int numoftris = efa->len - 2; @@ -1568,8 +1568,8 @@ static UvEdge *uv_edge_get(BMLoop *l, StitchState *state) { UvEdge tmp_edge; - UvElement *element1 = ED_uv_element_get(state->element_map, l->f, l); - UvElement *element2 = ED_uv_element_get(state->element_map, l->f, l->next); + UvElement *element1 = BM_uv_element_get(state->element_map, l->f, l); + UvElement *element2 = BM_uv_element_get(state->element_map, l->f, l->next); int uv1 = state->map[element1 - state->element_map->buf]; int uv2 = state->map[element2 - state->element_map->buf]; @@ -1613,10 +1613,7 @@ static int stitch_init(bContext *C, wmOperator *op) if (!ar) return 0; - state = MEM_mallocN(sizeof(StitchState), "stitch state"); - - if (!state) - return 0; + state = MEM_callocN(sizeof(StitchState), "stitch state"); op->customdata = state; @@ -1648,13 +1645,12 @@ static int stitch_init(bContext *C, wmOperator *op) } } - state->draw_handle = ED_region_draw_cb_activate(ar->type, stitch_draw, state, REGION_DRAW_POST_VIEW); /* in uv synch selection, all uv's are visible */ if (ts->uv_flag & UV_SYNC_SELECTION) { - state->element_map = EDBM_uv_element_map_create(state->em, FALSE, TRUE); + state->element_map = BM_uv_element_map_create(state->em->bm, false, true); } else { - state->element_map = EDBM_uv_element_map_create(state->em, TRUE, TRUE); + state->element_map = BM_uv_element_map_create(state->em->bm, true, true); } if (!state->element_map) { state_delete(state); @@ -1715,9 +1711,9 @@ static int stitch_init(bContext *C, wmOperator *op) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - UvElement *element = ED_uv_element_get(state->element_map, efa, l); + UvElement *element = BM_uv_element_get(state->element_map, efa, l); int offset1, itmp1 = element - state->element_map->buf; - int offset2, itmp2 = ED_uv_element_get(state->element_map, efa, l->next) - state->element_map->buf; + int offset2, itmp2 = BM_uv_element_get(state->element_map, efa, l->next) - state->element_map->buf; UvEdge *edge; offset1 = map[itmp1]; @@ -1814,7 +1810,7 @@ static int stitch_init(bContext *C, wmOperator *op) UvElement *element; enum StitchModes stored_mode = RNA_enum_get(op->ptr, "stored_mode"); - EDBM_index_arrays_ensure(em, BM_FACE); + BM_mesh_elem_table_ensure(em->bm, BM_FACE); if (stored_mode == STITCH_VERT) { state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs, "uv_stitch_selection_stack"); @@ -1823,8 +1819,8 @@ static int stitch_init(bContext *C, wmOperator *op) { faceIndex = RNA_int_get(&itemptr, "face_index"); elementIndex = RNA_int_get(&itemptr, "element_index"); - efa = EDBM_face_at_index(em, faceIndex); - element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex)); + efa = BM_face_at_index(em->bm, faceIndex); + element = BM_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex)); stitch_select_uv(element, state, 1); } RNA_END; @@ -1838,11 +1834,11 @@ static int stitch_init(bContext *C, wmOperator *op) int uv1, uv2; faceIndex = RNA_int_get(&itemptr, "face_index"); elementIndex = RNA_int_get(&itemptr, "element_index"); - efa = EDBM_face_at_index(em, faceIndex); - element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex)); + efa = BM_face_at_index(em->bm, faceIndex); + element = BM_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex)); uv1 = map[element - state->element_map->buf]; - element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, (elementIndex + 1) % efa->len)); + element = BM_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, (elementIndex + 1) % efa->len)); uv2 = map[element - state->element_map->buf]; if (uv1 < uv2) { @@ -1877,7 +1873,7 @@ static int stitch_init(bContext *C, wmOperator *op) BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - UvElement *element = ED_uv_element_get(state->element_map, efa, l); + UvElement *element = BM_uv_element_get(state->element_map, efa, l); if (element) { stitch_select_uv(element, state, 1); } @@ -1913,7 +1909,7 @@ static int stitch_init(bContext *C, wmOperator *op) } BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - UvElement *element = ED_uv_element_get(state->element_map, efa, BM_FACE_FIRST_LOOP(efa)); + UvElement *element = BM_uv_element_get(state->element_map, efa, BM_FACE_FIRST_LOOP(efa)); if (element) { state->tris_per_island[element->island] += (efa->len > 2) ? efa->len - 2 : 0; @@ -1926,6 +1922,8 @@ static int stitch_init(bContext *C, wmOperator *op) return 0; } + state->draw_handle = ED_region_draw_cb_activate(ar->type, stitch_draw, state, REGION_DRAW_POST_VIEW); + stitch_update_header(state, C); return 1; } @@ -1998,10 +1996,9 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished) } -static int stitch_cancel(bContext *C, wmOperator *op) +static void stitch_cancel(bContext *C, wmOperator *op) { stitch_exit(C, op, 0); - return OPERATOR_CANCELLED; } @@ -2016,7 +2013,8 @@ static int stitch_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } else { - return stitch_cancel(C, op); + stitch_cancel(C, op); + return OPERATOR_CANCELLED; } } @@ -2039,7 +2037,7 @@ static void stitch_select(bContext *C, Scene *scene, const wmEvent *event, Stitc * you can do stuff like deselect the opposite stitchable vertex and the initial still gets deselected */ /* This works due to setting of tmp in find nearest uv vert */ - UvElement *element = ED_uv_element_get(state->element_map, hit.efa, hit.l); + UvElement *element = BM_uv_element_get(state->element_map, hit.efa, hit.l); stitch_select_uv(element, state, FALSE); } @@ -2067,8 +2065,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) /* Cancel */ case ESCKEY: - return stitch_cancel(C, op); - + stitch_cancel(C, op); + return OPERATOR_CANCELLED; case LEFTMOUSE: if (event->shift && (U.flag & USER_LMOUSESELECT)) { @@ -2076,7 +2074,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) stitch_select(C, scene, event, state); if (!stitch_process_data(state, scene, FALSE)) { - return stitch_cancel(C, op); + stitch_cancel(C, op); + return OPERATOR_CANCELLED; } } break; @@ -2089,7 +2088,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_FINISHED; } else { - return stitch_cancel(C, op); + stitch_cancel(C, op); + return OPERATOR_CANCELLED; } } else { @@ -2101,7 +2101,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) if (event->val == KM_PRESS && event->alt) { state->limit_dist += 0.01f; if (!stitch_process_data(state, scene, FALSE)) { - return stitch_cancel(C, op); + stitch_cancel(C, op); + return OPERATOR_CANCELLED; } break; } @@ -2115,7 +2116,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) state->limit_dist -= 0.01f; state->limit_dist = MAX2(0.01f, state->limit_dist); if (!stitch_process_data(state, scene, FALSE)) { - return stitch_cancel(C, op); + stitch_cancel(C, op); + return OPERATOR_CANCELLED; } break; } @@ -2128,7 +2130,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) if (event->val == KM_PRESS) { state->use_limit = !state->use_limit; if (!stitch_process_data(state, scene, FALSE)) { - return stitch_cancel(C, op); + stitch_cancel(C, op); + return OPERATOR_CANCELLED; } break; } @@ -2140,7 +2143,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) state->static_island %= state->element_map->totalIslands; if (!stitch_process_data(state, scene, FALSE)) { - return stitch_cancel(C, op); + stitch_cancel(C, op); + return OPERATOR_CANCELLED; } break; } @@ -2150,7 +2154,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) if (event->val == KM_PRESS) { state->midpoints = !state->midpoints; if (!stitch_process_data(state, scene, FALSE)) { - return stitch_cancel(C, op); + stitch_cancel(C, op); + return OPERATOR_CANCELLED; } } break; @@ -2158,13 +2163,15 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) /* Select geometry*/ case RIGHTMOUSE: if (!event->shift) { - return stitch_cancel(C, op); + stitch_cancel(C, op); + return OPERATOR_CANCELLED; } if (event->val == KM_PRESS && !(U.flag & USER_LMOUSESELECT)) { stitch_select(C, scene, event, state); if (!stitch_process_data(state, scene, FALSE)) { - return stitch_cancel(C, op); + stitch_cancel(C, op); + return OPERATOR_CANCELLED; } break; } @@ -2175,7 +2182,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) if (event->val == KM_PRESS) { state->snap_islands = !state->snap_islands; if (!stitch_process_data(state, scene, FALSE)) { - return stitch_cancel(C, op); + stitch_cancel(C, op); + return OPERATOR_CANCELLED; } break; } @@ -2189,7 +2197,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) stitch_switch_selection_mode(state); if (!stitch_process_data(state, scene, FALSE)) { - return stitch_cancel(C, op); + stitch_cancel(C, op); + return OPERATOR_CANCELLED; } } break; diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 87cc42001d6..d6bd6f466b9 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -421,11 +421,11 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B faceMap = MEM_mallocN(numOfFaces * sizeof(BMFace *), "unwrap_edit_face_map"); BM_mesh_elem_index_ensure(em->bm, BM_VERT); - EDBM_index_arrays_ensure(em, BM_EDGE | BM_FACE); + BM_mesh_elem_table_ensure(em->bm, BM_EDGE | BM_FACE); /* map subsurfed faces to original editFaces */ for (i = 0; i < numOfFaces; i++) - faceMap[i] = EDBM_face_at_index(em, DM_origindex_mface_mpoly(origFaceIndices, origPolyIndices, i)); + faceMap[i] = BM_face_at_index(em->bm, DM_origindex_mface_mpoly(origFaceIndices, origPolyIndices, i)); edgeMap = MEM_mallocN(numOfEdges * sizeof(BMEdge *), "unwrap_edit_edge_map"); @@ -433,7 +433,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B for (i = 0; i < numOfEdges; i++) { /* not all edges correspond to an old edge */ edgeMap[i] = (origEdgeIndices[i] != ORIGINDEX_NONE) ? - EDBM_edge_at_index(em, origEdgeIndices[i]) : NULL; + BM_edge_at_index(em->bm, origEdgeIndices[i]) : NULL; } /* Prepare and feed faces to the solver */ @@ -542,7 +542,7 @@ static bool minimize_stretch_init(bContext *C, wmOperator *op) return true; } -static void minimize_stretch_iteration(bContext *C, wmOperator *op, int interactive) +static void minimize_stretch_iteration(bContext *C, wmOperator *op, bool interactive) { MinStretch *ms = op->customdata; ScrArea *sa = CTX_wm_area(C); @@ -570,7 +570,7 @@ static void minimize_stretch_iteration(bContext *C, wmOperator *op, int interact } } -static void minimize_stretch_exit(bContext *C, wmOperator *op, int cancel) +static void minimize_stretch_exit(bContext *C, wmOperator *op, bool cancel) { MinStretch *ms = op->customdata; ScrArea *sa = CTX_wm_area(C); @@ -604,8 +604,8 @@ static int minimize_stretch_exec(bContext *C, wmOperator *op) iterations = RNA_int_get(op->ptr, "iterations"); for (i = 0; i < iterations; i++) - minimize_stretch_iteration(C, op, 0); - minimize_stretch_exit(C, op, 0); + minimize_stretch_iteration(C, op, false); + minimize_stretch_exit(C, op, false); return OPERATOR_FINISHED; } @@ -617,7 +617,7 @@ static int minimize_stretch_invoke(bContext *C, wmOperator *op, const wmEvent *U if (!minimize_stretch_init(C, op)) return OPERATOR_CANCELLED; - minimize_stretch_iteration(C, op, 1); + minimize_stretch_iteration(C, op, true); ms = op->customdata; WM_event_add_modal_handler(C, op); @@ -633,12 +633,12 @@ static int minimize_stretch_modal(bContext *C, wmOperator *op, const wmEvent *ev switch (event->type) { case ESCKEY: case RIGHTMOUSE: - minimize_stretch_exit(C, op, 1); + minimize_stretch_exit(C, op, true); return OPERATOR_CANCELLED; case RETKEY: case PADENTER: case LEFTMOUSE: - minimize_stretch_exit(C, op, 0); + minimize_stretch_exit(C, op, false); return OPERATOR_FINISHED; case PADPLUSKEY: case WHEELUPMOUSE: @@ -647,7 +647,7 @@ static int minimize_stretch_modal(bContext *C, wmOperator *op, const wmEvent *ev ms->blend += 0.1f; ms->lasttime = 0.0f; RNA_float_set(op->ptr, "blend", ms->blend); - minimize_stretch_iteration(C, op, 1); + minimize_stretch_iteration(C, op, true); } } break; @@ -658,7 +658,7 @@ static int minimize_stretch_modal(bContext *C, wmOperator *op, const wmEvent *ev ms->blend -= 0.1f; ms->lasttime = 0.0f; RNA_float_set(op->ptr, "blend", ms->blend); - minimize_stretch_iteration(C, op, 1); + minimize_stretch_iteration(C, op, true); } } break; @@ -667,25 +667,23 @@ static int minimize_stretch_modal(bContext *C, wmOperator *op, const wmEvent *ev double start = PIL_check_seconds_timer(); do { - minimize_stretch_iteration(C, op, 1); + minimize_stretch_iteration(C, op, true); } while (PIL_check_seconds_timer() - start < 0.01); } break; } if (ms->iterations && ms->i >= ms->iterations) { - minimize_stretch_exit(C, op, 0); + minimize_stretch_exit(C, op, false); return OPERATOR_FINISHED; } return OPERATOR_RUNNING_MODAL; } -static int minimize_stretch_cancel(bContext *C, wmOperator *op) +static void minimize_stretch_cancel(bContext *C, wmOperator *op) { - minimize_stretch_exit(C, op, 1); - - return OPERATOR_CANCELLED; + minimize_stretch_exit(C, op, true); } void UV_OT_minimize_stretch(wmOperatorType *ot) @@ -890,7 +888,7 @@ static void uv_map_transform_center(Scene *scene, View3D *v3d, float *result, } case V3D_CURSOR: /* cursor center */ { - const float *curs = give_cursor(scene, v3d); + const float *curs = ED_view3d_cursor3d_get(scene, v3d); /* shift to objects world */ sub_v3_v3v3(result, curs, ob->obmat[3]); break; diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp index c61f72295d2..81034c1502c 100644 --- a/source/blender/freestyle/intern/application/Controller.cpp +++ b/source/blender/freestyle/intern/application/Controller.cpp @@ -204,7 +204,6 @@ void Controller::setPassZ(float *buf, int width, int height) void Controller::setContext(bContext *C) { PythonInterpreter *py_inter = dynamic_cast<PythonInterpreter*>(_inter); - assert(py_inter != 0); py_inter->setContext(C); } diff --git a/source/blender/freestyle/intern/geometry/Grid.h b/source/blender/freestyle/intern/geometry/Grid.h index a1368f1ea21..070bee047a9 100644 --- a/source/blender/freestyle/intern/geometry/Grid.h +++ b/source/blender/freestyle/intern/geometry/Grid.h @@ -261,7 +261,7 @@ public: /*! inserts a convex polygon occluder * This method is quite coarse insofar as it adds all cells intersecting the polygon bounding box * convex_poly - * The list of 3D points constituing a convex polygon + * The list of 3D points constituting a convex polygon */ void insertOccluder(Polygon3r *convex_poly); diff --git a/source/blender/freestyle/intern/geometry/Noise.cpp b/source/blender/freestyle/intern/geometry/Noise.cpp index b21ded9dd95..8ec56e84f95 100644 --- a/source/blender/freestyle/intern/geometry/Noise.cpp +++ b/source/blender/freestyle/intern/geometry/Noise.cpp @@ -62,10 +62,10 @@ namespace Freestyle { #define SETUP(i, b0, b1, r0, r1) \ { \ (t) = (i) + (N); \ - (b0) = ((int)(t)) & BM; \ - (b1) = ((b0) + 1) & BM; \ - (r0) = (t) - (int)(t); \ + (r0) = modff((t), &(u)); \ (r1) = (r0) - 1.0; \ + (b0) = ((int)(u)) & BM; \ + (b1) = ((b0) + 1) & BM; \ } (void)0 static void normalize2(float v[2]) diff --git a/source/blender/freestyle/intern/python/BPy_Convert.cpp b/source/blender/freestyle/intern/python/BPy_Convert.cpp index 3b1232c51af..56c096a1eae 100644 --- a/source/blender/freestyle/intern/python/BPy_Convert.cpp +++ b/source/blender/freestyle/intern/python/BPy_Convert.cpp @@ -512,93 +512,100 @@ Nature::EdgeNature EdgeNature_from_BPy_Nature(PyObject *obj) return static_cast<Nature::EdgeNature>(PyLong_AsLong(obj)); } -Vec2f *Vec2f_ptr_from_PyObject(PyObject *obj) -{ - Vec2f *v; - if ((v = Vec2f_ptr_from_Vector(obj))) - return v; - if ((v = Vec2f_ptr_from_PyList(obj))) - return v; - if ((v = Vec2f_ptr_from_PyTuple(obj))) - return v; - return NULL; +bool Vec2f_ptr_from_PyObject(PyObject *obj, Vec2f *vec) +{ + if (Vec2f_ptr_from_Vector(obj, vec)) + return true; + if (Vec2f_ptr_from_PyList(obj, vec)) + return true; + if (Vec2f_ptr_from_PyTuple(obj, vec)) + return true; + return false; } -Vec3f *Vec3f_ptr_from_PyObject(PyObject *obj) +bool Vec3f_ptr_from_PyObject(PyObject *obj, Vec3f *vec) { - Vec3f *v; - if ((v = Vec3f_ptr_from_Vector(obj))) - return v; - if ((v = Vec3f_ptr_from_Color(obj))) - return v; - if ((v = Vec3f_ptr_from_PyList(obj))) - return v; - if ((v = Vec3f_ptr_from_PyTuple(obj))) - return v; - return NULL; + if (Vec3f_ptr_from_Vector(obj, vec)) + return true; + if (Vec3f_ptr_from_Color(obj, vec)) + return true; + if (Vec3f_ptr_from_PyList(obj, vec)) + return true; + if (Vec3f_ptr_from_PyTuple(obj, vec)) + return true; + return false; } -Vec3r *Vec3r_ptr_from_PyObject(PyObject *obj) +bool Vec3r_ptr_from_PyObject(PyObject *obj, Vec3r *vec) { - Vec3r *v; - if ((v = Vec3r_ptr_from_Vector(obj))) - return v; - if ((v = Vec3r_ptr_from_Color(obj))) - return v; - if ((v = Vec3r_ptr_from_PyList(obj))) - return v; - if ((v = Vec3r_ptr_from_PyTuple(obj))) - return v; - return NULL; + if (Vec3r_ptr_from_Vector(obj, vec)) + return true; + if (Vec3r_ptr_from_Color(obj, vec)) + return true; + if (Vec3r_ptr_from_PyList(obj, vec)) + return true; + if (Vec3r_ptr_from_PyTuple(obj, vec)) + return true; + return false; } -Vec2f *Vec2f_ptr_from_Vector(PyObject *obj) +bool Vec2f_ptr_from_Vector(PyObject *obj, Vec2f *vec) { if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 2) - return NULL; - float x = ((VectorObject *)obj)->vec[0]; - float y = ((VectorObject *)obj)->vec[1]; - return new Vec2f(x, y); + return false; + if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) + return false; + vec[0] = ((VectorObject *)obj)->vec[0]; + vec[1] = ((VectorObject *)obj)->vec[1]; + return true; } -Vec3f *Vec3f_ptr_from_Vector(PyObject *obj) +bool Vec3f_ptr_from_Vector(PyObject *obj, Vec3f *vec) { if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 3) - return NULL; - float x = ((VectorObject *)obj)->vec[0]; - float y = ((VectorObject *)obj)->vec[1]; - float z = ((VectorObject *)obj)->vec[2]; - return new Vec3f(x, y, z); + return false; + if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) + return false; + vec[0] = ((VectorObject *)obj)->vec[0]; + vec[1] = ((VectorObject *)obj)->vec[1]; + vec[2] = ((VectorObject *)obj)->vec[2]; + return true; } -Vec3r *Vec3r_ptr_from_Vector(PyObject *obj) +bool Vec3r_ptr_from_Vector(PyObject *obj, Vec3r *vec) { if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 3) - return NULL; - real x = ((VectorObject *)obj)->vec[0]; - real y = ((VectorObject *)obj)->vec[1]; - real z = ((VectorObject *)obj)->vec[2]; - return new Vec3r(x, y, z); + return false; + if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) + return false; + vec[0] = ((VectorObject *)obj)->vec[0]; + vec[1] = ((VectorObject *)obj)->vec[1]; + vec[2] = ((VectorObject *)obj)->vec[2]; + return true; } -Vec3f *Vec3f_ptr_from_Color(PyObject *obj) +bool Vec3f_ptr_from_Color(PyObject *obj, Vec3f *vec) { if (!ColorObject_Check(obj)) - return NULL; - float r = ((ColorObject *)obj)->col[0]; - float g = ((ColorObject *)obj)->col[1]; - float b = ((ColorObject *)obj)->col[2]; - return new Vec3f(r, g, b); + return false; + if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) + return false; + vec[0] = ((ColorObject *)obj)->col[0]; + vec[1] = ((ColorObject *)obj)->col[1]; + vec[2] = ((ColorObject *)obj)->col[2]; + return true; } -Vec3r *Vec3r_ptr_from_Color(PyObject *obj) +bool Vec3r_ptr_from_Color(PyObject *obj, Vec3r *vec) { if (!ColorObject_Check(obj)) - return NULL; - real r = ((ColorObject *)obj)->col[0]; - real g = ((ColorObject *)obj)->col[1]; - real b = ((ColorObject *)obj)->col[2]; - return new Vec3r(r, g, b); + return false; + if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) + return false; + vec[0] = ((ColorObject *)obj)->col[0]; + vec[1] = ((ColorObject *)obj)->col[1]; + vec[2] = ((ColorObject *)obj)->col[2]; + return true; } static int float_array_from_PyList(PyObject *obj, float *v, int n) @@ -613,37 +620,45 @@ static int float_array_from_PyList(PyObject *obj, float *v, int n) return 1; } -Vec2f *Vec2f_ptr_from_PyList(PyObject *obj) +bool Vec2f_ptr_from_PyList(PyObject *obj, Vec2f *vec) { float v[2]; if (!PyList_Check(obj) || PyList_Size(obj) != 2) - return NULL; + return false; if (!float_array_from_PyList(obj, v, 2)) - return NULL; - return new Vec2f(v[0], v[1]); + return false; + vec[0] = v[0]; + vec[1] = v[1]; + return true; } -Vec3f *Vec3f_ptr_from_PyList(PyObject *obj) +bool Vec3f_ptr_from_PyList(PyObject *obj, Vec3f *vec) { float v[3]; if (!PyList_Check(obj) || PyList_Size(obj) != 3) - return NULL; + return false; if (!float_array_from_PyList(obj, v, 3)) - return NULL; - return new Vec3f(v[0], v[1], v[2]); + return false; + vec[0] = v[0]; + vec[1] = v[1]; + vec[2] = v[2]; + return true; } -Vec3r *Vec3r_ptr_from_PyList(PyObject *obj) +bool Vec3r_ptr_from_PyList(PyObject *obj, Vec3r *vec) { float v[3]; if (!PyList_Check(obj) || PyList_Size(obj) != 3) - return NULL; + return false; if (!float_array_from_PyList(obj, v, 3)) - return NULL; - return new Vec3r(v[0], v[1], v[2]); + return false; + vec[0] = v[0]; + vec[1] = v[1]; + vec[2] = v[2]; + return true; } static int float_array_from_PyTuple(PyObject *obj, float *v, int n) @@ -658,37 +673,45 @@ static int float_array_from_PyTuple(PyObject *obj, float *v, int n) return 1; } -Vec2f *Vec2f_ptr_from_PyTuple(PyObject *obj) +bool Vec2f_ptr_from_PyTuple(PyObject *obj, Vec2f *vec) { float v[2]; if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 2) - return NULL; + return false; if (!float_array_from_PyTuple(obj, v, 2)) - return NULL; - return new Vec2f(v[0], v[1]); + return false; + vec[0] = v[0]; + vec[1] = v[1]; + return true; } -Vec3f *Vec3f_ptr_from_PyTuple(PyObject *obj) +bool Vec3f_ptr_from_PyTuple(PyObject *obj, Vec3f *vec) { float v[3]; if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 3) - return NULL; + return false; if (!float_array_from_PyTuple(obj, v, 3)) - return NULL; - return new Vec3f(v[0], v[1], v[2]); + return false; + vec[0] = v[0]; + vec[1] = v[1]; + vec[2] = v[2]; + return true; } -Vec3r *Vec3r_ptr_from_PyTuple(PyObject *obj) +bool Vec3r_ptr_from_PyTuple(PyObject *obj, Vec3r *vec) { float v[3]; if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 3) - return NULL; + return false; if (!float_array_from_PyTuple(obj, v, 3)) - return NULL; - return new Vec3r(v[0], v[1], v[2]); + return false; + vec[0] = v[0]; + vec[1] = v[1]; + vec[2] = v[2]; + return true; } // helper for argument parsing @@ -696,10 +719,19 @@ Vec3r *Vec3r_ptr_from_PyTuple(PyObject *obj) int float_array_from_PyObject(PyObject *obj, float *v, int n) { if (VectorObject_Check(obj) && ((VectorObject *)obj)->size == n) { + if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) + return 0; for (int i = 0; i < n; i++) v[i] = ((VectorObject *)obj)->vec[i]; return 1; } + else if (ColorObject_Check(obj) && n == 3) { + if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) + return 0; + for (int i = 0; i < n; i++) + v[i] = ((ColorObject *)obj)->col[i]; + return 1; + } else if (PyList_Check(obj) && PyList_Size(obj) == n) { return float_array_from_PyList(obj, v, n); } diff --git a/source/blender/freestyle/intern/python/BPy_Convert.h b/source/blender/freestyle/intern/python/BPy_Convert.h index 1df4901757b..a8bc7eaa306 100644 --- a/source/blender/freestyle/intern/python/BPy_Convert.h +++ b/source/blender/freestyle/intern/python/BPy_Convert.h @@ -150,20 +150,20 @@ bool bool_from_PyBool(PyObject *b); IntegrationType IntegrationType_from_BPy_IntegrationType(PyObject *obj); Stroke::MediumType MediumType_from_BPy_MediumType(PyObject *obj); Nature::EdgeNature EdgeNature_from_BPy_Nature(PyObject *obj); -Vec2f * Vec2f_ptr_from_PyObject(PyObject *obj); -Vec3f * Vec3f_ptr_from_PyObject(PyObject *obj); -Vec3r * Vec3r_ptr_from_PyObject(PyObject *obj); -Vec2f * Vec2f_ptr_from_Vector(PyObject *obj); -Vec3f * Vec3f_ptr_from_Vector(PyObject *obj); -Vec3r * Vec3r_ptr_from_Vector(PyObject *obj); -Vec3f * Vec3f_ptr_from_Color(PyObject *obj); -Vec3r * Vec3r_ptr_from_Color(PyObject *obj); -Vec2f * Vec2f_ptr_from_PyList(PyObject *obj); -Vec3f * Vec3f_ptr_from_PyList(PyObject *obj); -Vec3r * Vec3r_ptr_from_PyList(PyObject *obj); -Vec2f * Vec2f_ptr_from_PyTuple(PyObject *obj); -Vec3f * Vec3f_ptr_from_PyTuple(PyObject *obj); -Vec3r * Vec3r_ptr_from_PyTuple(PyObject *obj); +bool Vec2f_ptr_from_PyObject(PyObject *obj, Vec2f *vec); +bool Vec3f_ptr_from_PyObject(PyObject *obj, Vec3f *vec); +bool Vec3r_ptr_from_PyObject(PyObject *obj, Vec3r *vec); +bool Vec2f_ptr_from_Vector(PyObject *obj, Vec2f *vec); +bool Vec3f_ptr_from_Vector(PyObject *obj, Vec3f *vec); +bool Vec3r_ptr_from_Vector(PyObject *obj, Vec3r *vec); +bool Vec3f_ptr_from_Color(PyObject *obj, Vec3f *vec); +bool Vec3r_ptr_from_Color(PyObject *obj, Vec3r *vec); +bool Vec2f_ptr_from_PyList(PyObject *obj, Vec2f *vec); +bool Vec3f_ptr_from_PyList(PyObject *obj, Vec3f *vec); +bool Vec3r_ptr_from_PyList(PyObject *obj, Vec3r *vec); +bool Vec2f_ptr_from_PyTuple(PyObject *obj, Vec2f *vec); +bool Vec3f_ptr_from_PyTuple(PyObject *obj, Vec3f *vec); +bool Vec3r_ptr_from_PyTuple(PyObject *obj, Vec3r *vec); int float_array_from_PyObject(PyObject *obj, float *v, int n); diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp index 680f399cc77..fb678d7ea66 100644 --- a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp +++ b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp @@ -101,8 +101,8 @@ static int ramp_blend_type(const char *type) if (!strcmp(type, "SATURATION")) return MA_RAMP_SAT; if (!strcmp(type, "VALUE")) return MA_RAMP_VAL; if (!strcmp(type, "COLOR")) return MA_RAMP_COLOR; - if (!strcmp(type, "SOFT LIGHT")) return MA_RAMP_SOFT; - if (!strcmp(type, "LINEAR LIGHT")) return MA_RAMP_LINEAR; + if (!strcmp(type, "SOFT_LIGHT")) return MA_RAMP_SOFT; + if (!strcmp(type, "LINEAR_LIGHT")) return MA_RAMP_LINEAR; return -1; } @@ -129,7 +129,6 @@ static PyObject *Freestyle_blendRamp(PyObject *self, PyObject *args) PyObject *obj1, *obj2; char *s; int type; - Vec3f *v1 = NULL, *v2 = NULL; float a[3], fac, b[3]; if (!PyArg_ParseTuple(args, "sOfO", &s, &obj1, &fac, &obj2)) @@ -137,32 +136,20 @@ static PyObject *Freestyle_blendRamp(PyObject *self, PyObject *args) type = ramp_blend_type(s); if (type < 0) { PyErr_SetString(PyExc_TypeError, "argument 1 is an unknown ramp blend type"); - goto error; + return NULL; } - v1 = Vec3f_ptr_from_PyObject(obj1); - if (!v1) { + if (!float_array_from_PyObject(obj1, a, 3)) { PyErr_SetString(PyExc_TypeError, "argument 2 must be a 3D vector (either a tuple/list of 3 elements or Vector)"); - goto error; + return NULL; } - v2 = Vec3f_ptr_from_PyObject(obj2); - if (!v2) { + if (!float_array_from_PyObject(obj2, b, 3)) { PyErr_SetString(PyExc_TypeError, "argument 4 must be a 3D vector (either a tuple/list of 3 elements or Vector)"); - goto error; + return NULL; } - a[0] = v1->x(); b[0] = v2->x(); - a[1] = v1->y(); b[1] = v2->y(); - a[2] = v1->z(); b[2] = v2->z(); ramp_blend(type, a, fac, b); - delete v1; - delete v2; return Vector_CreatePyObject(a, 3, Py_NEW, NULL); - -error: - if (v1) delete v1; - if (v2) delete v2; - return NULL; } #include "BKE_texture.h" /* do_colorband() */ diff --git a/source/blender/freestyle/intern/python/BPy_FrsNoise.cpp b/source/blender/freestyle/intern/python/BPy_FrsNoise.cpp index abdcbaff6e1..2575b16b27a 100644 --- a/source/blender/freestyle/intern/python/BPy_FrsNoise.cpp +++ b/source/blender/freestyle/intern/python/BPy_FrsNoise.cpp @@ -132,16 +132,15 @@ static PyObject *FrsNoise_turbulence2(BPy_FrsNoise *self, PyObject *args, PyObje PyObject *obj1; float f2, f3; unsigned int i = 4; + Vec2f vec; if (!PyArg_ParseTupleAndKeywords(args, kwds, "Off|I", (char **)kwlist, &obj1, &f2, &f3, &i)) return NULL; - Vec2f *v = Vec2f_ptr_from_PyObject(obj1); - if (!v) { + if (!Vec2f_ptr_from_PyObject(obj1, &vec)) { PyErr_SetString(PyExc_TypeError, "argument 1 must be a 2D vector (either a list of 2 elements or Vector)"); return NULL; } - float t = self->n->turbulence2(*v, f2, f3, i); - delete v; + float t = self->n->turbulence2(vec, f2, f3, i); return PyFloat_FromDouble(t); } @@ -167,16 +166,15 @@ static PyObject *FrsNoise_turbulence3(BPy_FrsNoise *self, PyObject *args, PyObje PyObject *obj1; float f2, f3; unsigned int i = 4; + Vec3f vec; if (!PyArg_ParseTupleAndKeywords(args, kwds, "Off|I", (char **)kwlist, &obj1, &f2, &f3, &i)) return NULL; - Vec3f *v = Vec3f_ptr_from_PyObject(obj1); - if (!v) { + if (!Vec3f_ptr_from_PyObject(obj1, &vec)) { PyErr_SetString(PyExc_TypeError, "argument 1 must be a 3D vector (either a list of 3 elements or Vector)"); return NULL; } - float t = self->n->turbulence3(*v, f2, f3, i); - delete v; + float t = self->n->turbulence3(vec, f2, f3, i); return PyFloat_FromDouble(t); } @@ -214,16 +212,15 @@ static PyObject *FrsNoise_smoothNoise2(BPy_FrsNoise *self, PyObject *args, PyObj { static const char *kwlist[] = {"v", NULL}; PyObject *obj; + Vec2f vec; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", (char **)kwlist, &obj)) return NULL; - Vec2f *v = Vec2f_ptr_from_PyObject(obj); - if (!v) { + if (!Vec2f_ptr_from_PyObject(obj, &vec)) { PyErr_SetString(PyExc_TypeError, "argument 1 must be a 2D vector (either a list of 2 elements or Vector)"); return NULL; } - float t = self->n->smoothNoise2(*v); - delete v; + float t = self->n->smoothNoise2(vec); return PyFloat_FromDouble(t); } @@ -241,16 +238,15 @@ static PyObject *FrsNoise_smoothNoise3(BPy_FrsNoise *self, PyObject *args, PyObj { static const char *kwlist[] = {"v", NULL}; PyObject *obj; + Vec3f vec; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", (char **)kwlist, &obj)) return NULL; - Vec3f *v = Vec3f_ptr_from_PyObject(obj); - if (!v) { + if (!Vec3f_ptr_from_PyObject(obj, &vec)) { PyErr_SetString(PyExc_TypeError, "argument 1 must be a 3D vector (either a list of 3 elements or Vector)"); return NULL; } - float t = self->n->smoothNoise3(*v); - delete v; + float t = self->n->smoothNoise3(vec); return PyFloat_FromDouble(t); } diff --git a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp index e17f16a2fa7..b08fcfa8dba 100644 --- a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp +++ b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp @@ -311,16 +311,15 @@ static PyObject * StrokeAttribute_set_attribute_vec2(BPy_StrokeAttribute *self, static const char *kwlist[] = {"name", "value", NULL}; char *s; PyObject *obj = 0; + Vec2f vec; if (!PyArg_ParseTupleAndKeywords(args, kwds, "sO", (char **)kwlist, &s, &obj)) return NULL; - Vec2f *v = Vec2f_ptr_from_PyObject(obj); - if (!v) { + if (!Vec2f_ptr_from_PyObject(obj, &vec)) { PyErr_SetString(PyExc_TypeError, "argument 2 must be a 2D vector (either a list of 2 elements or Vector)"); return NULL; } - self->sa->setAttributeVec2f(s, *v); - delete v; + self->sa->setAttributeVec2f(s, vec); Py_RETURN_NONE; } @@ -341,16 +340,15 @@ static PyObject * StrokeAttribute_set_attribute_vec3(BPy_StrokeAttribute *self, static const char *kwlist[] = {"name", "value", NULL}; char *s; PyObject *obj = 0; + Vec3f vec; if (!PyArg_ParseTupleAndKeywords(args, kwds, "sO", (char **)kwlist, &s, &obj)) return NULL; - Vec3f *v = Vec3f_ptr_from_PyObject(obj); - if (!v) { + if (!Vec3f_ptr_from_PyObject(obj, &vec)) { PyErr_SetString(PyExc_TypeError, "argument 2 must be a 3D vector (either a list of 3 elements or Vector)"); return NULL; } - self->sa->setAttributeVec3f(s, *v); - delete v; + self->sa->setAttributeVec3f(s, vec); Py_RETURN_NONE; } diff --git a/source/blender/freestyle/intern/python/Director.cpp b/source/blender/freestyle/intern/python/Director.cpp index cd6f9da3e05..011609bb343 100644 --- a/source/blender/freestyle/intern/python/Director.cpp +++ b/source/blender/freestyle/intern/python/Director.cpp @@ -251,14 +251,16 @@ int Director_BPy_UnaryFunction0D___call__(void *uf0D, PyObject *obj, Interface0D ((UnaryFunction0D<unsigned> *)uf0D)->result = PyLong_AsLong(result); } else if (BPy_UnaryFunction0DVec2f_Check(obj)) { - Vec2f *v = Vec2f_ptr_from_Vector(result); - ((UnaryFunction0D<Vec2f> *)uf0D)->result = *v; - delete v; + Vec2f vec; + if (!Vec2f_ptr_from_Vector(result, &vec)) + return -1; + ((UnaryFunction0D<Vec2f> *)uf0D)->result = vec; } else if (BPy_UnaryFunction0DVec3f_Check(obj)) { - Vec3f *v = Vec3f_ptr_from_Vector(result); - ((UnaryFunction0D<Vec3f> *)uf0D)->result = *v; - delete v; + Vec3f vec; + if (!Vec3f_ptr_from_Vector(result, &vec)) + return -1; + ((UnaryFunction0D<Vec3f> *)uf0D)->result = vec; } else if (BPy_UnaryFunction0DVectorViewShape_Check(obj)) { vector<ViewShape*> vec; @@ -301,14 +303,16 @@ int Director_BPy_UnaryFunction1D___call__(void *uf1D, PyObject *obj, Interface1D ((UnaryFunction1D<unsigned> *)uf1D)->result = PyLong_AsLong(result); } else if (BPy_UnaryFunction1DVec2f_Check(obj)) { - Vec2f *v = Vec2f_ptr_from_Vector(result); - ((UnaryFunction1D<Vec2f> *)uf1D)->result = *v; - delete v; + Vec2f vec; + if (!Vec2f_ptr_from_Vector(result, &vec)) + return -1; + ((UnaryFunction1D<Vec2f> *)uf1D)->result = vec; } else if (BPy_UnaryFunction1DVec3f_Check(obj)) { - Vec3f *v = Vec3f_ptr_from_Vector(result); - ((UnaryFunction1D<Vec3f> *)uf1D)->result = *v; - delete v; + Vec3f vec; + if (!Vec3f_ptr_from_Vector(result, &vec)) + return -1; + ((UnaryFunction1D<Vec3f> *)uf1D)->result = vec; } else if (BPy_UnaryFunction1DVectorViewShape_Check(obj)) { vector<ViewShape*> vec; diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp index 3205a3a3d7e..d2dd1657770 100644 --- a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp +++ b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp @@ -107,17 +107,15 @@ static PyObject *SVertex_add_normal(BPy_SVertex *self, PyObject *args, PyObject { static const char *kwlist[] = {"normal", NULL}; PyObject *py_normal; + Vec3r n; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", (char **)kwlist, &py_normal)) return NULL; - Vec3r *n = Vec3r_ptr_from_PyObject(py_normal); - if (!n) { + if (!Vec3r_ptr_from_PyObject(py_normal, &n)) { PyErr_SetString(PyExc_TypeError, "argument 1 must be a 3D vector (either a list of 3 elements or Vector)"); return NULL; } - self->sv->AddNormal(*n); - delete n; - + self->sv->AddNormal(n); Py_RETURN_NONE; } diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp index 50d54df2ead..9bbb0405e49 100644 --- a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp @@ -167,7 +167,7 @@ static PyObject *FrsCurve_is_empty_get(BPy_FrsCurve *self, void *UNUSED(closure) } PyDoc_STRVAR(FrsCurve_segments_size_doc, -"The number of segments in the polyline constituing the Curve.\n" +"The number of segments in the polyline constituting the Curve.\n" "\n" ":type: int"); diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp index 3e4e7e3aef3..80765e794fb 100644 --- a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp @@ -283,7 +283,7 @@ static PyObject *Stroke_stroke_vertices_end(BPy_Stroke *self) PyDoc_STRVAR(Stroke_stroke_vertices_size_doc, ".. method:: stroke_vertices_size()\n" "\n" -" Returns the number of StrokeVertex constituing the Stroke.\n" +" Returns the number of StrokeVertex constituting the Stroke.\n" "\n" " :return: The number of stroke vertices.\n" " :rtype: int"); diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp index 510875ebb2f..292729782ec 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp @@ -115,6 +115,10 @@ PyDoc_STRVAR(AdjacencyIterator_object_doc, static PyObject *AdjacencyIterator_object_get(BPy_AdjacencyIterator *self, void *UNUSED(closure)) { + if (self->a_it->isEnd()) { + PyErr_SetString(PyExc_RuntimeError, "iteration has stopped"); + return NULL; + } ViewEdge *ve = self->a_it->operator*(); if (ve) return BPy_ViewEdge_from_ViewEdge(*ve); @@ -129,6 +133,10 @@ PyDoc_STRVAR(AdjacencyIterator_is_incoming_doc, static PyObject *AdjacencyIterator_is_incoming_get(BPy_AdjacencyIterator *self, void *UNUSED(closure)) { + if (self->a_it->isEnd()) { + PyErr_SetString(PyExc_RuntimeError, "iteration has stopped"); + return NULL; + } return PyBool_from_bool(self->a_it->isIncoming()); } diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp index 2b8b4eec4dd..99ac72db028 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp @@ -104,7 +104,7 @@ PyDoc_STRVAR(ChainPredicateIterator_doc, static int check_begin(PyObject *obj, void *v) { - if (obj != 0 && obj != Py_None && !BPy_ViewEdge_Check(obj)) + if (obj != NULL && obj != Py_None && !BPy_ViewEdge_Check(obj)) return 0; *((PyObject **)v) = obj; return 1; diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp index b723631f365..1a082ac93bb 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp @@ -74,7 +74,7 @@ PyDoc_STRVAR(ChainSilhouetteIterator_doc, static int check_begin(PyObject *obj, void *v) { - if (obj != 0 && obj != Py_None && !BPy_ViewEdge_Check(obj)) + if (obj != NULL && obj != Py_None && !BPy_ViewEdge_Check(obj)) return 0; *((PyObject **)v) = obj; return 1; diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp index 3e2f0102dc3..1dadfbced03 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp @@ -75,7 +75,7 @@ PyDoc_STRVAR(ChainingIterator_doc, static int check_begin(PyObject *obj, void *v) { - if (obj != 0 && obj != Py_None && !BPy_ViewEdge_Check(obj)) + if (obj != NULL && obj != Py_None && !BPy_ViewEdge_Check(obj)) return 0; *((PyObject **)v) = obj; return 1; @@ -175,6 +175,10 @@ PyDoc_STRVAR(ChainingIterator_object_doc, static PyObject *ChainingIterator_object_get(BPy_ChainingIterator *self, void *UNUSED(closure)) { + if (self->c_it->isEnd()) { + PyErr_SetString(PyExc_RuntimeError, "iteration has stopped"); + return NULL; + } ViewEdge *ve = self->c_it->operator*(); if (ve) return BPy_ViewEdge_from_ViewEdge(*ve); diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp index 3e45ef17c1b..0329aa99acc 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp @@ -97,6 +97,10 @@ PyDoc_STRVAR(CurvePointIterator_object_doc, static PyObject *CurvePointIterator_object_get(BPy_CurvePointIterator *self, void *UNUSED(closure)) { + if (self->cp_it->isEnd()) { + PyErr_SetString(PyExc_RuntimeError, "iteration has stopped"); + return NULL; + } return BPy_CurvePoint_from_CurvePoint(self->cp_it->operator*()); } diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp index 3a537eb672a..3a246263efa 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp @@ -123,6 +123,10 @@ PyDoc_STRVAR(Interface0DIterator_object_doc, static PyObject *Interface0DIterator_object_get(BPy_Interface0DIterator *self, void *UNUSED(closure)) { + if (self->if0D_it->isEnd()) { + PyErr_SetString(PyExc_RuntimeError, "iteration has stopped"); + return NULL; + } return Any_BPy_Interface0D_from_Interface0D(self->if0D_it->operator*()); } diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp index d493b6c158b..ccf52c64757 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp @@ -115,6 +115,10 @@ PyDoc_STRVAR(SVertexIterator_object_doc, static PyObject *SVertexIterator_object_get(BPy_SVertexIterator *self, void *UNUSED(closure)) { + if (self->sv_it->isEnd()) { + PyErr_SetString(PyExc_RuntimeError, "iteration has stopped"); + return NULL; + } SVertex *sv = self->sv_it->operator->(); if (sv) return BPy_SVertex_from_SVertex(*sv); diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp index 3174980b7d9..8287e280186 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp @@ -109,8 +109,10 @@ PyDoc_STRVAR(StrokeVertexIterator_object_doc, static PyObject *StrokeVertexIterator_object_get(BPy_StrokeVertexIterator *self, void *UNUSED(closure)) { - if (!self->reversed && self->sv_it->isEnd()) - Py_RETURN_NONE; + if (!self->reversed && self->sv_it->isEnd()) { + PyErr_SetString(PyExc_RuntimeError, "iteration has stopped"); + return NULL; + } StrokeVertex *sv = self->sv_it->operator->(); if (sv) return BPy_StrokeVertex_from_StrokeVertex(*sv); diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp index f30621f01e3..4a45be8caa5 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp @@ -65,7 +65,7 @@ PyDoc_STRVAR(ViewEdgeIterator_doc, static int check_begin(PyObject *obj, void *v) { - if (obj != 0 && obj != Py_None && !BPy_ViewEdge_Check(obj)) + if (obj != NULL && obj != Py_None && !BPy_ViewEdge_Check(obj)) return 0; *((PyObject **)v) = obj; return 1; @@ -122,6 +122,10 @@ PyDoc_STRVAR(ViewEdgeIterator_object_doc, static PyObject *ViewEdgeIterator_object_get(BPy_ViewEdgeIterator *self, void *UNUSED(closure)) { + if (!self->ve_it->isEnd()) { + PyErr_SetString(PyExc_RuntimeError, "iteration has stopped"); + return NULL; + } ViewEdge *ve = self->ve_it->operator*(); if (ve) return BPy_ViewEdge_from_ViewEdge(*ve); @@ -138,7 +142,8 @@ static PyObject *ViewEdgeIterator_current_edge_get(BPy_ViewEdgeIterator *self, v ViewEdge *ve = self->ve_it->getCurrentEdge(); if (ve) return BPy_ViewEdge_from_ViewEdge(*ve); - Py_RETURN_NONE;} + Py_RETURN_NONE; +} static int ViewEdgeIterator_current_edge_set(BPy_ViewEdgeIterator *self, PyObject *value, void *UNUSED(closure)) { diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp index f2b0e604c22..12ca3d6cc4a 100644 --- a/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp +++ b/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp @@ -103,6 +103,10 @@ PyDoc_STRVAR(orientedViewEdgeIterator_object_doc, static PyObject *orientedViewEdgeIterator_object_get(BPy_orientedViewEdgeIterator *self, void *UNUSED(closure)) { + if (self->ove_it->isEnd()) { + PyErr_SetString(PyExc_RuntimeError, "iteration has stopped"); + return NULL; + } return BPy_directedViewEdge_from_directedViewEdge(self->ove_it->operator*()); } diff --git a/source/blender/freestyle/intern/stroke/Curve.h b/source/blender/freestyle/intern/stroke/Curve.h index 68da744d7b3..7e3b6732bff 100644 --- a/source/blender/freestyle/intern/stroke/Curve.h +++ b/source/blender/freestyle/intern/stroke/Curve.h @@ -491,7 +491,7 @@ public: return _Id; } - /*! Returns the number of segments in the polyline constituing the Curve. */ + /*! Returns the number of segments in the polyline constituting the Curve. */ inline unsigned int nSegments() const { return _nSegments; diff --git a/source/blender/freestyle/intern/stroke/Stroke.h b/source/blender/freestyle/intern/stroke/Stroke.h index e7a75728985..d116edc6ace 100644 --- a/source/blender/freestyle/intern/stroke/Stroke.h +++ b/source/blender/freestyle/intern/stroke/Stroke.h @@ -774,7 +774,7 @@ public: const_vertex_iterator vertices_end() const; vertex_iterator vertices_end(); - /*! Returns a StrokeVertexIterator pointing on the first StrokeVertex of the Stroke. One can specifly a sampling + /*! Returns a StrokeVertexIterator pointing on the first StrokeVertex of the Stroke. One can specify a sampling * value to resample the Stroke on the fly if needed. * \param t * The resampling value with which we want our Stroke to be resampled. @@ -785,7 +785,7 @@ public: /*! Returns a StrokeVertexIterator pointing after the last StrokeVertex of the Stroke. */ StrokeInternal::StrokeVertexIterator strokeVerticesEnd(); - /*! Returns the number of StrokeVertex constituing the Stroke. */ + /*! Returns the number of StrokeVertex constituting the Stroke. */ inline unsigned int strokeVerticesSize() const { return _Vertices.size(); diff --git a/source/blender/freestyle/intern/system/Id.h b/source/blender/freestyle/intern/system/Id.h index 9cd45646f1c..8b028cdb3da 100644 --- a/source/blender/freestyle/intern/system/Id.h +++ b/source/blender/freestyle/intern/system/Id.h @@ -92,13 +92,13 @@ public: return _second; } - /*! Sets the first number constituing the Id */ + /*! Sets the first number constituting the Id */ void setFirst(id_type first) { _first = first; } - /*! Sets the second number constituing the Id */ + /*! Sets the second number constituting the Id */ void setSecond(id_type second) { _second = second; diff --git a/source/blender/freestyle/intern/system/TimeUtils.h b/source/blender/freestyle/intern/system/TimeUtils.h index bbf4c5a1edb..6fe8b0e7431 100644 --- a/source/blender/freestyle/intern/system/TimeUtils.h +++ b/source/blender/freestyle/intern/system/TimeUtils.h @@ -23,7 +23,7 @@ /** \file blender/freestyle/intern/system/TimeUtils.h * \ingroup freestyle - * \brief Class to measure ellapsed time + * \brief Class to measure elapsed time * \author Stephane Grabli * \date 10/04/2002 */ diff --git a/source/blender/freestyle/intern/view_map/SteerableViewMap.h b/source/blender/freestyle/intern/view_map/SteerableViewMap.h index 581155fa6e8..d6af7384fb8 100644 --- a/source/blender/freestyle/intern/view_map/SteerableViewMap.h +++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.h @@ -95,7 +95,7 @@ public: /*! Builds _nbOrientations+1 pyramids of images from the _nbOrientations+1 base images of the steerable viewmap. * \param steerableBases - * The _nbOrientations+1 images constituing the basis for the steerable pyramid. + * The _nbOrientations+1 images constituting the basis for the steerable pyramid. * \param copy * If false, the data is not duplicated, and Canvas deals with the memory management of these * _nbOrientations+1 images. If true, data is copied, and it's up to the caller to delete the images. diff --git a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp index 91d077278fb..b5d73640c11 100644 --- a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp +++ b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp @@ -39,7 +39,7 @@ namespace Freestyle { void ViewEdgeXBuilder::Init(ViewShape *oVShape) { - if (0 == oVShape) + if (NULL == oVShape) return; // for design conveniance, we store the current SShape. @@ -527,7 +527,7 @@ FEdge *ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& bool ViewEdgeXBuilder::stopSmoothViewEdge(WXFaceLayer *iFaceLayer) { - if (0 == iFaceLayer) + if (NULL == iFaceLayer) return true; if (iFaceLayer->userdata == 0) return false; @@ -698,7 +698,7 @@ FEdge *ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe) bool ViewEdgeXBuilder::stopSharpViewEdge(WXEdge *iEdge) { - if (0 == iEdge) + if (NULL == iEdge) return true; if (iEdge->userdata == 0) return false; diff --git a/source/blender/freestyle/intern/view_map/ViewMap.h b/source/blender/freestyle/intern/view_map/ViewMap.h index 0ab089b7d7a..2c9672be53b 100644 --- a/source/blender/freestyle/intern/view_map/ViewMap.h +++ b/source/blender/freestyle/intern/view_map/ViewMap.h @@ -1352,12 +1352,12 @@ public: vertex_iterator vertices_end(); // Iterator access (Interface1D) - /*! Returns an Interface0DIterator to iterate over the SVertex constituing the embedding of this ViewEdge. + /*! Returns an Interface0DIterator to iterate over the SVertex constituting the embedding of this ViewEdge. * The returned Interface0DIterator points to the first SVertex of the ViewEdge. */ virtual Interface0DIterator verticesBegin(); - /*! Returns an Interface0DIterator to iterate over the SVertex constituing the embedding of this ViewEdge. + /*! Returns an Interface0DIterator to iterate over the SVertex constituting the embedding of this ViewEdge. * The returned Interface0DIterator points after the last SVertex of the ViewEdge. */ virtual Interface0DIterator verticesEnd(); diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index d7919125fee..8e0d0e55709 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -65,7 +65,7 @@ static char *glsl_material_library = NULL; /* structs and defines */ -static const char* GPU_DATATYPE_STR[17] = {"", "float", "vec2", "vec3", "vec4", +static const char *GPU_DATATYPE_STR[17] = {"", "float", "vec2", "vec3", "vec4", NULL, NULL, NULL, NULL, "mat3", NULL, NULL, NULL, NULL, NULL, NULL, "mat4"}; #define LINK_IMAGE_BLENDER 1 diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 633112095a7..f5881cdc923 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -393,11 +393,21 @@ void set_rgb_zero(out vec3 outval) outval = vec3(0.0); } +void set_rgb_one(out vec3 outval) +{ + outval = vec3(1.0); +} + void set_rgba_zero(out vec4 outval) { outval = vec4(0.0); } +void set_rgba_one(out vec4 outval) +{ + outval = vec4(1.0); +} + void brightness_contrast(vec4 col, float brightness, float contrast, out vec4 outcol) { float a = 1.0 + contrast; @@ -725,6 +735,21 @@ void combine_rgb(float r, float g, float b, out vec4 col) col = vec4(r, g, b, 1.0); } +void separate_hsv(vec4 col, out float h, out float s, out float v) +{ + vec4 hsv; + + rgb_to_hsv(col, hsv); + h = hsv[0]; + s = hsv[1]; + v = hsv[2]; +} + +void combine_hsv(float h, float s, float v, out vec4 col) +{ + hsv_to_rgb(vec4(h, s, v, 1.0), col); +} + void output_node(vec4 rgb, float alpha, out vec4 outrgb) { outrgb = vec4(rgb.rgb, alpha); @@ -2131,7 +2156,25 @@ void node_add_shader(vec4 shader1, vec4 shader2, out vec4 shader) void node_fresnel(float ior, vec3 N, vec3 I, out float result) { float eta = max(ior, 0.00001); - result = fresnel_dielectric(I, N, (gl_FrontFacing)? eta: 1.0/eta); + result = fresnel_dielectric(normalize(I), N, (gl_FrontFacing)? eta: 1.0/eta); +} + +/* layer_weight */ + +void node_layer_weight(float blend, vec3 N, vec3 I, out float fresnel, out float facing) +{ + /* fresnel */ + float eta = max(1.0 - blend, 0.00001); + fresnel = fresnel_dielectric(normalize(I), N, (gl_FrontFacing)? 1.0/eta : eta ); + + /* facing */ + facing = abs(dot(normalize(I), N)); + if(blend != 0.5) { + blend = clamp(blend, 0.0, 0.99999); + blend = (blend < 0.5)? 2.0*blend: 0.5/(1.0 - blend); + facing = pow(facing, blend); + } + facing = 1.0 - facing; } /* gamma */ diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index 63790cf7d25..271e52da1d4 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -477,7 +477,7 @@ static int startffmpeg(struct anim *anim) const int *inv_table; #endif - if (anim == 0) return(-1); + if (anim == NULL) return(-1); streamcount = anim->streamindex; @@ -960,7 +960,7 @@ static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position, int new_frame_index = 0; /* To quiet gcc barking... */ int old_frame_index = 0; /* To quiet gcc barking... */ - if (anim == 0) return (0); + if (anim == NULL) return (0); av_log(anim->pFormatCtx, AV_LOG_DEBUG, "FETCH: pos=%d\n", position); diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c index 1481b2aaa66..fddfa2618c2 100644 --- a/source/blender/imbuf/intern/cineon/cineonlib.c +++ b/source/blender/imbuf/intern/cineon/cineonlib.c @@ -277,10 +277,10 @@ LogImageFile *cineonOpen(const unsigned char *byteStuff, int fromMemory, size_t return NULL; } - if (cineon->element[i].refLowData == CINEON_UNDEFINED_U32 || isnan(cineon->element[i].refLowData)) + if (cineon->element[i].refLowData == CINEON_UNDEFINED_U32) cineon->element[i].refLowData = 0; - if (cineon->element[i].refHighData == CINEON_UNDEFINED_U32 || isnan(cineon->element[i].refHighData)) + if (cineon->element[i].refHighData == CINEON_UNDEFINED_U32) cineon->element[i].refHighData = (unsigned int)cineon->element[i].maxValue; if (cineon->element[i].refLowQuantity == CINEON_UNDEFINED_R32 || isnan(cineon->element[i].refLowQuantity)) diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c index 5a4371d84ba..e839c2fce90 100644 --- a/source/blender/imbuf/intern/cineon/dpxlib.c +++ b/source/blender/imbuf/intern/cineon/dpxlib.c @@ -300,10 +300,10 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf case descriptor_RGB: case descriptor_RGBA: case descriptor_ABGR: - if (dpx->element[i].refLowData == DPX_UNDEFINED_U32 || isnan(dpx->element[i].refLowData)) + if (dpx->element[i].refLowData == DPX_UNDEFINED_U32) dpx->element[i].refLowData = 0; - if (dpx->element[i].refHighData == DPX_UNDEFINED_U32 || isnan(dpx->element[i].refHighData)) + if (dpx->element[i].refHighData == DPX_UNDEFINED_U32) dpx->element[i].refHighData = (unsigned int)dpx->element[i].maxValue; if (dpx->element[i].refLowQuantity == DPX_UNDEFINED_R32 || isnan(dpx->element[i].refLowQuantity)) @@ -324,10 +324,10 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf case descriptor_CbYCr: case descriptor_CbYACrYA: case descriptor_CbYCrA: - if (dpx->element[i].refLowData == DPX_UNDEFINED_U32 || isnan(dpx->element[i].refLowData)) + if (dpx->element[i].refLowData == DPX_UNDEFINED_U32) dpx->element[i].refLowData = 16.0f / 255.0f * dpx->element[i].maxValue; - if (dpx->element[i].refHighData == DPX_UNDEFINED_U32 || isnan(dpx->element[i].refHighData)) + if (dpx->element[i].refHighData == DPX_UNDEFINED_U32) dpx->element[i].refHighData = 235.0f / 255.0f * dpx->element[i].maxValue; if (dpx->element[i].refLowQuantity == DPX_UNDEFINED_R32 || isnan(dpx->element[i].refLowQuantity)) diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c index 93324b94cdc..49a40c461ac 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -656,7 +656,6 @@ static int add_to_proxy_output_ffmpeg( static void free_proxy_output_ffmpeg(struct proxy_output_ctx *ctx, int rollback) { - int i; char fname[FILE_MAX]; char fname_tmp[FILE_MAX]; @@ -674,18 +673,12 @@ static void free_proxy_output_ffmpeg(struct proxy_output_ctx *ctx, avcodec_close(ctx->c); - for (i = 0; i < ctx->of->nb_streams; i++) { - if (&ctx->of->streams[i]) { - av_freep(&ctx->of->streams[i]); - } - } - if (ctx->of->oformat) { if (!(ctx->of->oformat->flags & AVFMT_NOFILE)) { avio_close(ctx->of->pb); } } - av_free(ctx->of); + avformat_free_context(ctx->of); MEM_freeN(ctx->video_buffer); @@ -854,6 +847,9 @@ static void index_rebuild_ffmpeg_finish(FFmpegIndexBuilderContext *context, int } } + avcodec_close(context->iCodecCtx); + avformat_close_input(&context->iFormatCtx); + MEM_freeN(context); } diff --git a/source/blender/imbuf/intern/oiio/openimageio_api.cpp b/source/blender/imbuf/intern/oiio/openimageio_api.cpp index 838343dce35..fe74b8f7cce 100644 --- a/source/blender/imbuf/intern/oiio/openimageio_api.cpp +++ b/source/blender/imbuf/intern/oiio/openimageio_api.cpp @@ -98,11 +98,20 @@ static ImBuf *imb_oiio_load_image(ImageInput *in, int width, int height, int com try { - in->read_image(TypeDesc::UINT8, - (uchar *)ibuf->rect + (height - 1) * scanlinesize, - AutoStride, - -scanlinesize, - AutoStride); + if (!in->read_image(TypeDesc::UINT8, + (uchar *)ibuf->rect + (height - 1) * scanlinesize, + AutoStride, + -scanlinesize, + AutoStride)) + { + std::cerr << __func__ << ": ImageInput::read_image() failed:" << std::endl + << in->geterror() << std::endl; + + if (ibuf) + IMB_freeImBuf(ibuf); + + return NULL; + } } catch (const std::exception &exc) { @@ -128,11 +137,20 @@ static ImBuf *imb_oiio_load_image_float(ImageInput *in, int width, int height, i try { - in->read_image(TypeDesc::FLOAT, - (uchar *)ibuf->rect_float + (height - 1) * scanlinesize, - AutoStride, - -scanlinesize, - AutoStride); + if (!in->read_image(TypeDesc::FLOAT, + (uchar *)ibuf->rect_float + (height - 1) * scanlinesize, + AutoStride, + -scanlinesize, + AutoStride)) + { + std::cerr << __func__ << ": ImageInput::read_image() failed:" << std::endl + << in->geterror() << std::endl; + + if (ibuf) + IMB_freeImBuf(ibuf); + + return NULL; + } } catch (const std::exception &exc) { @@ -191,12 +209,18 @@ struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspac colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE); in = ImageInput::create(filename); - if (!in) return NULL; + if (!in) { + std::cerr << __func__ << ": ImageInput::create() failed:" << std::endl + << OpenImageIO::geterror() << std::endl; + return NULL; + } ImageSpec spec, config; config.attribute("oiio:UnassociatedAlpha", (int) 1); if (!in->open(filename, spec, config)) { + std::cerr << __func__ << ": ImageInput::open() failed:" << std::endl + << in->geterror() << std::endl; delete in; return NULL; } diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index ecf6458ac57..9d1ff79960c 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -120,6 +120,17 @@ const char *imb_ext_image_qt[] = { NULL }; +const char *imb_ext_movie_qt[] = { + ".avi", + ".flc", + ".dv", + ".r3d", + ".mov", + ".movie", + ".mv", + NULL +}; + const char *imb_ext_movie[] = { ".avi", ".flc", @@ -131,10 +142,13 @@ const char *imb_ext_movie[] = { ".m2t", ".m2ts", ".mts", + ".ts", ".mv", ".avs", ".wmv", ".ogv", + ".ogg", + ".r3d", ".dv", ".mpeg", ".mpg", @@ -145,6 +159,7 @@ const char *imb_ext_movie[] = { ".divx", ".xvid", ".mxf", + ".webm", NULL }; @@ -448,14 +463,7 @@ int IMB_isanim(const char *filename) if (U.uiflag & USER_FILTERFILEEXTS) { if (G.have_quicktime) { - if (BLI_testextensie(filename, ".avi") || - BLI_testextensie(filename, ".flc") || - BLI_testextensie(filename, ".dv") || - BLI_testextensie(filename, ".r3d") || - BLI_testextensie(filename, ".mov") || - BLI_testextensie(filename, ".movie") || - BLI_testextensie(filename, ".mv")) - { + if (BLI_testextensie_array(filename, imb_ext_movie_qt)) { type = imb_get_anim_type(filename); } else { @@ -463,11 +471,7 @@ int IMB_isanim(const char *filename) } } else { /* no quicktime */ - if (BLI_testextensie(filename, ".avi") || - BLI_testextensie(filename, ".dv") || - BLI_testextensie(filename, ".r3d") || - BLI_testextensie(filename, ".mv")) - { + if (BLI_testextensie_array(filename, imb_ext_movie)) { type = imb_get_anim_type(filename); } else { diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index fc0dd54a8e7..7a7e08138b0 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -459,6 +459,8 @@ typedef struct FCurve { /* curve coloring (for editor) */ int color_mode; /* coloring method to use (eFCurve_Coloring) */ float color[3]; /* the last-color this curve took */ + + float prev_norm_factor, pad; } FCurve; diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h index 4780b2e85de..e751966c34d 100644 --- a/source/blender/makesdna/DNA_armature_types.h +++ b/source/blender/makesdna/DNA_armature_types.h @@ -88,7 +88,7 @@ typedef struct bArmature { * - from the user perspective active == last selected * - active should be ignored when not visible (hidden layer) */ - Bone *act_bone; /* active bone (when not in editmode) */ + Bone *act_bone; /* active bone */ struct EditBone *act_edbone; /* active editbone (in editmode) */ void *sketch; /* sketch struct for etch-a-ton */ diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 2cfbbbd516b..0141c4b61db 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -223,7 +223,7 @@ typedef struct Curve { float linewidth; char *str; - struct SelBox *selboxes; + struct SelBox *selboxes; /* runtime variable for drawing selections (editmode data) */ struct EditFont *editfont; char family[24]; @@ -364,6 +364,8 @@ typedef enum eBezTriple_KeyframeType { /* mixed with KEY_LINEAR but define here since only curve supports */ #define KEY_CU_EASE 3 +/* indicates point has been seen during surface duplication */ +#define SURF_SEEN 4 #endif diff --git a/source/blender/makesdna/DNA_fileglobal_types.h b/source/blender/makesdna/DNA_fileglobal_types.h index 7e81041fe4a..040b55d9eb6 100644 --- a/source/blender/makesdna/DNA_fileglobal_types.h +++ b/source/blender/makesdna/DNA_fileglobal_types.h @@ -48,8 +48,8 @@ typedef struct FileGlobal { struct Scene *curscene; int fileflags; int globalf; - int revision; /* svn revision from buildinfo */ - int pad; + uint64_t build_commit_timestamp; /* commit timestamp from buildinfo */ + char build_hash[16]; /* hash from buildinfo */ /* file path where this was saved, for recover */ char filename[1024]; /* 1024 = FILE_MAX */ } FileGlobal; diff --git a/source/blender/makesdna/DNA_ipo_types.h b/source/blender/makesdna/DNA_ipo_types.h index 2699c6e576e..b4088cc5a5d 100644 --- a/source/blender/makesdna/DNA_ipo_types.h +++ b/source/blender/makesdna/DNA_ipo_types.h @@ -308,6 +308,7 @@ typedef struct Ipo { #define WO_MISTSTA 10 #define WO_MISTHI 11 +/* Stars are deprecated */ #define WO_STAR_R 12 #define WO_STAR_G 13 #define WO_STAR_B 14 diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 799968335b7..11bdf707c45 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -822,12 +822,13 @@ typedef struct ScrewModifierData { ModifierData modifier; struct Object *ob_axis; - int steps; - int render_steps; - int iter; + unsigned int steps; + unsigned int render_steps; + unsigned int iter; float screw_ofs; float angle; - short axis; + char axis; + char pad; short flag; } ScrewModifierData; @@ -1177,11 +1178,27 @@ typedef struct TriangulateModifierData { ModifierData modifier; int flag; + int quad_method; + int ngon_method; int pad; } TriangulateModifierData; enum { - MOD_TRIANGULATE_BEAUTY = (1 << 0), + MOD_TRIANGULATE_BEAUTY = (1 << 0), /* deprecated */ +}; + +/* Triangulate methods - NGons */ +enum { + MOD_TRIANGULATE_NGON_BEAUTY = 0, + MOD_TRIANGULATE_NGON_SCANFILL, +}; + +/* Triangulate methods - Quads */ +enum { + MOD_TRIANGULATE_QUAD_BEAUTY = 0, + MOD_TRIANGULATE_QUAD_FIXED, + MOD_TRIANGULATE_QUAD_ALTERNATE, + MOD_TRIANGULATE_QUAD_SHORTEDGE }; typedef struct LaplacianSmoothModifierData { diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 75b9540f736..a4510dd23fd 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -402,6 +402,7 @@ typedef struct bNodeTree { #define NTREE_TWO_PASS 4 /* two pass */ #define NTREE_COM_GROUPNODE_BUFFER 8 /* use groupnode buffers */ #define NTREE_VIEWER_BORDER 16 /* use a border for viewer nodes */ +#define NTREE_IS_LOCALIZED 32 /* tree is localized copy, free when deleting node groups */ /* XXX not nice, but needed as a temporary flags * for group updates after library linking. @@ -676,19 +677,15 @@ typedef struct NodeLensDist { } NodeLensDist; typedef struct NodeColorBalance { - /* for processing */ + /* ASC CDL parameters */ float slope[3]; float offset[3]; float power[3]; - /* for ui representation */ + /* LGG parameters */ float lift[3]; float gamma[3]; float gain[3]; - - /* temp storage for inverted lift */ - float lift_lgg[3]; - float gamma_inv[3]; } NodeColorBalance; typedef struct NodeColorspill { diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 232fe62df31..7aabad86809 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -196,7 +196,7 @@ typedef struct SceneRenderLayer { #define SCE_LAY_SOLID 1 #define SCE_LAY_ZTRA 2 #define SCE_LAY_HALO 4 -#define SCE_LAY_EDGE 8 +#define SCE_LAY_EDGE 8 /* deprecated */ #define SCE_LAY_SKY 16 #define SCE_LAY_STRAND 32 #define SCE_LAY_FRS 64 @@ -378,7 +378,7 @@ typedef struct RenderData { float framelen, blurfac; /** For UR edge rendering: give the edges this color */ - float edgeR, edgeG, edgeB; + float edgeR DNA_DEPRECATED, edgeG DNA_DEPRECATED, edgeB DNA_DEPRECATED; /* standalone player */ // XXX deprecated since 2.5 @@ -725,7 +725,7 @@ typedef struct GameData { #define GAME_PLAYER_DESKTOP_RESOLUTION (1 << 1) /* GameData.matmode */ -#define GAME_MAT_TEXFACE 0 +#define GAME_MAT_TEXFACE 0 /* deprecated */ #define GAME_MAT_MULTITEX 1 #define GAME_MAT_GLSL 2 @@ -1212,6 +1212,7 @@ typedef struct Scene { /* flag */ /* use preview range */ #define SCER_PRV_RANGE (1<<0) +#define SCER_LOCK_FRAME_SELECTION (1<<1) /* mode (int now) */ #define R_OSA 0x0001 @@ -1219,7 +1220,7 @@ typedef struct Scene { #define R_GAMMA 0x0004 #define R_ORTHO 0x0008 #define R_ENVMAP 0x0010 -#define R_EDGE 0x0020 +#define R_EDGE 0x0020 /* deprecated */ #define R_FIELDS 0x0040 #define R_FIELDSTILL 0x0080 /*#define R_RADIO 0x0100 */ /* deprecated */ @@ -1456,6 +1457,7 @@ typedef struct Scene { #define SCE_SNAP_MODE_NODE_X 5 #define SCE_SNAP_MODE_NODE_Y 6 #define SCE_SNAP_MODE_NODE_XY 7 +#define SCE_SNAP_MODE_GRID 8 /* toolsettings->selectmode */ #define SCE_SELECT_VERTEX 1 /* for mesh */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 5befaa87e7f..4ebfe349a9f 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -286,11 +286,11 @@ typedef enum eSpaceOutliner_Mode { SO_GROUPS = 6, SO_LIBRARIES = 7, /* SO_VERSE_SESSION = 8, */ /* deprecated! */ - /* SO_VERSE_MS = 9, */ /* deprecated!*/ + /* SO_VERSE_MS = 9, */ /* deprecated! */ SO_SEQUENCE = 10, SO_DATABLOCKS = 11, SO_USERDEF = 12, - SO_KEYMAP = 13, + /* SO_KEYMAP = 13, */ /* deprecated! */ } eSpaceOutliner_Mode; /* SpaceOops->storeflag */ @@ -366,6 +366,9 @@ typedef enum eGraphEdit_Flag { SIPO_BEAUTYDRAW_OFF = (1 << 12), /* draw grouped channels with colors set in group */ SIPO_NODRAWGCOLORS = (1 << 13), + /* normalize curves on display */ + SIPO_NORMALIZE = (1 << 14), + SIPO_NORMALIZE_FREEZE = (1 << 15), } eGraphEdit_Flag; /* SpaceIpo->mode (Graph Editor Mode) */ @@ -690,6 +693,7 @@ typedef enum eFileSel_File_Types { BTXFILE = (1 << 12), COLLADAFILE = (1 << 13), OPERATORFILE = (1 << 14), /* from filter_glob operator property */ + APPLICATIONBUNDLE = (1 << 15), } eFileSel_File_Types; /* Selection Flags in filesel: struct direntry, unsigned char selflag */ diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index 49c1e3ed35d..ad9a2ea169c 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -142,6 +142,17 @@ typedef struct MovieTrackingTrack { float minimum_correlation; /* minimal correlation which is still treated as successful tracking */ struct bGPdata *gpd; /* grease-pencil data */ + + /* Weight of this track. + * + * Weight defines how much the track affects on the final reconstruction, + * usually gets animated in a way so when track has just appeared it's + * weight is zero and then it gets faded up. + * + * Used to prevent jumps of the camera when tracks are appearing or + * disappearing. + */ + float weight, pad; } MovieTrackingTrack; typedef struct MovieTrackingPlaneMarker { @@ -207,8 +218,7 @@ typedef struct MovieTrackingSettings { * were moved to per-tracking object settings */ - float reconstruction_success_threshold; - int reconstruction_flag; + int reconstruction_flag, pad; /* which camera intrinsics to refine. uses on the REFINE_* flags */ short refine_camera_intrinsics, pad2; @@ -409,7 +419,7 @@ enum { /* MovieTrackingSettings->reconstruction_flag */ enum { - TRACKING_USE_FALLBACK_RECONSTRUCTION = (1 << 0), + /* TRACKING_USE_FALLBACK_RECONSTRUCTION = (1 << 0), */ /* DEPRECATED */ TRACKING_USE_KEYFRAME_SELECTION = (1 << 1) }; diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 1621f7c6cb6..37d5f313dfb 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -474,6 +474,7 @@ typedef struct UserDef { struct ColorBand coba_weight; /* from texture.h */ float sculpt_paint_overlay_col[3]; + float gpencil_new_layer_col[4]; /* default color for newly created Grease Pencil layers */ short tweak_threshold; short pad3; diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 155f41b2c6e..5eba8503c2a 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -280,7 +280,8 @@ typedef struct View3D { #define V3D_SOLID_MATCAP 4096 /* user flag */ #define V3D_SHOW_SOLID_MATCAP 8192 /* runtime flag */ #define V3D_OCCLUDE_WIRE 16384 -#define V3D_NO_PHYSICS 32768 +#define V3D_SHADELESS_TEX 32768 +#define V3D_NO_PHYSICS 32768 // RB_FIXME need new drawing flag /* View3D->around */ diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 07a679be571..ff43cc31b9a 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -60,42 +60,44 @@ struct ReportList; struct Report; struct uiLayout; -#define OP_MAX_TYPENAME 64 -#define KMAP_MAX_NAME 64 +#define OP_MAX_TYPENAME 64 +#define KMAP_MAX_NAME 64 /* keep in sync with 'wm_report_items' in wm_rna.c */ typedef enum ReportType { - RPT_DEBUG = 1 << 0, - RPT_INFO = 1 << 1, - RPT_OPERATOR = 1 << 2, - RPT_PROPERTY = 1 << 3, - RPT_WARNING = 1 << 4, - RPT_ERROR = 1 << 5, - RPT_ERROR_INVALID_INPUT = 1 << 6, - RPT_ERROR_INVALID_CONTEXT = 1 << 7, - RPT_ERROR_OUT_OF_MEMORY = 1 << 8 + RPT_DEBUG = (1 << 0), + RPT_INFO = (1 << 1), + RPT_OPERATOR = (1 << 2), + RPT_PROPERTY = (1 << 3), + RPT_WARNING = (1 << 4), + RPT_ERROR = (1 << 5), + RPT_ERROR_INVALID_INPUT = (1 << 6), + RPT_ERROR_INVALID_CONTEXT = (1 << 7), + RPT_ERROR_OUT_OF_MEMORY = (1 << 8), } ReportType; -#define RPT_DEBUG_ALL (RPT_DEBUG) -#define RPT_INFO_ALL (RPT_INFO) -#define RPT_OPERATOR_ALL (RPT_OPERATOR) -#define RPT_PROPERTY_ALL (RPT_PROPERTY) -#define RPT_WARNING_ALL (RPT_WARNING) -#define RPT_ERROR_ALL (RPT_ERROR|RPT_ERROR_INVALID_INPUT|RPT_ERROR_INVALID_CONTEXT|RPT_ERROR_OUT_OF_MEMORY) +#define RPT_DEBUG_ALL (RPT_DEBUG) +#define RPT_INFO_ALL (RPT_INFO) +#define RPT_OPERATOR_ALL (RPT_OPERATOR) +#define RPT_PROPERTY_ALL (RPT_PROPERTY) +#define RPT_WARNING_ALL (RPT_WARNING) +#define RPT_ERROR_ALL (RPT_ERROR|RPT_ERROR_INVALID_INPUT|RPT_ERROR_INVALID_CONTEXT|RPT_ERROR_OUT_OF_MEMORY) enum ReportListFlags { - RPT_PRINT = 1, - RPT_STORE = 2, - RPT_FREE = 4, - RPT_OP_HOLD = 8 /* don't move them into the operator global list (caller will use) */ + RPT_PRINT = (1 << 0), + RPT_STORE = (1 << 1), + RPT_FREE = (1 << 2), + RPT_OP_HOLD = (1 << 3), /* don't move them into the operator global list (caller will use) */ }; + +/* These two Lines with # tell makesdna this struct can be excluded. */ # # typedef struct Report { struct Report *next, *prev; - short type; /* ReportType */ + short type; /* ReportType */ short flag; - int len; /* strlen(message), saves some time calculating the word wrap */ + int len; /* strlen(message), saves some time calculating the word wrap */ const char *typestr; const char *message; } Report; @@ -103,13 +105,14 @@ typedef struct Report { /* saved in the wm, don't remove */ typedef struct ReportList { ListBase list; - int printlevel; /* ReportType */ - int storelevel; /* ReportType */ + int printlevel; /* ReportType */ + int storelevel; /* ReportType */ int flag, pad; struct wmTimer *reporttimer; } ReportList; /* timer customdata to control reports display */ +/* These two Lines with # tell makesdna this struct can be excluded. */ # # typedef struct ReportTimerInfo { @@ -124,84 +127,86 @@ typedef struct ReportTimerInfo { /* windowmanager is saved, tag WMAN */ typedef struct wmWindowManager { ID id; - - struct wmWindow *windrawable, *winactive; /* separate active from drawable */ + + struct wmWindow *windrawable, *winactive; /* separate active from drawable */ ListBase windows; - - int initialized; /* set on file read */ - short file_saved; /* indicator whether data was saved */ - short op_undo_depth; /* operator stack depth to avoid nested undo pushes */ - - ListBase operators; /* operator registry */ - - ListBase queue; /* refresh/redraw wmNotifier structs */ - - struct ReportList reports; /* information and error reports */ - - ListBase jobs; /* threaded jobs manager */ - - ListBase paintcursors; /* extra overlay cursors to draw, like circles */ - - ListBase drags; /* active dragged items */ - - ListBase keyconfigs; /* known key configurations */ - struct wmKeyConfig *defaultconf; /* default configuration */ - struct wmKeyConfig *addonconf; /* addon configuration */ - struct wmKeyConfig *userconf; /* user configuration */ - - ListBase timers; /* active timers */ - struct wmTimer *autosavetimer; /* timer for auto save */ + + int initialized; /* set on file read */ + short file_saved; /* indicator whether data was saved */ + short op_undo_depth; /* operator stack depth to avoid nested undo pushes */ + + ListBase operators; /* operator registry */ + + ListBase queue; /* refresh/redraw wmNotifier structs */ + + struct ReportList reports; /* information and error reports */ + + ListBase jobs; /* threaded jobs manager */ + + ListBase paintcursors; /* extra overlay cursors to draw, like circles */ + + ListBase drags; /* active dragged items */ + + ListBase keyconfigs; /* known key configurations */ + struct wmKeyConfig *defaultconf; /* default configuration */ + struct wmKeyConfig *addonconf; /* addon configuration */ + struct wmKeyConfig *userconf; /* user configuration */ + + ListBase timers; /* active timers */ + struct wmTimer *autosavetimer; /* timer for auto save */ } wmWindowManager; /* wmWindowManager.initialized */ -#define WM_INIT_WINDOW (1<<0) -#define WM_INIT_KEYMAP (1<<1) +enum { + WM_INIT_WINDOW = (1<<0), + WM_INIT_KEYMAP = (1<<1), +}; /* the savable part, rest of data is local in ghostwinlay */ typedef struct wmWindow { struct wmWindow *next, *prev; - - void *ghostwin; /* don't want to include ghost.h stuff */ - - int winid; /* winid also in screens, is for retrieving this window after read */ - short grabcursor; /* cursor grab mode */ + void *ghostwin; /* don't want to include ghost.h stuff */ + + int winid; /* winid also in screens, is for retrieving this window after read */ + + short grabcursor; /* cursor grab mode */ short pad; - - struct bScreen *screen; /* active screen */ - struct bScreen *newscreen; /* temporary when switching */ - char screenname[64]; /* MAX_ID_NAME for matching window with active screen after file read */ - - short posx, posy, sizex, sizey; /* window coords */ - short windowstate; /* borderless, full */ - short monitor; /* multiscreen... no idea how to store yet */ - short active; /* set to 1 if an active window, for quick rejects */ - short cursor; /* current mouse cursor type */ - short lastcursor; /* previous cursor when setting modal one */ - short modalcursor; /* the current modal cursor */ - short addmousemove; /* internal: tag this for extra mousemove event, makes cursors/buttons active on UI switching */ + + struct bScreen *screen; /* active screen */ + struct bScreen *newscreen; /* temporary when switching */ + char screenname[64]; /* MAX_ID_NAME for matching window with active screen after file read */ + + short posx, posy, sizex, sizey; /* window coords */ + short windowstate; /* borderless, full */ + short monitor; /* multiscreen... no idea how to store yet */ + short active; /* set to 1 if an active window, for quick rejects */ + short cursor; /* current mouse cursor type */ + short lastcursor; /* previous cursor when setting modal one */ + short modalcursor; /* the current modal cursor */ + short addmousemove; /* internal: tag this for extra mousemove event, makes cursors/buttons active on UI switching */ short pad2; - struct wmEvent *eventstate; /* storage for event system */ - - struct wmSubWindow *curswin; /* internal for wm_subwindow.c only */ - - struct wmGesture *tweak; /* internal for wm_operators.c */ - - int drawmethod, drawfail; /* internal for wm_draw.c only */ - void *drawdata; /* internal for wm_draw.c only */ - - ListBase queue; /* all events (ghost level events were handled) */ - ListBase handlers; /* window+screen handlers, handled last */ - ListBase modalhandlers; /* priority handlers, handled first */ - - ListBase subwindows; /* opengl stuff for sub windows, see notes in wm_subwindow.c */ - ListBase gesture; /* gesture stuff */ + struct wmEvent *eventstate; /* storage for event system */ + + struct wmSubWindow *curswin; /* internal for wm_subwindow.c only */ + + struct wmGesture *tweak; /* internal for wm_operators.c */ + + int drawmethod, drawfail; /* internal for wm_draw.c only */ + void *drawdata; /* internal for wm_draw.c only */ + + ListBase queue; /* all events (ghost level events were handled) */ + ListBase handlers; /* window+screen handlers, handled last */ + ListBase modalhandlers; /* priority handlers, handled first */ + + ListBase subwindows; /* opengl stuff for sub windows, see notes in wm_subwindow.c */ + ListBase gesture; /* gesture stuff */ } wmWindow; +/* These two Lines with # tell makesdna this struct can be excluded. */ /* should be something like DNA_EXCLUDE * but the preprocessor first removes all comments, spaces etc */ - # # typedef struct wmOperatorTypeMacro { @@ -210,37 +215,36 @@ typedef struct wmOperatorTypeMacro { /* operator id */ char idname[64]; /* rna pointer to access properties, like keymap */ - struct IDProperty *properties; /* operator properties, assigned to ptr->data and can be written to a file */ + struct IDProperty *properties; /* operator properties, assigned to ptr->data and can be written to a file */ struct PointerRNA *ptr; - } wmOperatorTypeMacro; /* partial copy of the event, for matching by eventhandler */ typedef struct wmKeyMapItem { struct wmKeyMapItem *next, *prev; - + /* operator */ - char idname[64]; /* used to retrieve operator type pointer */ - IDProperty *properties; /* operator properties, assigned to ptr->data and can be written to a file */ - + char idname[64]; /* used to retrieve operator type pointer */ + IDProperty *properties; /* operator properties, assigned to ptr->data and can be written to a file */ + /* modal */ - char propvalue_str[64]; /* runtime temporary storage for loading */ - short propvalue; /* if used, the item is from modal map */ + char propvalue_str[64]; /* runtime temporary storage for loading */ + short propvalue; /* if used, the item is from modal map */ /* event */ - short type; /* event code itself */ - short val; /* KM_ANY, KM_PRESS, KM_NOTHING etc */ - short shift, ctrl, alt, oskey; /* oskey is apple or windowskey, value denotes order of pressed */ - short keymodifier; /* rawkey modifier */ - + short type; /* event code itself */ + short val; /* KM_ANY, KM_PRESS, KM_NOTHING etc */ + short shift, ctrl, alt, oskey; /* oskey is apple or windowskey, value denotes order of pressed */ + short keymodifier; /* rawkey modifier */ + /* flag: inactive, expanded */ short flag; /* runtime */ - short maptype; /* keymap editor */ - short id; /* unique identifier. Positive for kmi that override builtins, negative otherwise */ + short maptype; /* keymap editor */ + short id; /* unique identifier. Positive for kmi that override builtins, negative otherwise */ short pad; - struct PointerRNA *ptr; /* rna pointer to access properties */ + struct PointerRNA *ptr; /* rna pointer to access properties */ } wmKeyMapItem; /* used instead of wmKeyMapItem for diff keymaps */ @@ -252,52 +256,68 @@ typedef struct wmKeyMapDiffItem { } wmKeyMapDiffItem; /* wmKeyMapItem.flag */ -#define KMI_INACTIVE 1 -#define KMI_EXPANDED 2 -#define KMI_USER_MODIFIED 4 -#define KMI_UPDATE 8 +enum { + KMI_INACTIVE = (1 << 0), + KMI_EXPANDED = (1 << 1), + KMI_USER_MODIFIED = (1 << 2), + KMI_UPDATE = (1 << 3), +}; + +/* wmKeyMapItem.maptype */ +enum { + KMI_TYPE_KEYBOARD = 0, + KMI_TYPE_MOUSE = 1, + KMI_TYPE_TWEAK = 2, + KMI_TYPE_TEXTINPUT = 3, + KMI_TYPE_TIMER = 4, + KMI_TYPE_NDOF = 5, +}; /* stored in WM, the actively used keymaps */ typedef struct wmKeyMap { struct wmKeyMap *next, *prev; - + ListBase items; ListBase diff_items; - - char idname[64]; /* global editor keymaps, or for more per space/region */ - short spaceid; /* same IDs as in DNA_space_types.h */ - short regionid; /* see above */ - - short flag; /* general flags */ - short kmi_id; /* last kmi id */ - + + char idname[64]; /* global editor keymaps, or for more per space/region */ + short spaceid; /* same IDs as in DNA_space_types.h */ + short regionid; /* see above */ + + short flag; /* general flags */ + short kmi_id; /* last kmi id */ + /* runtime */ - int (*poll)(struct bContext *); /* verify if enabled in the current context */ - void *modal_items; /* for modal, EnumPropertyItem for now */ + int (*poll)(struct bContext *); /* verify if enabled in the current context */ + void *modal_items; /* for modal, EnumPropertyItem for now */ } wmKeyMap; /* wmKeyMap.flag */ -#define KEYMAP_MODAL 1 /* modal map, not using operatornames */ -#define KEYMAP_USER 2 /* user keymap */ -#define KEYMAP_EXPANDED 4 -#define KEYMAP_CHILDREN_EXPANDED 8 -#define KEYMAP_DIFF 16 /* diff keymap for user preferences */ -#define KEYMAP_USER_MODIFIED 32 /* keymap has user modifications */ -#define KEYMAP_UPDATE 64 +enum { + KEYMAP_MODAL = (1 << 0), /* modal map, not using operatornames */ + KEYMAP_USER = (1 << 1), /* user keymap */ + KEYMAP_EXPANDED = (1 << 2), + KEYMAP_CHILDREN_EXPANDED = (1 << 3), + KEYMAP_DIFF = (1 << 4), /* diff keymap for user preferences */ + KEYMAP_USER_MODIFIED = (1 << 5), /* keymap has user modifications */ + KEYMAP_UPDATE = (1 << 6), +}; typedef struct wmKeyConfig { struct wmKeyConfig *next, *prev; - char idname[64]; /* unique name */ - char basename[64]; /* idname of configuration this is derives from, "" if none */ - + char idname[64]; /* unique name */ + char basename[64]; /* idname of configuration this is derives from, "" if none */ + ListBase keymaps; int actkeymap, flag; } wmKeyConfig; /* wmKeyConfig.flag */ -#define KEYCONF_USER (1 << 1) -#define KEYCONF_INIT_DEFAULT (1 << 2) +enum { + KEYCONF_USER = (1 << 1), /* And what about (1 << 0)? */ + KEYCONF_INIT_DEFAULT = (1 << 2), +}; /* this one is the operator itself, stored in files for macros etc */ /* operator + operatortype should be able to redo entirely, but for different contextes */ @@ -305,46 +325,46 @@ typedef struct wmOperator { struct wmOperator *next, *prev; /* saved */ - char idname[64];/* used to retrieve type pointer */ - IDProperty *properties; /* saved, user-settable properties */ + char idname[64]; /* used to retrieve type pointer */ + IDProperty *properties; /* saved, user-settable properties */ /* runtime */ - struct wmOperatorType *type;/* operator type definition from idname */ - void *customdata; /* custom storage, only while operator runs */ - void *py_instance; /* python stores the class instance here */ + struct wmOperatorType *type; /* operator type definition from idname */ + void *customdata; /* custom storage, only while operator runs */ + void *py_instance; /* python stores the class instance here */ - struct PointerRNA *ptr; /* rna pointer to access properties */ - struct ReportList *reports; /* errors and warnings storage */ + struct PointerRNA *ptr; /* rna pointer to access properties */ + struct ReportList *reports; /* errors and warnings storage */ - ListBase macro; /* list of operators, can be a tree */ - struct wmOperator *opm; /* current running macro, not saved */ - struct uiLayout *layout; /* runtime for drawing */ + ListBase macro; /* list of operators, can be a tree */ + struct wmOperator *opm; /* current running macro, not saved */ + struct uiLayout *layout; /* runtime for drawing */ short flag, pad[3]; } wmOperator; - /* operator type return flags: exec(), invoke() modal(), return values */ -#define OPERATOR_RUNNING_MODAL (1<<0) -#define OPERATOR_CANCELLED (1<<1) -#define OPERATOR_FINISHED (1<<2) +enum { + OPERATOR_RUNNING_MODAL = (1 << 0), + OPERATOR_CANCELLED = (1 << 1), + OPERATOR_FINISHED = (1 << 2), /* add this flag if the event should pass through */ -#define OPERATOR_PASS_THROUGH (1<<3) + OPERATOR_PASS_THROUGH = (1 << 3), /* in case operator got executed outside WM code... like via fileselect */ -#define OPERATOR_HANDLED (1<<4) - -#define OPERATOR_FLAGS_ALL ((1<<5)-1) + OPERATOR_HANDLED = (1 << 4), +}; +#define OPERATOR_FLAGS_ALL (OPERATOR_RUNNING_MODAL | OPERATOR_CANCELLED | OPERATOR_FINISHED | \ + OPERATOR_PASS_THROUGH | OPERATOR_HANDLED) /* sanity checks for debug mode only */ #define OPERATOR_RETVAL_CHECK(ret) (void)ret, BLI_assert(ret != 0 && (ret & OPERATOR_FLAGS_ALL) == ret) /* wmOperator flag */ enum { - OP_GRAB_POINTER = (1 << 0), - + OP_GRAB_POINTER = (1 << 0), /* low level flag so exec() operators can tell if they were invoked, use with care. * typically this shouldn't make any difference, but it rare cases its needed (see smooth-view) */ - OP_IS_INVOKE = (1 << 1), + OP_IS_INVOKE = (1 << 1), }; #endif /* __DNA_WINDOWMANAGER_TYPES_H__ */ diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h index a0863b18cca..3e01e159d6c 100644 --- a/source/blender/makesdna/DNA_world_types.h +++ b/source/blender/makesdna/DNA_world_types.h @@ -47,7 +47,7 @@ struct MTex; /** * World defines general modeling data such as a background fill, - * gravity, color model, stars, etc. It mixes game-data, rendering + * gravity, color model etc. It mixes game-data, rendering * data and modeling data. */ typedef struct World { ID id; @@ -96,8 +96,8 @@ typedef struct World { float misi, miststa, mistdist, misthi; float starr DNA_DEPRECATED, starg DNA_DEPRECATED, starb DNA_DEPRECATED, stark DNA_DEPRECATED; /* Deprecated */ - float starsize, starmindist; - float stardist, starcolnoise; + float starsize DNA_DEPRECATED, starmindist DNA_DEPRECATED; + float stardist DNA_DEPRECATED, starcolnoise DNA_DEPRECATED; /* unused now: DOF */ short dofsta, dofend, dofmin, dofmax; @@ -142,7 +142,7 @@ typedef struct World { /* mode */ #define WO_MIST 1 -#define WO_STARS 2 +#define WO_STARS 2 /* deprecated */ /*#define WO_DOF 4*/ #define WO_ACTIVITY_CULLING 8 #define WO_ENV_LIGHT 16 diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index b4b79059f93..d82bae1ce57 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -660,7 +660,6 @@ extern StructRNA RNA_World; extern StructRNA RNA_WorldAmbientOcclusion; extern StructRNA RNA_WorldLighting; extern StructRNA RNA_WorldMistSettings; -extern StructRNA RNA_WorldStarsSettings; extern StructRNA RNA_WorldTextureSlot; extern StructRNA RNA_XnorController; extern StructRNA RNA_XorController; @@ -1034,6 +1033,7 @@ void RNA_struct_property_unset(PointerRNA *ptr, const char *identifier); /* python compatible string representation of this property, (must be freed!) */ char *RNA_property_as_string(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index, int max_prop_length); +char *RNA_pointer_as_string_id(struct bContext *C, PointerRNA *ptr); char *RNA_pointer_as_string(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop_ptr, PointerRNA *ptr_prop); char *RNA_pointer_as_string_keywords_ex(struct bContext *C, PointerRNA *ptr, const bool skip_optional_value, const bool all_args, diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index d33d3df8a5e..f1881c8beba 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -60,6 +60,9 @@ extern EnumPropertyItem constraint_type_items[]; extern EnumPropertyItem boidrule_type_items[]; extern EnumPropertyItem sequence_modifier_type_items[]; +extern EnumPropertyItem modifier_triangulate_quad_method_items[]; +extern EnumPropertyItem modifier_triangulate_ngon_method_items[]; + extern EnumPropertyItem image_type_items[]; extern EnumPropertyItem image_color_mode_items[]; extern EnumPropertyItem image_depth_mode_items[]; @@ -68,7 +71,6 @@ extern EnumPropertyItem image_generated_type_items[]; extern EnumPropertyItem color_sets_items[]; extern EnumPropertyItem beztriple_keyframe_type_items[]; -extern EnumPropertyItem beztriple_handle_type_items[]; extern EnumPropertyItem beztriple_interpolation_mode_items[]; extern EnumPropertyItem keyframe_handle_type_items[]; diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 8a4022de104..1cb9eb8e9ae 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1555,7 +1555,7 @@ static void rna_def_property_funcs_header(FILE *f, StructRNA *srna, PropertyDefR } else if (prop->arraydimension && prop->totarraylength) { fprintf(f, "void %sget(PointerRNA *ptr, int values[%u]);\n", func, prop->totarraylength); - fprintf(f, "void %sset(PointerRNA *ptr, const int values[%d]);\n", func, prop->totarraylength); + fprintf(f, "void %sset(PointerRNA *ptr, const int values[%u]);\n", func, prop->totarraylength); } else { fprintf(f, "void %sget(PointerRNA *ptr, int values[]);\n", func); @@ -1571,7 +1571,7 @@ static void rna_def_property_funcs_header(FILE *f, StructRNA *srna, PropertyDefR } else if (prop->arraydimension && prop->totarraylength) { fprintf(f, "void %sget(PointerRNA *ptr, float values[%u]);\n", func, prop->totarraylength); - fprintf(f, "void %sset(PointerRNA *ptr, const float values[%d]);\n", func, prop->totarraylength); + fprintf(f, "void %sset(PointerRNA *ptr, const float values[%u]);\n", func, prop->totarraylength); } else { fprintf(f, "void %sget(PointerRNA *ptr, float values[]);\n", func); @@ -3446,7 +3446,7 @@ static const char *cpp_classes = "" " inline void sname::identifier(int value) { sname##_##identifier##_set(&ptr, value); }\n" "\n" "#define BOOLEAN_ARRAY_PROPERTY(sname, size, identifier) \\\n" -" inline Array<int,size> sname::identifier(void) \\\n" +" inline Array<int, size> sname::identifier(void) \\\n" " { Array<int, size> ar; sname##_##identifier##_get(&ptr, ar.data); return ar; } \\\n" " inline void sname::identifier(int values[size]) \\\n" " { sname##_##identifier##_set(&ptr, values); } \\\n" @@ -3466,7 +3466,7 @@ static const char *cpp_classes = "" " inline void sname::identifier(int value) { sname##_##identifier##_set(&ptr, value); }\n" "\n" "#define INT_ARRAY_PROPERTY(sname, size, identifier) \\\n" -" inline Array<int,size> sname::identifier(void) \\\n" +" inline Array<int, size> sname::identifier(void) \\\n" " { Array<int, size> ar; sname##_##identifier##_get(&ptr, ar.data); return ar; } \\\n" " inline void sname::identifier(int values[size]) \\\n" " { sname##_##identifier##_set(&ptr, values); } \\\n" @@ -3486,7 +3486,7 @@ static const char *cpp_classes = "" " inline void sname::identifier(float value) { sname##_##identifier##_set(&ptr, value); }\n" "\n" "#define FLOAT_ARRAY_PROPERTY(sname, size, identifier) \\\n" -" inline Array<float,size> sname::identifier(void) \\\n" +" inline Array<float, size> sname::identifier(void) \\\n" " { Array<float, size> ar; sname##_##identifier##_get(&ptr, ar.data); return ar; } \\\n" " inline void sname::identifier(float values[size]) \\\n" " { sname##_##identifier##_set(&ptr, values); } \\\n" @@ -3695,7 +3695,7 @@ static const char *cpp_classes = "" " typename Tcollection_funcs>\n" "class Collection : public Tcollection_funcs {\n" "public:\n" -" Collection(const PointerRNA &p) : Tcollection_funcs(p), ptr(p) {}\n" +" Collection(const PointerRNA &p) : Tcollection_funcs(p), ptr(p) {}\n" "\n" " void begin(CollectionIterator<T, Tbegin, Tnext, Tend>& iter)\n" " { iter.begin(ptr); }\n" diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 341ba02fd47..6c216936190 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -290,9 +290,7 @@ static void rna_idproperty_free(PointerRNA *ptr, const char *name) if (group) { IDProperty *idprop = IDP_GetPropertyFromGroup(group, name); if (idprop) { - IDP_RemFromGroup(group, idprop); - IDP_FreeProperty(idprop); - MEM_freeN(idprop); + IDP_FreeFromGroup(group, idprop); } } } @@ -423,9 +421,7 @@ IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr) if (idprop && !rna_idproperty_verify_valid(ptr, *prop, idprop)) { IDProperty *group = RNA_struct_idprops(ptr, 0); - IDP_RemFromGroup(group, idprop); - IDP_FreeProperty(idprop); - MEM_freeN(idprop); + IDP_FreeFromGroup(group, idprop); return NULL; } @@ -596,9 +592,7 @@ bool RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier) if (group) { IDProperty *idp = IDP_GetPropertyFromGroup(group, identifier); if (idp) { - IDP_RemFromGroup(group, idp); - IDP_FreeProperty(idp); - MEM_freeN(idp); + IDP_FreeFromGroup(group, idp); return true; } @@ -2771,9 +2765,7 @@ void RNA_property_pointer_remove(PointerRNA *ptr, PropertyRNA *prop) group = RNA_struct_idprops(ptr, 0); if (group) { - IDP_RemFromGroup(group, idprop); - IDP_FreeProperty(idprop); - MEM_freeN(idprop); + IDP_FreeFromGroup(group, idprop); } } else @@ -4901,6 +4893,7 @@ int RNA_collection_length(PointerRNA *ptr, const char *name) bool RNA_property_is_set_ex(PointerRNA *ptr, PropertyRNA *prop, bool use_ghost) { + prop = rna_ensure_property(prop); if (prop->flag & PROP_IDPROPERTY) { IDProperty *idprop = rna_idproperty_find(ptr, prop->identifier); return ((idprop != NULL) && (use_ghost == false || !(idprop->flag & IDP_FLAG_GHOST))); @@ -4912,6 +4905,7 @@ bool RNA_property_is_set_ex(PointerRNA *ptr, PropertyRNA *prop, bool use_ghost) bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop) { + prop = rna_ensure_property(prop); if (prop->flag & PROP_IDPROPERTY) { IDProperty *idprop = rna_idproperty_find(ptr, prop->identifier); return ((idprop != NULL) && !(idprop->flag & IDP_FLAG_GHOST)); @@ -4923,6 +4917,7 @@ bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop) void RNA_property_unset(PointerRNA *ptr, PropertyRNA *prop) { + prop = rna_ensure_property(prop); if (prop->flag & PROP_IDPROPERTY) { rna_idproperty_free(ptr, prop->identifier); } @@ -4985,7 +4980,7 @@ bool RNA_property_is_unlink(PropertyRNA *prop) /* string representation of a property, python * compatible but can be used for display too, * context may be NULL */ -static char *rna_pointer_as_string__idprop(bContext *C, PointerRNA *ptr) +char *RNA_pointer_as_string_id(bContext *C, PointerRNA *ptr) { DynStr *dynstr = BLI_dynstr_new(); char *cstring; @@ -5036,7 +5031,7 @@ static char *rna_pointer_as_string__bldata(PointerRNA *ptr) char *RNA_pointer_as_string(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *prop_ptr, PointerRNA *ptr_prop) { if (RNA_property_flag(prop_ptr) & PROP_IDPROPERTY) { - return rna_pointer_as_string__idprop(C, ptr_prop); + return RNA_pointer_as_string_id(C, ptr_prop); } else { return rna_pointer_as_string__bldata(ptr_prop); diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index bd4b8dd76b1..74fe3c145f1 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -38,6 +38,7 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "RNA_enum_types.h" #include "rna_internal.h" diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c index e13ec1f09a4..2a008a44b55 100644 --- a/source/blender/makesrna/intern/rna_dynamicpaint.c +++ b/source/blender/makesrna/intern/rna_dynamicpaint.c @@ -470,7 +470,7 @@ static void rna_def_canvas_surface(BlenderRNA *brna) prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "start_frame"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_range(prop, 1.0, 9999.0); + RNA_def_property_range(prop, 1.0, MAXFRAMEF); RNA_def_property_ui_range(prop, 1.0, 9999, 1, -1); RNA_def_property_ui_text(prop, "Start Frame", "Simulation start frame"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaintSurfaces_updateFrames"); @@ -478,7 +478,7 @@ static void rna_def_canvas_surface(BlenderRNA *brna) prop = RNA_def_property(srna, "frame_end", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "end_frame"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_range(prop, 1.0, 9999.0); + RNA_def_property_range(prop, 1.0, MAXFRAMEF); RNA_def_property_ui_range(prop, 1.0, 9999.0, 1, -1); RNA_def_property_ui_text(prop, "End Frame", "Simulation end frame"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaintSurfaces_updateFrames"); diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index 4b50127d999..2036257e5d7 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -453,28 +453,66 @@ static void rna_FCurve_modifiers_remove(FCurve *fcu, ReportList *reports, Pointe static void rna_FModifier_active_set(PointerRNA *ptr, int UNUSED(value)) { - FModifier *fm = (FModifier *)ptr->data; + FModifier *fcm = (FModifier *)ptr->data; /* don't toggle, always switch on */ - fm->flag |= FMODIFIER_FLAG_ACTIVE; + fcm->flag |= FMODIFIER_FLAG_ACTIVE; } -static void rna_FModifier_start_frame_range(PointerRNA *ptr, float *min, float *max, - float *UNUSED(softmin), float *UNUSED(softmax)) +static void rna_FModifier_start_frame_set(PointerRNA *ptr, float value) { FModifier *fcm = (FModifier *)ptr->data; - *min = MINAFRAMEF; - *max = (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) ? fcm->efra : MAXFRAMEF; + CLAMP(value, MINAFRAMEF, MAXFRAMEF); + fcm->sfra = value; + + /* XXX: maintain old offset? */ + if (fcm->sfra >= fcm->efra) { + fcm->efra = fcm->sfra; + } } -static void rna_FModifier_end_frame_range(PointerRNA *ptr, float *min, float *max, - float *UNUSED(softmin), float *UNUSED(softmax)) +static void rna_FModifer_end_frame_set(PointerRNA *ptr, float value) { FModifier *fcm = (FModifier *)ptr->data; + + CLAMP(value, MINAFRAMEF, MAXFRAMEF); + fcm->efra = value; + + /* XXX: maintain old offset? */ + if (fcm->efra <= fcm->sfra) { + fcm->sfra = fcm->efra; + } +} - *min = (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) ? fcm->sfra : MINAFRAMEF; - *max = MAXFRAMEF; +static void rna_FModifier_start_frame_range(PointerRNA *UNUSED(ptr), float *min, float *max, + float *UNUSED(softmin), float *UNUSED(softmax)) +{ + // FModifier *fcm = (FModifier *)ptr->data; + + /* Technically, "sfra <= efra" must hold; however, we can't strictly enforce that, + * or else it becomes tricky to adjust the range... [#36844] + * + * NOTE: we do not set soft-limits on lower bounds, as it's too confusing when you + * can't easily use the slider to set things here + */ + *min = MINAFRAMEF; + *max = MAXFRAMEF; +} + +static void rna_FModifier_end_frame_range(PointerRNA *ptr, float *min, float *max, + float *softmin, float *softmax) +{ + FModifier *fcm = (FModifier *)ptr->data; + + /* Technically, "sfra <= efra" must hold; however, we can't strictly enforce that, + * or else it becomes tricky to adjust the range... [#36844] + */ + *min = MINAFRAMEF; + *softmin = (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) ? fcm->sfra : MINAFRAMEF; + + *softmax = MAXFRAMEF; + *max = MAXFRAMEF; } static void rna_FModifier_blending_range(PointerRNA *ptr, float *min, float *max, @@ -527,44 +565,101 @@ static void rna_FModifierGenerator_coefficients_set(PointerRNA *ptr, const float memcpy(gen->coefficients, values, gen->arraysize * sizeof(float)); } -static void rna_FModifierLimits_minx_range(PointerRNA *ptr, float *min, float *max, - float *UNUSED(softmin), float *UNUSED(softmax)) + +static void rna_FModifierLimits_minx_set(PointerRNA *ptr, float value) { FModifier *fcm = (FModifier *)ptr->data; FMod_Limits *data = fcm->data; + + data->rect.xmin = value; + + if (data->rect.xmin >= data->rect.xmax) { + data->rect.xmax = data->rect.xmin; + } +} - *min = MINAFRAMEF; - *max = (data->flag & FCM_LIMIT_XMAX) ? data->rect.xmax : MAXFRAMEF; +static void rna_FModifierLimits_maxx_set(PointerRNA *ptr, float value) +{ + FModifier *fcm = (FModifier *)ptr->data; + FMod_Limits *data = fcm->data; + + data->rect.xmax = value; + + if (data->rect.xmax <= data->rect.xmin) { + data->rect.xmin = data->rect.xmax; + } } -static void rna_FModifierLimits_maxx_range(PointerRNA *ptr, float *min, float *max, - float *UNUSED(softmin), float *UNUSED(softmax)) +static void rna_FModifierLimits_miny_set(PointerRNA *ptr, float value) { FModifier *fcm = (FModifier *)ptr->data; FMod_Limits *data = fcm->data; + + data->rect.ymin = value; + + if (data->rect.ymin >= data->rect.ymax) { + data->rect.ymax = data->rect.ymin; + } +} - *min = (data->flag & FCM_LIMIT_XMIN) ? data->rect.xmin : MINAFRAMEF; - *max = MAXFRAMEF; +static void rna_FModifierLimits_maxy_set(PointerRNA *ptr, float value) +{ + FModifier *fcm = (FModifier *)ptr->data; + FMod_Limits *data = fcm->data; + + data->rect.ymax = value; + + if (data->rect.ymax <= data->rect.ymin) { + data->rect.ymin = data->rect.ymax; + } } -static void rna_FModifierLimits_miny_range(PointerRNA *ptr, float *min, float *max, +static void rna_FModifierLimits_minx_range(PointerRNA *UNUSED(ptr), float *min, float *max, float *UNUSED(softmin), float *UNUSED(softmax)) { + // FModifier *fcm = (FModifier *)ptr->data; + // FMod_Limits *data = fcm->data; + + /* no soft-limits on lower bound - it's too confusing when you can't easily use the slider to set things here */ + *min = MINAFRAMEF; + *max = MAXFRAMEF; +} + +static void rna_FModifierLimits_maxx_range(PointerRNA *ptr, float *min, float *max, + float *softmin, float *softmax) +{ FModifier *fcm = (FModifier *)ptr->data; FMod_Limits *data = fcm->data; + + *min = MINAFRAMEF; + *softmin = (data->flag & FCM_LIMIT_XMIN) ? data->rect.xmin : MINAFRAMEF; + + *softmax = MAXFRAMEF; + *max = MAXFRAMEF; +} - *min = -FLT_MAX; - *max = (data->flag & FCM_LIMIT_YMAX) ? data->rect.ymax : FLT_MAX; +static void rna_FModifierLimits_miny_range(PointerRNA *UNUSED(ptr), float *min, float *max, + float *UNUSED(softmin), float *UNUSED(softmax)) +{ + // FModifier *fcm = (FModifier *)ptr->data; + // FMod_Limits *data = fcm->data; + + /* no soft-limits on lower bound - it's too confusing when you can't easily use the slider to set things here */ + *min = -FLT_MAX; + *max = FLT_MAX; } static void rna_FModifierLimits_maxy_range(PointerRNA *ptr, float *min, float *max, - float *UNUSED(softmin), float *UNUSED(softmax)) + float *softmin, float *softmax) { FModifier *fcm = (FModifier *)ptr->data; FMod_Limits *data = fcm->data; - - *min = (data->flag & FCM_LIMIT_YMIN) ? data->rect.ymin : -FLT_MAX; - *max = FLT_MAX; + + *min = -FLT_MAX; + *softmin = (data->flag & FCM_LIMIT_YMIN) ? data->rect.ymin : -FLT_MAX; + + *softmax = FLT_MAX; + *max = FLT_MAX; } @@ -1008,25 +1103,25 @@ static void rna_def_fmodifier_limits(BlenderRNA *brna) prop = RNA_def_property(srna, "min_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rect.xmin"); - RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifierLimits_minx_range"); + RNA_def_property_float_funcs(prop, NULL, "rna_FModifierLimits_minx_set", "rna_FModifierLimits_minx_range"); RNA_def_property_ui_text(prop, "Minimum X", "Lowest X value to allow"); RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); prop = RNA_def_property(srna, "min_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rect.ymin"); - RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifierLimits_miny_range"); + RNA_def_property_float_funcs(prop, NULL, "rna_FModifierLimits_miny_set", "rna_FModifierLimits_miny_range"); RNA_def_property_ui_text(prop, "Minimum Y", "Lowest Y value to allow"); RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); prop = RNA_def_property(srna, "max_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rect.xmax"); - RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifierLimits_maxx_range"); + RNA_def_property_float_funcs(prop, NULL, "rna_FModifierLimits_maxx_set", "rna_FModifierLimits_maxx_range"); RNA_def_property_ui_text(prop, "Maximum X", "Highest X value to allow"); RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); prop = RNA_def_property(srna, "max_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rect.ymax"); - RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifierLimits_maxy_range"); + RNA_def_property_float_funcs(prop, NULL, "rna_FModifierLimits_maxy_set", "rna_FModifierLimits_maxy_range"); RNA_def_property_ui_text(prop, "Maximum Y", "Highest Y value to allow"); RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); } @@ -1191,14 +1286,14 @@ static void rna_def_fmodifier(BlenderRNA *brna) prop = RNA_def_property(srna, "frame_start", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "sfra"); - RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifier_start_frame_range"); + RNA_def_property_float_funcs(prop, NULL, "rna_FModifier_start_frame_set", "rna_FModifier_start_frame_range"); RNA_def_property_ui_text(prop, "Start Frame", "Frame that modifier's influence starts (if Restrict Frame Range is in use)"); RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, NULL); prop = RNA_def_property(srna, "frame_end", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "efra"); - RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifier_end_frame_range"); + RNA_def_property_float_funcs(prop, NULL, "rna_FModifer_end_frame_set", "rna_FModifier_end_frame_range"); RNA_def_property_ui_text(prop, "End Frame", "Frame that modifier's influence ends (if Restrict Frame Range is in use)"); RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, NULL); diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c index b18c21d53f1..9007baa9dad 100644 --- a/source/blender/makesrna/intern/rna_fluidsim.c +++ b/source/blender/makesrna/intern/rna_fluidsim.c @@ -122,7 +122,7 @@ static void rna_FluidSettings_update_type(Main *bmain, Scene *scene, PointerRNA Object *ob = (Object *)ptr->id.data; FluidsimModifierData *fluidmd; ParticleSystemModifierData *psmd; - ParticleSystem *psys; + ParticleSystem *psys, *next_psys; ParticleSettings *part; fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim); @@ -155,7 +155,8 @@ static void rna_FluidSettings_update_type(Main *bmain, Scene *scene, PointerRNA } } else { - for (psys = ob->particlesystem.first; psys; psys = psys->next) { + for (psys = ob->particlesystem.first; psys; psys = next_psys) { + next_psys = psys->next; if (psys->part->type == PART_FLUID) { /* clear modifier */ psmd = psys_get_modifier(ob, psys); diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c index a20cb73b3aa..6d6f516ecac 100644 --- a/source/blender/makesrna/intern/rna_key.c +++ b/source/blender/makesrna/intern/rna_key.c @@ -405,7 +405,7 @@ static KeyBlock *rna_ShapeKeyData_find_keyblock(Key *key, float *point) } /* determine where end of array is - * - elemsize is in bytes, so use char* cast to get array in terms of bytes + * - elemsize is in bytes, so use (char *) cast to get array in terms of bytes */ end = (float *)((char *)start + (key->elemsize * kb->totelem)); @@ -422,7 +422,7 @@ static KeyBlock *rna_ShapeKeyData_find_keyblock(Key *key, float *point) static int rna_ShapeKeyPoint_get_index(Key *key, KeyBlock *kb, float *point) { - /* if we frame the data array and point pointers as char*, then the difference between + /* if we frame the data array and point pointers as (char *), then the difference between * them will be in bytes. Thus, dividing through by key->elemsize (number of bytes per point) * gives us the offset of point from start of array. */ diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index 77d593b67b6..670df017038 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -446,7 +446,7 @@ static void rna_MaskSpline_points_add(ID *id, MaskSpline *spline, int count) BKE_mask_parent_init(&new_point->parent); /* Not efficient, but there's no other way for now */ - BKE_mask_layer_shape_changed_add(layer, spline_shape_index + point_index, TRUE, TRUE); + BKE_mask_layer_shape_changed_add(layer, spline_shape_index + point_index, true, true); } WM_main_add_notifier(NC_MASK | ND_DATA, mask); diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 34f138cd7c5..eee7692e2ed 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -109,6 +109,22 @@ EnumPropertyItem modifier_type_items[] = { {0, NULL, 0, NULL, NULL} }; +EnumPropertyItem modifier_triangulate_quad_method_items[] = { + {MOD_TRIANGULATE_QUAD_BEAUTY, "BEAUTY", 0, "Beauty ", "Split the quads in nice triangles, slower method"}, + {MOD_TRIANGULATE_QUAD_FIXED, "FIXED", 0, "Fixed", "Split the quads on the first and third vertices"}, + {MOD_TRIANGULATE_QUAD_ALTERNATE, "FIXED_ALTERNATE", 0, "Fixed Alternate", + "Split the quads on the 2nd and 4th vertices"}, + {MOD_TRIANGULATE_QUAD_SHORTEDGE, "SHORTEST_DIAGONAL", 0, "Shortest Diagonal", + "Split the quads based on the distance between the vertices"}, + {0, NULL, 0, NULL, NULL} +}; + +EnumPropertyItem modifier_triangulate_ngon_method_items[] = { + {MOD_TRIANGULATE_NGON_SCANFILL, "SCANFILL", 0, "Scanfill", "Split the polygons using a scanfill algorithm"}, + {MOD_TRIANGULATE_NGON_BEAUTY, "BEAUTY", 0, "Beauty", "Arrange the new triangles nicely, slower method"}, + {0, NULL, 0, NULL, NULL} +}; + #ifdef RNA_RUNTIME #include "DNA_particle_types.h" @@ -118,6 +134,7 @@ EnumPropertyItem modifier_type_items[] = { #include "BKE_depsgraph.h" #include "BKE_library.h" #include "BKE_modifier.h" +#include "BKE_object.h" #include "BKE_particle.h" static void rna_UVProject_projectors_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) @@ -536,6 +553,14 @@ static int rna_MultiresModifier_filepath_length(PointerRNA *ptr) return strlen((external) ? external->filename : ""); } +static void rna_HookModifier_object_set(PointerRNA *ptr, PointerRNA value) +{ + HookModifierData *hmd = ptr->data; + + hmd->object = (Object *)value.data; + BKE_object_modifier_hook_reset((Object *)ptr->id.data, hmd); +} + static void modifier_object_set(Object *self, Object **ob_p, int type, PointerRNA value) { Object *ob = value.data; @@ -1434,6 +1459,7 @@ static void rna_def_modifier_hook(BlenderRNA *brna) prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); RNA_def_property_ui_text(prop, "Object", "Parent Object for hook, also recalculates and clears offset"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK); + RNA_def_property_pointer_funcs(prop, NULL, "rna_HookModifier_object_set", NULL, NULL); RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE); @@ -3490,9 +3516,16 @@ static void rna_def_modifier_triangulate(BlenderRNA *brna) RNA_def_struct_sdna(srna, "TriangulateModifierData"); RNA_def_struct_ui_icon(srna, ICON_MOD_TRIANGULATE); - prop = RNA_def_property(srna, "use_beauty", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_TRIANGULATE_BEAUTY); - RNA_def_property_ui_text(prop, "Beauty Subdivide", "Subdivide across shortest diagonal"); + prop = RNA_def_property(srna, "quad_method", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "quad_method"); + RNA_def_property_enum_items(prop, modifier_triangulate_quad_method_items); + RNA_def_property_ui_text(prop, "Quad Method", "Method for splitting the quads into triangles"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "ngon_method", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "ngon_method"); + RNA_def_property_enum_items(prop, modifier_triangulate_ngon_method_items); + RNA_def_property_ui_text(prop, "Polygon Method", "Method for splitting the polygons into triangles"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); } diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index bb8e8d87252..6b5bced75bd 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1280,6 +1280,29 @@ static void rna_Node_draw_buttons_ext(struct uiLayout *layout, bContext *C, Poin RNA_parameter_list_free(&list); } +static void rna_Node_draw_label(bNodeTree *ntree, bNode *node, char *label, int maxlen) +{ + extern FunctionRNA rna_Node_draw_label_func; + + PointerRNA ptr; + ParameterList list; + FunctionRNA *func; + void *ret; + char *rlabel; + + func = &rna_Node_draw_label_func; /* RNA_struct_find_function(&ptr, "draw_label"); */ + + RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); + RNA_parameter_list_create(&list, &ptr, func); + node->typeinfo->ext.call(NULL, &ptr, func, &list); + + RNA_parameter_get_lookup(&list, "label", &ret); + rlabel = *(char **)ret; + BLI_strncpy(label, rlabel != NULL ? rlabel : "", maxlen); + + RNA_parameter_list_free(&list); +} + static int rna_Node_is_registered_node_type(StructRNA *type) { return (RNA_struct_blender_type_get(type) != NULL); @@ -1321,7 +1344,7 @@ static bNodeType *rna_Node_register_base(Main *bmain, ReportList *reports, Struc PointerRNA dummyptr; FunctionRNA *func; PropertyRNA *parm; - int have_function[8]; + int have_function[9]; /* setup dummy node & node type to store static properties in */ memset(&dummynt, 0, sizeof(bNodeType)); @@ -1379,6 +1402,7 @@ static bNodeType *rna_Node_register_base(Main *bmain, ReportList *reports, Struc nt->freefunc_api = (have_function[5]) ? rna_Node_free : NULL; nt->draw_buttons = (have_function[6]) ? rna_Node_draw_buttons : NULL; nt->draw_buttons_ex = (have_function[7]) ? rna_Node_draw_buttons_ext : NULL; + nt->labelfunc = (have_function[8]) ? rna_Node_draw_label : NULL; /* sanitize size values in case not all have been registered */ if (nt->maxwidth < nt->minwidth) @@ -2693,6 +2717,18 @@ static PointerRNA rna_NodeOutputFile_slot_file_get(CollectionPropertyIterator *i return ptr; } +static void rna_NodeColorBalance_update_lgg(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + ntreeCompositColorBalanceSyncFromLGG(ptr->id.data, ptr->data); + rna_Node_update(bmain, scene, ptr); +} + +static void rna_NodeColorBalance_update_cdl(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + ntreeCompositColorBalanceSyncFromCDL(ptr->id.data, ptr->data); + rna_Node_update(bmain, scene, ptr); +} + /* ******** Node Socket Types ******** */ static PointerRNA rna_NodeOutputFile_slot_layer_get(CollectionPropertyIterator *iter) @@ -3256,6 +3292,7 @@ static void def_sh_tex_sky(StructRNA *srna) {SHD_SKY_NEW, "HOSEK_WILKIE", 0, "Hosek / Wilkie", ""}, {0, NULL, 0, NULL, NULL} }; + static float default_dir[3] = {0.0f, 0.0f, 1.0f}; PropertyRNA *prop; @@ -3270,6 +3307,8 @@ static void def_sh_tex_sky(StructRNA *srna) prop = RNA_def_property(srna, "sun_direction", PROP_FLOAT, PROP_DIRECTION); RNA_def_property_ui_text(prop, "Sun Direction", "Direction from where the sun is shining"); + RNA_def_property_array(prop, 3); + RNA_def_property_float_array_default(prop, default_dir); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); prop = RNA_def_property(srna, "turbidity", PROP_FLOAT, PROP_NONE); @@ -4343,7 +4382,7 @@ static void def_cmp_despeckle(StructRNA *srna) RNA_def_property_ui_text(prop, "Threshold", "Threshold for detecting pixels to despeckle"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); - prop = RNA_def_property(srna, "threshold_neighbour", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "threshold_neighbor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "custom4"); RNA_def_property_range(prop, 0.0, 1.0f); RNA_def_property_ui_text(prop, "Neighbor", "Threshold for the number of neighbor pixels that must match"); @@ -5233,7 +5272,7 @@ static void def_cmp_colorbalance(StructRNA *srna) RNA_def_property_float_array_default(prop, default_1); RNA_def_property_ui_range(prop, 0, 2, 0.1, 3); RNA_def_property_ui_text(prop, "Lift", "Correction for Shadows"); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeColorBalance_update_lgg"); prop = RNA_def_property(srna, "gamma", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "gamma"); @@ -5241,7 +5280,7 @@ static void def_cmp_colorbalance(StructRNA *srna) RNA_def_property_float_array_default(prop, default_1); RNA_def_property_ui_range(prop, 0, 2, 0.1, 3); RNA_def_property_ui_text(prop, "Gamma", "Correction for Midtones"); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeColorBalance_update_lgg"); prop = RNA_def_property(srna, "gain", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "gain"); @@ -5249,33 +5288,33 @@ static void def_cmp_colorbalance(StructRNA *srna) RNA_def_property_float_array_default(prop, default_1); RNA_def_property_ui_range(prop, 0, 2, 0.1, 3); RNA_def_property_ui_text(prop, "Gain", "Correction for Highlights"); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeColorBalance_update_lgg"); prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_float_sdna(prop, NULL, "lift"); + RNA_def_property_float_sdna(prop, NULL, "offset"); RNA_def_property_array(prop, 3); RNA_def_property_ui_range(prop, 0, 1, 0.1, 3); RNA_def_property_ui_text(prop, "Offset", "Correction for Shadows"); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeColorBalance_update_cdl"); prop = RNA_def_property(srna, "power", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_float_sdna(prop, NULL, "gamma"); + RNA_def_property_float_sdna(prop, NULL, "power"); RNA_def_property_array(prop, 3); RNA_def_property_float_array_default(prop, default_1); RNA_def_property_range(prop, 0.f, FLT_MAX); RNA_def_property_ui_range(prop, 0, 2, 0.1, 3); RNA_def_property_ui_text(prop, "Power", "Correction for Midtones"); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeColorBalance_update_cdl"); prop = RNA_def_property(srna, "slope", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_float_sdna(prop, NULL, "gain"); + RNA_def_property_float_sdna(prop, NULL, "slope"); RNA_def_property_array(prop, 3); RNA_def_property_float_array_default(prop, default_1); RNA_def_property_range(prop, 0.f, FLT_MAX); RNA_def_property_ui_range(prop, 0, 2, 0.1, 3); RNA_def_property_ui_text(prop, "Slope", "Correction for Highlights"); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeColorBalance_update_cdl"); } static void def_cmp_huecorrect(StructRNA *srna) @@ -7134,6 +7173,14 @@ static void rna_def_node(BlenderRNA *brna) RNA_def_property_struct_type(parm, "UILayout"); RNA_def_property_ui_text(parm, "Layout", "Layout in the UI"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + + /* dynamic label */ + func = RNA_def_function(srna, "draw_label", NULL); + RNA_def_function_ui_description(func, "Returns a dynamic label string"); + RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); + parm = RNA_def_string(func, "label", "", MAX_NAME, "Label", ""); + RNA_def_property_flag(parm, PROP_THICK_WRAP); /* needed for string return value */ + RNA_def_function_output(func, parm); } static void rna_def_node_link(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 33ae256c042..2a93925a8e5 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -517,21 +517,9 @@ static void rna_FieldSettings_shape_update(Main *bmain, Scene *scene, PointerRNA { if (!particle_id_check(ptr)) { Object *ob = (Object *)ptr->id.data; - PartDeflect *pd = ob->pd; - ModifierData *md = modifiers_findByType(ob, eModifierType_Surface); - - /* add/remove modifier as needed */ - if (!md) { - if (pd && (pd->shape == PFIELD_SHAPE_SURFACE) && ELEM(pd->forcefield, PFIELD_GUIDE, PFIELD_TEXTURE) == 0) - if (ELEM4(ob->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVE)) - ED_object_modifier_add(NULL, bmain, scene, ob, NULL, eModifierType_Surface); - } - else { - if (!pd || pd->shape != PFIELD_SHAPE_SURFACE) - ED_object_modifier_remove(NULL, bmain, ob, md); - } - + ED_object_check_force_modifiers(bmain, scene, ob); WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob); + WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob); } } diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 8dafe54e678..5151310cd64 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -2718,7 +2718,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "brownfac"); RNA_def_property_range(prop, 0.0f, 200.0f); RNA_def_property_ui_range(prop, 0, 20, 1, 3); - RNA_def_property_ui_text(prop, "Brownian", "Amount of Brownian motion"); + RNA_def_property_ui_text(prop, "Brownian", "Amount of random, erratic particle movement"); RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop = RNA_def_property(srna, "damping", PROP_FLOAT, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 7ebbcf7b39b..1cd27e27f01 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -395,7 +395,7 @@ static void rna_def_render_engine(BlenderRNA *brna) RNA_def_boolean(func, "cancel", 0, "Cancel", "Don't merge back results"); func = RNA_def_function(srna, "test_break", "RE_engine_test_break"); - RNA_def_function_ui_description(func, "Test if the render operation should been cancelled, this is a fast call that should be used regularly for responsiveness"); + RNA_def_function_ui_description(func, "Test if the render operation should been canceled, this is a fast call that should be used regularly for responsiveness"); prop = RNA_def_boolean(func, "do_break", 0, "Break", ""); RNA_def_function_return(func, prop); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 4d35acc84a0..686672e1629 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -145,7 +145,7 @@ EnumPropertyItem snap_element_items[] = { }; EnumPropertyItem snap_node_element_items[] = { - {SCE_SNAP_MODE_INCREMENT, "INCREMENT", ICON_SNAP_INCREMENT, "Increment", "Snap to increments of grid"}, + {SCE_SNAP_MODE_GRID, "GRID", ICON_SNAP_INCREMENT, "Grid", "Snap to grid"}, {SCE_SNAP_MODE_NODE_X, "NODE_X", ICON_SNAP_EDGE, "Node X", "Snap to left/right node border"}, {SCE_SNAP_MODE_NODE_Y, "NODE_Y", ICON_SNAP_EDGE, "Node Y", "Snap to top/bottom node border"}, {SCE_SNAP_MODE_NODE_XY, "NODE_XY", ICON_SNAP_EDGE, "Node X / Y", "Snap to any node border"}, @@ -159,7 +159,7 @@ EnumPropertyItem snap_uv_element_items[] = { }; /* workaround for duplicate enums, - * have each enum line as a defne then conditionally set it or not + * have each enum line as a define then conditionally set it or not */ #define R_IMF_ENUM_BMP {R_IMF_IMTYPE_BMP, "BMP", ICON_FILE_IMAGE, "BMP", "Output image in bitmap format"}, @@ -219,14 +219,6 @@ EnumPropertyItem snap_uv_element_items[] = { # define R_IMF_ENUM_TIFF #endif -#ifdef WITH_OPENIMAGEIO -# define R_IMF_ENUM_PSD {R_IMF_IMTYPE_PSD, "PSD", ICON_FILE_IMAGE, "Photosp PSD", \ - "Output image in Photoshop PSD format"}, -#else -# define R_IMF_ENUM_PSD -#endif - - #define IMAGE_TYPE_ITEMS_IMAGE_ONLY \ R_IMF_ENUM_BMP \ /* DDS save not supported yet R_IMF_ENUM_DDS */ \ @@ -243,7 +235,6 @@ EnumPropertyItem snap_uv_element_items[] = { R_IMF_ENUM_EXR \ R_IMF_ENUM_HDR \ R_IMF_ENUM_TIFF \ - R_IMF_ENUM_PSD \ EnumPropertyItem image_only_type_items[] = { @@ -270,11 +261,7 @@ EnumPropertyItem image_type_items[] = { {R_IMF_IMTYPE_THEORA, "THEORA", ICON_FILE_MOVIE, "Ogg Theora", "Output video in Ogg format"}, #endif #ifdef WITH_QUICKTIME -# ifdef USE_QTKIT - {R_IMF_IMTYPE_QUICKTIME, "QUICKTIME_QTKIT", ICON_FILE_MOVIE, "QuickTime", "Output video in Quicktime format"}, -# else - {R_IMF_IMTYPE_QUICKTIME, "QUICKTIME_CARBON", ICON_FILE_MOVIE, "QuickTime", "Output video in Quicktime format"}, -# endif + {R_IMF_IMTYPE_QUICKTIME, "QUICKTIME", ICON_FILE_MOVIE, "QuickTime", "Output video in Quicktime format"}, #endif #ifdef WITH_FFMPEG {R_IMF_IMTYPE_XVID, "XVID", ICON_FILE_MOVIE, "Xvid", "Output video in Xvid format"}, @@ -964,7 +951,6 @@ static EnumPropertyItem *rna_RenderSettings_qtcodecsettings_codecType_itemf(bCon return item; } -#ifdef USE_QTKIT static int rna_RenderSettings_qtcodecsettings_audiocodecType_get(PointerRNA *ptr) { QuicktimeCodecSettings *settings = (QuicktimeCodecSettings *)ptr->data; @@ -1003,7 +989,6 @@ static EnumPropertyItem *rna_RenderSettings_qtcodecsettings_audiocodecType_itemf return item; } #endif -#endif #ifdef WITH_FFMPEG static void rna_FFmpegSettings_lossless_output_set(PointerRNA *ptr, int value) @@ -1452,6 +1437,12 @@ static KeyingSet *rna_Scene_keying_set_new(Scene *sce, ReportList *reports, cons } } +static void rna_UnifiedPaintSettings_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr)) +{ + Brush *br = BKE_paint_brush(BKE_paint_get_active(scene)); + WM_main_add_notifier(NC_BRUSH | NA_EDITED, br); +} + static void rna_UnifiedPaintSettings_size_set(PointerRNA *ptr, int value) { UnifiedPaintSettings *ups = ptr->data; @@ -1471,10 +1462,11 @@ static void rna_UnifiedPaintSettings_unprojected_radius_set(PointerRNA *ptr, flo ups->unprojected_radius = value; } -static void rna_UnifiedPaintSettings_radius_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) +static void rna_UnifiedPaintSettings_radius_update(Main *bmain, Scene *scene, PointerRNA *ptr) { - /* changing the unified size should invalidate */ + /* changing the unified size should invalidate the overlay but also update the brush */ BKE_paint_invalidate_overlay_all(); + rna_UnifiedPaintSettings_update(bmain, scene, ptr); } static char *rna_UnifiedPaintSettings_path(PointerRNA *UNUSED(ptr)) @@ -2045,6 +2037,7 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna) RNA_def_property_range(prop, 0.0f, 10.0f); RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.001, 3); RNA_def_property_ui_text(prop, "Strength", "How powerful the effect of the brush is when applied"); + RNA_def_property_update(prop, 0, "rna_UnifiedPaintSettings_update"); prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "weight"); @@ -2052,6 +2045,7 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna) RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.001, 3); RNA_def_property_ui_text(prop, "Weight", "Weight to assign in vertex groups"); + RNA_def_property_update(prop, 0, "rna_UnifiedPaintSettings_update"); prop = RNA_def_property(srna, "use_pressure_size", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", UNIFIED_PAINT_BRUSH_SIZE_PRESSURE); @@ -2329,12 +2323,6 @@ void rna_def_render_layer_common(StructRNA *srna, int scene) if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); else RNA_def_property_clear_flag(prop, PROP_EDITABLE); - prop = RNA_def_property(srna, "use_edge_enhance", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "layflag", SCE_LAY_EDGE); - RNA_def_property_ui_text(prop, "Edge", "Render Edge-enhance in this Layer (only works for Solid faces)"); - if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - else RNA_def_property_clear_flag(prop, PROP_EDITABLE); - prop = RNA_def_property(srna, "use_strand", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "layflag", SCE_LAY_STRAND); RNA_def_property_ui_text(prop, "Strand", "Render Strands in this Layer"); @@ -3143,7 +3131,6 @@ static void rna_def_scene_game_data(BlenderRNA *brna) }; static EnumPropertyItem material_items[] = { - {GAME_MAT_TEXFACE, "SINGLETEXTURE", 0, "Singletexture", "Singletexture face materials"}, {GAME_MAT_MULTITEX, "MULTITEXTURE", 0, "Multitexture", "Multitexture materials"}, {GAME_MAT_GLSL, "GLSL", 0, "GLSL", "OpenGL shading language shaders"}, {0, NULL, 0, NULL, NULL} @@ -3435,7 +3422,8 @@ static void rna_def_scene_game_data(BlenderRNA *brna) prop = RNA_def_property(srna, "use_frame_rate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GAME_ENABLE_ALL_FRAMES); RNA_def_property_ui_text(prop, "Use Frame Rate", - "Respect the frame rate rather than rendering as many frames as possible"); + "Respect the frame rate from the Physics panel in the world properties " + "rather than rendering as many frames as possible"); prop = RNA_def_property(srna, "use_display_lists", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GAME_DISPLAY_LISTS); @@ -3783,8 +3771,6 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna) {FFMPEG_OGG, "OGG", 0, "Ogg", ""}, {FFMPEG_MKV, "MKV", 0, "Matroska", ""}, {FFMPEG_FLV, "FLASH", 0, "Flash", ""}, - {FFMPEG_WAV, "WAV", 0, "Wav", ""}, - {FFMPEG_MP3, "MP3", 0, "Mp3", ""}, {0, NULL, 0, NULL, NULL} }; @@ -3955,7 +3941,6 @@ static void rna_def_scene_quicktime_settings(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; -#ifdef USE_QTKIT static EnumPropertyItem quicktime_audio_samplerate_items[] = { {22050, "22050", 0, "22kHz", ""}, {44100, "44100", 0, "44.1kHz", ""}, @@ -3985,7 +3970,6 @@ static void rna_def_scene_quicktime_settings(BlenderRNA *brna) {320000, "320000", 0, "320kbps", ""}, {0, NULL, 0, NULL, NULL} }; -#endif /* QuickTime */ srna = RNA_def_struct(brna, "QuickTimeSettings", NULL); @@ -4007,7 +3991,6 @@ static void rna_def_scene_quicktime_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Spatial quality", "Intra-frame spatial quality level"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); -#ifdef USE_QTKIT prop = RNA_def_property(srna, "audiocodec_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "audiocodecType"); RNA_def_property_enum_items(prop, quicktime_codec_type_items); @@ -4044,7 +4027,6 @@ static void rna_def_scene_quicktime_settings(BlenderRNA *brna) RNA_def_property_enum_items(prop, quicktime_audio_bitrate_items); RNA_def_property_ui_text(prop, "Bitrate", "Compressed audio bitrate"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); -#endif } #endif @@ -4384,23 +4366,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Textures", "Use textures to affect material properties"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - prop = RNA_def_property(srna, "use_edge_enhance", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", R_EDGE); - RNA_def_property_ui_text(prop, "Edge", "Create a toon outline around the edges of geometry"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - - prop = RNA_def_property(srna, "edge_threshold", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "edgeint"); - RNA_def_property_range(prop, 0, 255); - RNA_def_property_ui_text(prop, "Edge Threshold", "Threshold for drawing outlines on geometry edges"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - - prop = RNA_def_property(srna, "edge_color", PROP_FLOAT, PROP_COLOR); - RNA_def_property_float_sdna(prop, NULL, "edgeR"); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Edge Color", "Edge color"); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); - prop = RNA_def_property(srna, "use_freestyle", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_EDGE_FRS); RNA_def_property_ui_text(prop, "Edge", "Draw stylized strokes using Freestyle"); @@ -5220,6 +5185,14 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Current Frame Final", "Current frame with subframe and time remapping applied"); + prop = RNA_def_property(srna, "lock_frame_selection_to_range", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_boolean_sdna(prop, NULL, "r.flag", SCER_LOCK_FRAME_SELECTION); + RNA_def_property_ui_text(prop, "Lock Frame Selection", + "Don't allow frame to be selected with mouse outside of frame range"); + RNA_def_property_update(prop, NC_SCENE | ND_FRAME, NULL); + RNA_def_property_ui_icon(prop, ICON_LOCKED, 0); + /* Preview Range (frame-range for UI playback) */ prop = RNA_def_property(srna, "use_preview_range", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 89714e49ebf..a9f84f1dcc7 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -340,36 +340,44 @@ static void rna_def_sculpt(BlenderRNA *brna) prop = RNA_def_property(srna, "use_symmetry_x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_SYMM_X); RNA_def_property_ui_text(prop, "Symmetry X", "Mirror brush across the X axis"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "use_symmetry_y", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_SYMM_Y); RNA_def_property_ui_text(prop, "Symmetry Y", "Mirror brush across the Y axis"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "use_symmetry_z", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_SYMM_Z); RNA_def_property_ui_text(prop, "Symmetry Z", "Mirror brush across the Z axis"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "lock_x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_LOCK_X); RNA_def_property_ui_text(prop, "Lock X", "Disallow changes to the X axis of vertices"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "lock_y", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_LOCK_Y); RNA_def_property_ui_text(prop, "Lock Y", "Disallow changes to the Y axis of vertices"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "lock_z", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_LOCK_Z); RNA_def_property_ui_text(prop, "Lock Z", "Disallow changes to the Z axis of vertices"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "use_symmetry_feather", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_SYMMETRY_FEATHER); RNA_def_property_ui_text(prop, "Symmetry Feathering", "Reduce the strength of the brush where it overlaps symmetrical daubs"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "use_threaded", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_USE_OPENMP); RNA_def_property_ui_text(prop, "Use OpenMP", "Take advantage of multiple CPU cores to improve sculpting performance"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "use_deform_only", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_ONLY_DEFORM); @@ -400,6 +408,7 @@ static void rna_def_sculpt(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Collapse Short Edges", "In dynamic-topology mode, collapse short edges " "in addition to subdividing long ones"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "symmetrize_direction", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, symmetrize_direction_items); @@ -432,19 +441,23 @@ static void rna_def_vertex_paint(BlenderRNA *brna) prop = RNA_def_property(srna, "use_all_faces", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", VP_AREA); RNA_def_property_ui_text(prop, "All Faces", "Paint on all faces inside brush"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "use_normal", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", VP_NORMALS); RNA_def_property_ui_text(prop, "Normals", "Apply the vertex normal before painting"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "use_spray", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", VP_SPRAY); RNA_def_property_ui_text(prop, "Spray", "Keep applying paint effect while holding mouse"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* weight paint only */ prop = RNA_def_property(srna, "use_group_restrict", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", VP_ONLYVGROUP); RNA_def_property_ui_text(prop, "Restrict", "Restrict painting to vertices in the group"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); } static void rna_def_image_paint(BlenderRNA *brna) @@ -461,27 +474,33 @@ static void rna_def_image_paint(BlenderRNA *brna) prop = RNA_def_property(srna, "use_occlude", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_XRAY); RNA_def_property_ui_text(prop, "Occlude", "Only paint onto the faces directly under the brush (slower)"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "use_backface_culling", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_BACKFACE); RNA_def_property_ui_text(prop, "Cull", "Ignore faces pointing away from the view (faster)"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "use_normal_falloff", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_FLAT); RNA_def_property_ui_text(prop, "Normal", "Paint most on faces pointing towards the view"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "use_stencil_layer", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_LAYER_STENCIL); RNA_def_property_ui_text(prop, "Stencil Layer", "Set the mask layer from the UV map buttons"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "invert_stencil", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_LAYER_STENCIL_INV); RNA_def_property_ui_text(prop, "Invert", "Invert the stencil layer"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "use_clone_layer", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_LAYER_CLONE); RNA_def_property_ui_text(prop, "Clone Map", "Use another UV map as clone source, otherwise use the 3D cursor as the source"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* integers */ diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 73f0d33257c..cf6202f07c6 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -370,7 +370,7 @@ static void rna_View3D_CursorLocation_get(PointerRNA *ptr, float *values) View3D *v3d = (View3D *)(ptr->data); bScreen *sc = (bScreen *)ptr->id.data; Scene *scene = (Scene *)sc->scene; - const float *loc = give_cursor(scene, v3d); + const float *loc = ED_view3d_cursor3d_get(scene, v3d); copy_v3_v3(values, loc); } @@ -380,7 +380,7 @@ static void rna_View3D_CursorLocation_set(PointerRNA *ptr, const float *values) View3D *v3d = (View3D *)(ptr->data); bScreen *sc = (bScreen *)ptr->id.data; Scene *scene = (Scene *)sc->scene; - float *cursor = give_cursor(scene, v3d); + float *cursor = ED_view3d_cursor3d_get(scene, v3d); copy_v3_v3(cursor, values); } @@ -1212,7 +1212,8 @@ static int rna_SpaceNodeEditor_tree_type_poll(void *Cv, bNodeTreeType *type) else return TRUE; } -static EnumPropertyItem *rna_SpaceNodeEditor_tree_type_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) +static EnumPropertyItem *rna_SpaceNodeEditor_tree_type_itemf(bContext *C, PointerRNA *UNUSED(ptr), + PropertyRNA *UNUSED(prop), int *free) { return rna_node_tree_type_itemf(C, rna_SpaceNodeEditor_tree_type_poll, free); } @@ -1490,7 +1491,6 @@ static void rna_def_space_outliner(BlenderRNA *brna) {SO_LIBRARIES, "LIBRARIES", 0, "Blender File", "Display data of current file and linked libraries"}, {SO_DATABLOCKS, "DATABLOCKS", 0, "Datablocks", "Display all raw datablocks"}, {SO_USERDEF, "USER_PREFERENCES", 0, "User Preferences", "Display the user preference datablocks"}, - {SO_KEYMAP, "KEYMAPS", 0, "Key Maps", "Display keymap datablocks"}, {0, NULL, 0, NULL, NULL} }; @@ -1786,8 +1786,8 @@ static void rna_def_space_view3d(BlenderRNA *brna) prop = RNA_def_property(srna, "use_render_border", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_RENDER_BORDER); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Render Border", - "Use a region within the frame size for rendered viewport (when not viewing through the camera)"); + RNA_def_property_ui_text(prop, "Render Border", "Use a region within the frame size for rendered viewport " + "(when not viewing through the camera)"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "render_border_min_x", PROP_FLOAT, PROP_NONE); @@ -1833,7 +1833,8 @@ static void rna_def_space_view3d(BlenderRNA *brna) prop = RNA_def_property(srna, "viewport_shade", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "drawtype"); RNA_def_property_enum_items(prop, viewport_shade_items); - RNA_def_property_enum_funcs(prop, "rna_SpaceView3D_viewport_shade_get", NULL, "rna_SpaceView3D_viewport_shade_itemf"); + RNA_def_property_enum_funcs(prop, "rna_SpaceView3D_viewport_shade_get", NULL, + "rna_SpaceView3D_viewport_shade_itemf"); RNA_def_property_ui_text(prop, "Viewport Shading", "Method to display/shade objects in the 3D View"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_SpaceView3D_viewport_shade_update"); @@ -1950,6 +1951,11 @@ static void rna_def_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Backface Culling", "Use back face culling to hide the back side of faces"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "show_textured_shadeless", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHADELESS_TEX); + RNA_def_property_ui_text(prop, "Shadeless", "Show shadeless texture without lighting in textured draw mode"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "show_occlude_wire", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_OCCLUDE_WIRE); RNA_def_property_ui_text(prop, "Hidden Wire", "Use hidden wireframe display"); @@ -2070,6 +2076,7 @@ static void rna_def_space_view3d(BlenderRNA *brna) prop = RNA_def_property(srna, "tracks_draw_size", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, FLT_MAX); + RNA_def_property_ui_range(prop, 0, 5, 1, 3); RNA_def_property_float_sdna(prop, NULL, "bundle_size"); RNA_def_property_ui_text(prop, "Tracks Size", "Display size of tracks from reconstructed data"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); @@ -2881,6 +2888,19 @@ static void rna_def_space_graph(BlenderRNA *brna) RNA_def_property_boolean_funcs(prop, "rna_SpaceGraphEditor_has_ghost_curves_get", NULL); RNA_def_property_ui_text(prop, "Has Ghost Curves", "Graph Editor instance has some ghost curves stored"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL); + + /* nromalize curves */ + prop = RNA_def_property(srna, "use_normalization", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SIPO_NORMALIZE); + RNA_def_property_ui_text(prop, "Use Normalization", "Display curves in normalized to -1..1 range, " + "for easier editing of multiple curves with different ranges"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL); + + prop = RNA_def_property(srna, "use_auto_normalization", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SIPO_NORMALIZE_FREEZE); + RNA_def_property_ui_text(prop, "Auto Normalization", + "Automatically recalculate curve normalization on every curve edit"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL); } static void rna_def_space_nla(BlenderRNA *brna) @@ -3374,7 +3394,8 @@ static void rna_def_space_node(BlenderRNA *brna) prop = RNA_def_property(srna, "tree_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, dummy_items); - RNA_def_property_enum_funcs(prop, "rna_SpaceNodeEditor_tree_type_get", "rna_SpaceNodeEditor_tree_type_set", "rna_SpaceNodeEditor_tree_type_itemf"); + RNA_def_property_enum_funcs(prop, "rna_SpaceNodeEditor_tree_type_get", "rna_SpaceNodeEditor_tree_type_set", + "rna_SpaceNodeEditor_tree_type_itemf"); RNA_def_property_ui_text(prop, "Tree Type", "Node tree type to display and edit"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE, NULL); @@ -3406,7 +3427,8 @@ static void rna_def_space_node(BlenderRNA *brna) rna_def_space_node_path_api(brna, prop); prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceNodeEditor_node_tree_set", NULL, "rna_SpaceNodeEditor_node_tree_poll"); + RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceNodeEditor_node_tree_set", NULL, + "rna_SpaceNodeEditor_node_tree_poll"); RNA_def_property_pointer_sdna(prop, NULL, "nodetree"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_CONTEXT_UPDATE); RNA_def_property_ui_text(prop, "Node Tree", "Base node tree from context"); diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 97f5c24dc56..a0aed94f3c6 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -570,7 +570,8 @@ static MovieTrackingTrack *rna_trackingTracks_new(ID *id, MovieTracking *trackin return track; } -static MovieTrackingTrack *rna_trackingObject_tracks_new(ID *id, MovieTrackingObject *object, const char *name, int frame) +static MovieTrackingTrack *rna_trackingObject_tracks_new(ID *id, MovieTrackingObject *object, const char *name, + int frame) { MovieClip *clip = (MovieClip *) id; ListBase *tracksbase = &object->tracks; @@ -649,7 +650,8 @@ static void rna_trackingMarkers_delete_frame(MovieTrackingTrack *track, int fram WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL); } -static MovieTrackingPlaneMarker *rna_trackingPlaneMarkers_find_frame(MovieTrackingPlaneTrack *plane_track, int framenr, int exact) +static MovieTrackingPlaneMarker *rna_trackingPlaneMarkers_find_frame(MovieTrackingPlaneTrack *plane_track, + int framenr, int exact) { if (exact) return BKE_tracking_plane_marker_get_exact(plane_track, framenr); @@ -657,7 +659,8 @@ static MovieTrackingPlaneMarker *rna_trackingPlaneMarkers_find_frame(MovieTracki return BKE_tracking_plane_marker_get(plane_track, framenr); } -static MovieTrackingPlaneMarker *rna_trackingPlaneMarkers_insert_frame(MovieTrackingPlaneTrack *plane_track, int framenr) +static MovieTrackingPlaneMarker *rna_trackingPlaneMarkers_insert_frame(MovieTrackingPlaneTrack *plane_track, + int framenr) { MovieTrackingPlaneMarker plane_marker, *new_plane_marker; @@ -767,22 +770,6 @@ static void rna_def_trackingSettings(BlenderRNA *brna) "Limit speed of tracking to make visual feedback easier " "(this does not affect the tracking quality)"); - /* reconstruction success_threshold */ - prop = RNA_def_property(srna, "reconstruction_success_threshold", PROP_FLOAT, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_float_default(prop, 0.001f); - RNA_def_property_range(prop, 0, FLT_MAX); - RNA_def_property_ui_text(prop, "Success Threshold", - "Threshold value of reconstruction error which is still considered successful"); - - /* use fallback reconstruction */ - prop = RNA_def_property(srna, "use_fallback_reconstruction", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_boolean_sdna(prop, NULL, "reconstruction_flag", TRACKING_USE_FALLBACK_RECONSTRUCTION); - RNA_def_property_ui_text(prop, "Use Fallback", - "Use fallback reconstruction algorithm in cases main reconstruction algorithm failed " - "(could give better solution with bad tracks)"); - /* use keyframe selection */ prop = RNA_def_property(srna, "use_keyframe_selection", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); @@ -1105,6 +1092,12 @@ static void rna_def_trackingMarker(BlenderRNA *brna) "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"); + + /* is marker keyframed */ + prop = RNA_def_property(srna, "is_keyed", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", MARKER_TRACKED); + RNA_def_property_ui_text(prop, "Keyframed", "Whether the position of the marker is keyframed or tracked"); } static void rna_def_trackingMarkers(BlenderRNA *brna, PropertyRNA *cprop) @@ -1355,6 +1348,20 @@ static void rna_def_trackingTrack(BlenderRNA *brna) 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); + + /* weight */ + prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "weight"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Weight", "Influence of this track on a final solution"); + + /* offset */ + prop = RNA_def_property(srna, "offset", 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, "offset"); + RNA_def_property_ui_text(prop, "Offset", "Offset of track from the parenting point"); + RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, NULL); } static void rna_def_trackingPlaneMarker(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 20e5083b1c4..0e45d6d4aea 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -367,7 +367,7 @@ static void rna_userdef_pathcompare_remove(ReportList *reports, PointerRNA *path { bPathCompare *path_cmp = path_cmp_ptr->data; if (BLI_findindex(&U.autoexec_paths, path_cmp) == -1) { - BKE_report(reports, RPT_ERROR, "Addon is no longer valid"); + BKE_report(reports, RPT_ERROR, "Excluded path is no longer valid"); return; } @@ -2909,7 +2909,7 @@ static void rna_def_userdef_view(BlenderRNA *brna) prop = RNA_def_property(srna, "show_tooltips_python", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", USER_TOOLTIPS_PYTHON); - RNA_def_property_ui_text(prop, "Show Python Tooltips", "Show Python references in tooltips"); + RNA_def_property_ui_text(prop, "Python Tooltips", "Show Python references in tooltips"); prop = RNA_def_property(srna, "show_object_info", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_DRAWVIEWINFO); @@ -3266,7 +3266,13 @@ static void rna_def_userdef_edit(BlenderRNA *brna) RNA_def_property_int_sdna(prop, NULL, "gp_eraser"); RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "Grease Pencil Eraser Radius", "Radius of eraser 'brush'"); - + + + prop = RNA_def_property(srna, "grease_pencil_default_color", PROP_FLOAT, PROP_COLOR); + RNA_def_property_float_sdna(prop, NULL, "gpencil_new_layer_col"); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Grease Pencil Default Color", "Color of new Grease Pencil layers"); + /* sculpt and paint */ prop = RNA_def_property(srna, "sculpt_paint_overlay_color", PROP_FLOAT, PROP_COLOR_GAMMA); @@ -4091,7 +4097,7 @@ static void rna_def_userdef_autoexec_path_collection(BlenderRNA *brna, PropertyR func = RNA_def_function(srna, "new", "rna_userdef_pathcompare_new"); RNA_def_function_flag(func, FUNC_NO_SELF); - RNA_def_function_ui_description(func, "Add a new addon"); + RNA_def_function_ui_description(func, "Add a new path"); /* return type */ parm = RNA_def_pointer(func, "pathcmp", "PathCompare", "", ""); RNA_def_function_return(func, parm); diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index c6366745c55..09451599ce5 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -442,13 +442,6 @@ EnumPropertyItem wm_report_items[] = { {0, NULL, 0, NULL, NULL} }; -#define KMI_TYPE_KEYBOARD 0 -#define KMI_TYPE_MOUSE 1 -#define KMI_TYPE_TWEAK 2 -#define KMI_TYPE_TEXTINPUT 3 -#define KMI_TYPE_TIMER 4 -#define KMI_TYPE_NDOF 5 - #ifdef RNA_RUNTIME #include <assert.h> @@ -625,13 +618,7 @@ static int rna_wmKeyMapItem_map_type_get(PointerRNA *ptr) { wmKeyMapItem *kmi = ptr->data; - if (ISTIMER(kmi->type)) return KMI_TYPE_TIMER; - if (ISKEYBOARD(kmi->type)) return KMI_TYPE_KEYBOARD; - if (ISTWEAK(kmi->type)) return KMI_TYPE_TWEAK; - if (ISMOUSE(kmi->type)) return KMI_TYPE_MOUSE; - if (ISNDOF(kmi->type)) return KMI_TYPE_NDOF; - if (kmi->type == KM_TEXTINPUT) return KMI_TYPE_TEXTINPUT; - return KMI_TYPE_KEYBOARD; + return WM_keymap_map_type_get(kmi); } static void rna_wmKeyMapItem_map_type_set(PointerRNA *ptr, int value) @@ -1055,15 +1042,13 @@ static void operator_draw(bContext *C, wmOperator *op) } /* same as exec(), but call cancel */ -static int operator_cancel(bContext *C, wmOperator *op) +static void operator_cancel(bContext *C, wmOperator *op) { extern FunctionRNA rna_Operator_cancel_func; PointerRNA opr; ParameterList list; FunctionRNA *func; - void *ret; - int result; RNA_pointer_create(NULL, op->type->ext.srna, op, &opr); func = &rna_Operator_cancel_func; /* RNA_struct_find_function(&opr, "cancel"); */ @@ -1072,12 +1057,7 @@ static int operator_cancel(bContext *C, wmOperator *op) RNA_parameter_set_lookup(&list, "context", &C); op->type->ext.call(C, &opr, func, &list); - RNA_parameter_get_lookup(&list, "result", &ret); - result = *(int *)ret; - RNA_parameter_list_free(&list); - - return result; } void operator_wrapper(wmOperatorType *ot, void *userdata); diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c index eb84bb61e1f..91cddd28be0 100644 --- a/source/blender/makesrna/intern/rna_wm_api.c +++ b/source/blender/makesrna/intern/rna_wm_api.c @@ -539,10 +539,6 @@ void RNA_api_operator(StructRNA *srna) RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); - - /* better name? */ - parm = RNA_def_enum_flag(func, "result", operator_return_items, OPERATOR_CANCELLED, "result", ""); - RNA_def_function_return(func, parm); } void RNA_api_macro(StructRNA *srna) diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index b689a82c231..c7997bebedb 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -56,10 +56,6 @@ static PointerRNA rna_World_lighting_get(PointerRNA *ptr) return rna_pointer_inherit_refine(ptr, &RNA_WorldLighting, ptr->id.data); } -static PointerRNA rna_World_stars_get(PointerRNA *ptr) -{ - return rna_pointer_inherit_refine(ptr, &RNA_WorldStarsSettings, ptr->id.data); -} static PointerRNA rna_World_mist_get(PointerRNA *ptr) { @@ -114,14 +110,6 @@ static void rna_World_draw_mist_update(Main *UNUSED(bmain), Scene *UNUSED(scene) WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL); } -static void rna_World_stars_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) -{ - World *wo = ptr->id.data; - - DAG_id_tag_update(&wo->id, 0); - WM_main_add_notifier(NC_WORLD | ND_WORLD_STARS, wo); -} - static void rna_World_use_nodes_update(bContext *C, PointerRNA *ptr) { World *wrld = (World *)ptr->data; @@ -450,46 +438,6 @@ static void rna_def_world_mist(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_World_update"); } -static void rna_def_world_stars(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "WorldStarsSettings", NULL); - RNA_def_struct_sdna(srna, "World"); - RNA_def_struct_nested(brna, srna, "World"); - RNA_def_struct_ui_text(srna, "World Stars", "Stars settings for a World data-block"); - - prop = RNA_def_property(srna, "use_stars", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", WO_STARS); - RNA_def_property_ui_text(prop, "Use Stars", "Enable starfield generation"); - RNA_def_property_update(prop, 0, "rna_World_stars_update"); - - prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "starsize"); - RNA_def_property_range(prop, 0, 10); - RNA_def_property_ui_text(prop, "Size", "Average screen dimension of stars"); - RNA_def_property_update(prop, 0, "rna_World_draw_update"); /* use normal update since this isn't visualized */ - - prop = RNA_def_property(srna, "distance_min", PROP_FLOAT, PROP_DISTANCE); - RNA_def_property_float_sdna(prop, NULL, "starmindist"); - RNA_def_property_range(prop, 0, 1000); - RNA_def_property_ui_text(prop, "Minimum Distance", "Minimum distance to the camera for stars"); - RNA_def_property_update(prop, 0, "rna_World_stars_update"); - - prop = RNA_def_property(srna, "average_separation", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "stardist"); - RNA_def_property_range(prop, 2, 1000); - RNA_def_property_ui_text(prop, "Average Separation", "Average distance between any two stars"); - RNA_def_property_update(prop, 0, "rna_World_stars_update"); - - prop = RNA_def_property(srna, "color_random", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "starcolnoise"); - RNA_def_property_range(prop, 0, 1); - RNA_def_property_ui_text(prop, "Color Randomization", "Randomize star colors"); - RNA_def_property_update(prop, 0, "rna_World_stars_update"); -} - void RNA_def_world(BlenderRNA *brna) { StructRNA *srna; @@ -568,12 +516,6 @@ void RNA_def_world(BlenderRNA *brna) RNA_def_property_pointer_funcs(prop, "rna_World_mist_get", NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Mist", "World mist settings"); - prop = RNA_def_property(srna, "star_settings", PROP_POINTER, PROP_NONE); - RNA_def_property_flag(prop, PROP_NEVER_NULL); - RNA_def_property_struct_type(prop, "WorldStarsSettings"); - RNA_def_property_pointer_funcs(prop, "rna_World_stars_get", NULL, NULL, NULL); - RNA_def_property_ui_text(prop, "Stars", "World stars settings"); - /* nodes */ prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "nodetree"); @@ -588,7 +530,6 @@ void RNA_def_world(BlenderRNA *brna) rna_def_lighting(brna); rna_def_world_mist(brna); - rna_def_world_stars(brna); rna_def_world_mtex(brna); } diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 7c47fd5862e..bc38b0e030b 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -384,18 +384,14 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, if (amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob) { Curve *cu = amd->curve_ob->data; if (cu) { - float tmp_mat[3][3]; - float scale; - - BKE_object_to_mat3(amd->curve_ob, tmp_mat); - scale = mat3_to_scale(tmp_mat); - if (!amd->curve_ob->curve_cache || !amd->curve_ob->curve_cache->path) { cu->flag |= CU_PATH; // needed for path & bevlist BKE_displist_make_curveTypes(scene, amd->curve_ob, 0); } - if (amd->curve_ob->curve_cache->path) + if (amd->curve_ob->curve_cache->path) { + float scale = mat4_to_scale(amd->curve_ob->obmat); length = scale * amd->curve_ob->curve_cache->path->totdist; + } } } diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 326ffba3e2e..6a1de92f9b2 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -158,7 +158,8 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob, } } - BM_mesh_bevel(bm, bmd->value, bmd->res, + /* TODO: add offset_kind to modifier properties to, and pass in as 3rd arg here */ + BM_mesh_bevel(bm, bmd->value, 0, bmd->res, vertex_only, bmd->lim_flags & MOD_BEVEL_WEIGHT, do_clamp, dvert, vgroup); diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index a3569cbde68..e4399d1e416 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -196,9 +196,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* update for display only */ dmd->face_count = bm->totface; result = CDDM_from_bmesh(bm, FALSE); - BLI_assert(bm->vtoolflagpool == NULL); /* make sure we never alloc'd this */ - BLI_assert(bm->etoolflagpool == NULL); - BLI_assert(bm->ftoolflagpool == NULL); + BLI_assert(bm->vtoolflagpool == NULL && + bm->etoolflagpool == NULL && + bm->ftoolflagpool == NULL); /* make sure we never alloc'd these */ + BLI_assert(bm->vtable == NULL && + bm->etable == NULL && + bm->ftable == NULL); + BM_mesh_free(bm); #ifdef USE_TIMEIT diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index 25254c7a30e..61f5495bee8 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -219,7 +219,7 @@ static void displaceModifier_do( if (dmd->texture) { texres.nor = NULL; - get_texture_value(dmd->modifier.scene, dmd->texture, tex_co[i], &texres, false); + BKE_texture_get_value(dmd->modifier.scene, dmd->texture, tex_co[i], &texres, false); delta = texres.tin - dmd->midlevel; } else { diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c index 0d302fed3e6..839e30d9c1a 100644 --- a/source/blender/modifiers/intern/MOD_mask.c +++ b/source/blender/modifiers/intern/MOD_mask.c @@ -62,6 +62,8 @@ static void copyData(ModifierData *md, ModifierData *target) BLI_strncpy(tmmd->vgroup, mmd->vgroup, sizeof(tmmd->vgroup)); tmmd->flag = mmd->flag; + tmmd->mode = mmd->mode; + tmmd->ob_arm = mmd->ob_arm; } static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md)) @@ -170,7 +172,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } /* if no dverts (i.e. no data for vertex groups exists), we've got an - * inconsistent situation, so free hashes and return oirginal mesh + * inconsistent situation, so free hashes and return original mesh */ dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); if (dvert == NULL) { diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index 8386f0ff9af..e540d5c1b2c 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -199,10 +199,10 @@ static void meshdeformModifier_do( if (!mmd->object || (!mmd->bindcagecos && !mmd->bindfunc)) return; - + /* get cage derivedmesh */ if (em) { - tmpdm = editbmesh_get_derived_cage_and_final(md->scene, ob, em, &cagedm, 0); + tmpdm = editbmesh_get_derived_cage_and_final(md->scene, mmd->object, em, &cagedm, 0); if (tmpdm) tmpdm->release(tmpdm); } @@ -346,7 +346,7 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, false, false); modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */ - + meshdeformModifier_do(md, ob, dm, vertexCos, numVerts); if (dm && dm != derivedData) diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index 0dd2f2770a4..7955e02cdb6 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -34,6 +34,7 @@ /* Screw modifier: revolves the edges about an axis */ +#include <limits.h> #include "DNA_meshdata_types.h" #include "DNA_object_types.h" @@ -41,19 +42,20 @@ #include "BLI_math.h" #include "BLI_utildefines.h" - #include "BKE_cdderivedmesh.h" #include "depsgraph_private.h" #include "MOD_modifiertypes.h" #include "MEM_guardedalloc.h" +#include "BLI_strict_flags.h" + /* used for gathering edge connectivity */ typedef struct ScrewVertConnect { float dist; /* distance from the center axis */ float co[3]; /* loaction relative to the transformed axis */ float no[3]; /* calc normal of the vertex */ - int v[2]; /* 2 verts on either side of this one */ + unsigned int v[2]; /* 2 verts on either side of this one */ MEdge *e[2]; /* edges on either side, a bit of a waste since each edge ref's 2 edges */ char flag; } ScrewVertConnect; @@ -61,18 +63,20 @@ typedef struct ScrewVertConnect { typedef struct ScrewVertIter { ScrewVertConnect *v_array; ScrewVertConnect *v_poin; - int v; - int v_other; + unsigned int v, v_other; MEdge *e; } ScrewVertIter; +#define SV_UNUSED (UINT_MAX) +#define SV_INVALID ((UINT_MAX) - 1) +#define SV_IS_VALID(v) (v < SV_INVALID) -static void screwvert_iter_init(ScrewVertIter *iter, ScrewVertConnect *array, int v_init, int dir) +static void screwvert_iter_init(ScrewVertIter *iter, ScrewVertConnect *array, unsigned int v_init, unsigned int dir) { iter->v_array = array; iter->v = v_init; - if (v_init >= 0) { + if (SV_IS_VALID(v_init)) { iter->v_poin = &array[v_init]; iter->v_other = iter->v_poin->v[dir]; iter->e = iter->v_poin->e[!dir]; @@ -94,7 +98,7 @@ static void screwvert_iter_step(ScrewVertIter *iter) iter->v_other = iter->v; iter->v = iter->v_poin->v[0]; } - if (iter->v >= 0) { + if (SV_IS_VALID(iter->v)) { iter->v_poin = &iter->v_array[iter->v]; iter->e = iter->v_poin->e[(iter->v_poin->e[0] == iter->e)]; } @@ -109,7 +113,7 @@ static void initData(ModifierData *md) { ScrewModifierData *ltmd = (ScrewModifierData *) md; ltmd->ob_axis = NULL; - ltmd->angle = M_PI * 2.0; + ltmd->angle = (float)(M_PI * 2.0); ltmd->axis = 2; ltmd->flag = MOD_SCREW_SMOOTH_SHADING; ltmd->steps = 16; @@ -143,16 +147,19 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, int *origindex; int mpoly_index = 0; - int step; - int i, j; + unsigned int step; + unsigned int i, j; unsigned int i1, i2; - int step_tot = useRenderParams ? ltmd->render_steps : ltmd->steps; - const int do_flip = ltmd->flag & MOD_SCREW_NORMAL_FLIP ? 1 : 0; - int maxVerts = 0, maxEdges = 0, maxPolys = 0; - const unsigned int totvert = dm->getNumVerts(dm); - const unsigned int totedge = dm->getNumEdges(dm); - - char axis_char = 'X', close; + unsigned int step_tot = useRenderParams ? ltmd->render_steps : ltmd->steps; + const bool do_flip = ltmd->flag & MOD_SCREW_NORMAL_FLIP ? 1 : 0; + unsigned int maxVerts = 0, maxEdges = 0, maxPolys = 0; + const unsigned int totvert = (unsigned int)dm->getNumVerts(dm); + const unsigned int totedge = (unsigned int)dm->getNumEdges(dm); + const unsigned int totpoly = (unsigned int)dm->getNumPolys(dm); + unsigned int *edge_poly_map = NULL; + + char axis_char = 'X'; + bool close; float angle = ltmd->angle; float screw_ofs = ltmd->screw_ofs; float axis_vec[3] = {0.0f, 0.0f, 0.0f}; @@ -162,14 +169,14 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, float mtx_tx_inv[4][4]; /* inverted */ float mtx_tmp_a[4][4]; - int vc_tot_linked = 0; + unsigned int vc_tot_linked = 0; short other_axis_1, other_axis_2; float *tmpf1, *tmpf2; - int edge_offset; + unsigned int edge_offset; - MPoly *mpoly_new, *mp_new; - MLoop *mloop_new, *ml_new; + MPoly *mpoly_orig, *mpoly_new, *mp_new; + MLoop *mloop_orig, *mloop_new, *ml_new; MEdge *medge_orig, *med_orig, *med_new, *med_new_firstloop, *medge_new; MVert *mvert_new, *mvert_orig, *mv_orig, *mv_new, *mv_new_base; @@ -259,7 +266,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } else { /* exis char is used by i_rotate*/ - axis_char += ltmd->axis; /* 'X' + axis */ + axis_char = (char)(axis_char + ltmd->axis); /* 'X' + axis */ /* useful to be able to use the axis vec in some cases still */ zero_v3(axis_vec); @@ -267,8 +274,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } /* apply the multiplier */ - angle *= ltmd->iter; - screw_ofs *= ltmd->iter; + angle *= (float)ltmd->iter; + screw_ofs *= (float)ltmd->iter; /* multiplying the steps is a bit tricky, this works best */ step_tot = ((step_tot + 1) * ltmd->iter) - (ltmd->iter - 1); @@ -299,7 +306,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, maxPolys = totedge * (step_tot - 1); } - result = CDDM_from_template(dm, maxVerts, maxEdges, 0, maxPolys * 4, maxPolys); + result = CDDM_from_template(dm, (int)maxVerts, (int)maxEdges, 0, (int)maxPolys * 4, (int)maxPolys); /* copy verts from mesh */ mvert_orig = dm->getVertArray(dm); @@ -311,12 +318,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, medge_new = result->getEdgeArray(result); if (!CustomData_has_layer(&result->polyData, CD_ORIGINDEX)) { - CustomData_add_layer(&result->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, maxPolys); + CustomData_add_layer(&result->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, (int)maxPolys); } origindex = CustomData_get_layer(&result->polyData, CD_ORIGINDEX); - DM_copy_vert_data(dm, result, 0, 0, totvert); /* copy first otherwise this overwrites our own vertex normals */ + DM_copy_vert_data(dm, result, 0, 0, (int)totvert); /* copy first otherwise this overwrites our own vertex normals */ /* Set the locations of the first set of verts */ @@ -333,6 +340,29 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, med_new->flag = med_orig->flag & ~ME_LOOSEEDGE; } + /* build polygon -> edge map */ + if (totpoly) { + MPoly *mp_orig; + + mpoly_orig = dm->getPolyArray(dm); + mloop_orig = dm->getLoopArray(dm); + edge_poly_map = MEM_mallocN(sizeof(*edge_poly_map) * totedge, __func__); + memset(edge_poly_map, 0xff, sizeof(*edge_poly_map) * totedge); + + for (i = 0, mp_orig = mpoly_orig; i < totpoly; i++, mp_orig++) { + MLoop *ml_orig = &mloop_orig[mp_orig->loopstart]; + int k; + for (k = 0; k < mp_orig->totloop; k++, ml_orig++) { + edge_poly_map[ml_orig->e] = i; + + /* also order edges based on faces */ + if (medge_new[ml_orig->e].v1 != ml_orig->v) { + SWAP(unsigned int, medge_new[ml_orig->e].v1, medge_new[ml_orig->e].v2); + } + } + } + } + if (ltmd->flag & MOD_SCREW_NORMAL_CALC) { /* * Normal Calculation (for face flipping) @@ -385,7 +415,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, vc->flag = 0; vc->e[0] = vc->e[1] = NULL; - vc->v[0] = vc->v[1] = -1; + vc->v[0] = vc->v[1] = SV_UNUSED; mul_m4_v3(mtx_tx, vc->co); /* length in 2d, don't sqrt because this is only for comparison */ @@ -403,7 +433,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, vc->flag = 0; vc->e[0] = vc->e[1] = NULL; - vc->v[0] = vc->v[1] = -1; + vc->v[0] = vc->v[1] = SV_UNUSED; /* length in 2d, don't sqrt because this is only for comparison */ vc->dist = vc->co[other_axis_1] * vc->co[other_axis_1] + @@ -417,31 +447,31 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, for (i = 0; i < totedge; i++, med_new++) { vc = &vert_connect[med_new->v1]; - if (vc->v[0] == -1) { /* unused */ + if (vc->v[0] == SV_UNUSED) { /* unused */ vc->v[0] = med_new->v2; vc->e[0] = med_new; } - else if (vc->v[1] == -1) { + else if (vc->v[1] == SV_UNUSED) { vc->v[1] = med_new->v2; vc->e[1] = med_new; } else { - vc->v[0] = vc->v[1] = -2; /* error value - don't use, 3 edges on vert */ + vc->v[0] = vc->v[1] = SV_INVALID; /* error value - don't use, 3 edges on vert */ } vc = &vert_connect[med_new->v2]; /* same as above but swap v1/2 */ - if (vc->v[0] == -1) { /* unused */ + if (vc->v[0] == SV_UNUSED) { /* unused */ vc->v[0] = med_new->v1; vc->e[0] = med_new; } - else if (vc->v[1] == -1) { + else if (vc->v[1] == SV_UNUSED) { vc->v[1] = med_new->v1; vc->e[1] = med_new; } else { - vc->v[0] = vc->v[1] = -2; /* error value - don't use, 3 edges on vert */ + vc->v[0] = vc->v[1] = SV_INVALID; /* error value - don't use, 3 edges on vert */ } } @@ -452,12 +482,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, * so resulting faces are flipped the right way */ vc_tot_linked = 0; /* count the number of linked verts for this loop */ if (vc->flag == 0) { - int v_best = -1, ed_loop_closed = 0; /* vert and vert new */ + unsigned int v_best = SV_UNUSED, ed_loop_closed = 0; /* vert and vert new */ ScrewVertIter lt_iter; float fl = -1.0f; /* compiler complains if not initialized, but it should be initialized below */ - int ed_loop_flip = 0; + bool ed_loop_flip = false; /*printf("Loop on connected vert: %i\n", i);*/ @@ -471,7 +501,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /*printf("\t\tVERT: %i\n", lt_iter.v);*/ if (lt_iter.v_poin->flag) { /*printf("\t\t\tBreaking Found end\n");*/ - //endpoints[0] = endpoints[1] = -1; + //endpoints[0] = endpoints[1] = SV_UNUSED; ed_loop_closed = 1; /* circle */ break; } @@ -493,7 +523,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } /* now we have a collection of used edges. flip their edges the right way*/ - /*if (v_best != -1) - */ + /*if (v_best != SV_UNUSED) - */ /*printf("Done Looking - vc_tot_linked: %i\n", vc_tot_linked);*/ @@ -507,7 +537,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* edge connects on each side! */ - if ((vc_tmp->v[0] > -1) && (vc_tmp->v[1] > -1)) { + if (SV_IS_VALID(vc_tmp->v[0]) && SV_IS_VALID(vc_tmp->v[1])) { /*printf("Verts on each side (%i %i)\n", vc_tmp->v[0], vc_tmp->v[1]);*/ /* find out which is higher */ @@ -536,7 +566,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } } } - else if (vc_tmp->v[0] >= 0) { /*vertex only connected on 1 side */ + else if (SV_IS_VALID(vc_tmp->v[0])) { /*vertex only connected on 1 side */ /*printf("Verts on ONE side (%i %i)\n", vc_tmp->v[0], vc_tmp->v[1]);*/ if (tmpf1[ltmd->axis] < vc_tmp->co[ltmd->axis]) { /* best is above */ ed_loop_flip = 1; @@ -577,7 +607,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* If this is the vert off the best vert and * the best vert has 2 edges connected too it * then swap the flip direction */ - if (j == 1 && (vc_tmp->v[0] > -1) && (vc_tmp->v[1] > -1)) + if (j == 1 && SV_IS_VALID(vc_tmp->v[0]) && SV_IS_VALID(vc_tmp->v[1])) ed_loop_flip = !ed_loop_flip; while (lt_iter.v_poin && lt_iter.v_poin->flag != 2) { @@ -622,8 +652,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, * * calculate vertex normals that can be propagated on lathing * use edge connectivity work this out */ - if (vc->v[0] >= 0) { - if (vc->v[1] >= 0) { + if (SV_IS_VALID(vc->v[0])) { + if (SV_IS_VALID(vc->v[1])) { /* 2 edges connedted */ /* make 2 connecting vert locations relative to the middle vert */ sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co); @@ -689,12 +719,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* Add Faces */ for (step = 1; step < step_tot; step++) { - const int varray_stride = totvert * step; + const unsigned int varray_stride = totvert * step; float step_angle; float nor_tx[3]; float mat[4][4]; /* Rotation Matrix */ - step_angle = (angle / (step_tot - (!close))) * step; + step_angle = (angle / (float)(step_tot - (!close))) * (float)step; if (ltmd->ob_axis) { axis_angle_normalized_to_mat3(mat3, axis_vec, step_angle); @@ -710,7 +740,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, madd_v3_v3fl(mat[3], axis_vec, screw_ofs * ((float)step / (float)(step_tot - 1))); /* copy a slice */ - DM_copy_vert_data(dm, result, 0, varray_stride, totvert); + DM_copy_vert_data(dm, result, 0, (int)varray_stride, (int)totvert); mv_new_base = mvert_new; mv_new = &mvert_new[varray_stride]; /* advance to the next slice */ @@ -757,7 +787,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, if (close) { /* last loop of edges, previous loop dosnt account for the last set of edges */ - const int varray_stride = (step_tot - 1) * totvert; + const unsigned int varray_stride = (step_tot - 1) * totvert; for (i = 0; i < totvert; i++) { med_new->v1 = i; @@ -775,10 +805,19 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, edge_offset = totedge + (totvert * (step_tot - (close ? 0 : 1))); for (i = 0; i < totedge; i++, med_new_firstloop++) { + short mat_nr; + /* for each edge, make a cylinder of quads */ i1 = med_new_firstloop->v1; i2 = med_new_firstloop->v2; + if (totpoly && (edge_poly_map[i] != UINT_MAX)) { + mat_nr = mpoly_orig[edge_poly_map[i]].mat_nr; + } + else { + mat_nr = 0; + } + for (step = 0; step < step_tot - 1; step++) { /* new face */ @@ -808,6 +847,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, mp_new->loopstart = mpoly_index * 4; mp_new->totloop = 4; + mp_new->mat_nr = mat_nr; mp_new->flag = mpoly_flag; origindex[mpoly_index] = ORIGINDEX_NONE; mp_new++; @@ -853,6 +893,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, mp_new->loopstart = mpoly_index * 4; mp_new->totloop = 4; + mp_new->mat_nr = mat_nr; mp_new->flag = mpoly_flag; origindex[mpoly_index] = ORIGINDEX_NONE; mp_new++; @@ -871,10 +912,10 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* validate loop edges */ #if 0 { - i = 0; + unsigned i = 0; printf("\n"); for (; i < maxPolys * 4; i += 4) { - int ii; + unsigned int ii; ml_new = mloop_new + i; ii = findEd(medge_new, maxEdges, ml_new[0].v, ml_new[1].v); printf("%d %d -- ", ii, ml_new[0].e); @@ -896,6 +937,10 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } #endif + if (edge_poly_map) { + MEM_freeN(edge_poly_map); + } + if ((ltmd->flag & MOD_SCREW_NORMAL_CALC) == 0) { result->dirty |= DM_DIRTY_NORMALS; } diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c index ffc813068b8..d519c981a23 100644 --- a/source/blender/modifiers/intern/MOD_triangulate.c +++ b/source/blender/modifiers/intern/MOD_triangulate.c @@ -36,7 +36,7 @@ #include "bmesh.h" #include "bmesh_tools.h" -static DerivedMesh *triangulate_dm(DerivedMesh *dm, const int flag) +static DerivedMesh *triangulate_dm(DerivedMesh *dm, const int quad_method, const int ngon_method) { DerivedMesh *result; BMesh *bm; @@ -45,7 +45,7 @@ static DerivedMesh *triangulate_dm(DerivedMesh *dm, const int flag) bm = DM_to_bmesh(dm, true); - BM_mesh_triangulate(bm, (flag & MOD_TRIANGULATE_BEAUTY), false, NULL, NULL); + BM_mesh_triangulate(bm, quad_method, ngon_method, false, NULL, NULL); result = CDDM_from_bmesh(bm, FALSE); BM_mesh_free(bm); @@ -69,7 +69,8 @@ static void initData(ModifierData *md) /* Enable in editmode by default */ md->mode |= eModifierMode_Editmode; - tmd->flag = MOD_TRIANGULATE_BEAUTY; + tmd->quad_method = MOD_TRIANGULATE_QUAD_SHORTEDGE; + tmd->ngon_method = MOD_TRIANGULATE_NGON_BEAUTY; } @@ -88,7 +89,7 @@ static DerivedMesh *applyModifier(ModifierData *md, { TriangulateModifierData *tmd = (TriangulateModifierData *)md; DerivedMesh *result; - if (!(result = triangulate_dm(dm, tmd->flag))) { + if (!(result = triangulate_dm(dm, tmd->quad_method, tmd->ngon_method))) { return dm; } diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index 230931a1a33..e9fabcd1fd0 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -70,30 +70,6 @@ void modifier_init_texture(Scene *scene, Tex *tex) BKE_image_user_frame_calc(&tex->iuser, scene->r.cfra, 0); } -void get_texture_value(Scene *scene, Tex *texture, float *tex_co, TexResult *texres, bool use_color_management) -{ - int result_type; - bool do_color_manage = false; - - if (use_color_management) { - do_color_manage = BKE_scene_check_color_management_enabled(scene); - } - - /* no node textures for now */ - result_type = multitex_ext_safe(texture, tex_co, texres, NULL, do_color_manage); - - /* if the texture gave an RGB value, we assume it didn't give a valid - * intensity, since this is in the context of modifiers don't use perceptual color conversion. - * if the texture didn't give an RGB value, copy the intensity across - */ - if (result_type & TEX_RGB) { - texres->tin = (1.0f / 3.0f) * (texres->tr + texres->tg + texres->tb); - } - else { - copy_v3_fl(&texres->tr, texres->tin); - } -} - void get_texture_coords(MappingInfoModifierData *dmd, Object *ob, DerivedMesh *dm, float (*co)[3], float (*texco)[3], diff --git a/source/blender/modifiers/intern/MOD_util.h b/source/blender/modifiers/intern/MOD_util.h index 25632eb5b80..b4dcdc1721a 100644 --- a/source/blender/modifiers/intern/MOD_util.h +++ b/source/blender/modifiers/intern/MOD_util.h @@ -41,7 +41,6 @@ struct Tex; struct TexResult; void modifier_init_texture(struct Scene *scene, struct Tex *texture); -void get_texture_value(struct Scene *scene, struct Tex *texture, float *tex_co, struct TexResult *texres, bool do_color_manage); void get_texture_coords(struct MappingInfoModifierData *dmd, struct Object *ob, struct DerivedMesh *dm, float (*co)[3], float (*texco)[3], int numVerts); void modifier_vgroup_cache(struct ModifierData *md, float (*vertexCos)[3]); diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c index 4fac201377a..83b05ae708a 100644 --- a/source/blender/modifiers/intern/MOD_warp.c +++ b/source/blender/modifiers/intern/MOD_warp.c @@ -282,7 +282,7 @@ static void warpModifier_do(WarpModifierData *wmd, Object *ob, if (tex_co) { TexResult texres; texres.nor = NULL; - get_texture_value(wmd->modifier.scene, wmd->texture, tex_co[i], &texres, false); + BKE_texture_get_value(wmd->modifier.scene, wmd->texture, tex_co[i], &texres, false); fac *= texres.tin; } diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c index 43dc1ba4eb9..168907e293c 100644 --- a/source/blender/modifiers/intern/MOD_wave.c +++ b/source/blender/modifiers/intern/MOD_wave.c @@ -48,6 +48,7 @@ #include "BKE_library.h" #include "BKE_object.h" #include "BKE_scene.h" +#include "BKE_texture.h" #include "depsgraph_private.h" @@ -306,7 +307,7 @@ static void waveModifier_do(WaveModifierData *md, if (wmd->texture) { TexResult texres; texres.nor = NULL; - get_texture_value(wmd->modifier.scene, wmd->texture, tex_co[i], &texres, false); + BKE_texture_get_value(wmd->modifier.scene, wmd->texture, tex_co[i], &texres, false); amplit *= texres.tin; } diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c index e2267addd53..5c3b87bd92c 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.c +++ b/source/blender/modifiers/intern/MOD_weightvg_util.c @@ -164,7 +164,7 @@ void weightvg_do_mask(int num, const int *indices, float *org_w, const float *ne do_color_manage = tex_use_channel != MOD_WVG_MASK_TEX_USE_INT; texres.nor = NULL; - get_texture_value(scene, texture, tex_co[idx], &texres, do_color_manage); + BKE_texture_get_value(scene, texture, tex_co[idx], &texres, do_color_manage); /* Get the good channel value... */ switch (tex_use_channel) { case MOD_WVG_MASK_TEX_USE_INT: diff --git a/source/blender/nodes/composite/nodes/node_composite_colorbalance.c b/source/blender/nodes/composite/nodes/node_composite_colorbalance.c index 9ae744439bc..5e7bbfaa1d3 100644 --- a/source/blender/nodes/composite/nodes/node_composite_colorbalance.c +++ b/source/blender/nodes/composite/nodes/node_composite_colorbalance.c @@ -46,6 +46,36 @@ static bNodeSocketTemplate cmp_node_colorbalance_out[] = { {-1, 0, ""} }; +/* Sync functions update formula parameters for other modes, such that the result is comparable. + * Note that the results are not exactly the same due to differences in color handling (sRGB conversion happens for LGG), + * but this keeps settings comparable. + */ + +void ntreeCompositColorBalanceSyncFromLGG(bNodeTree *UNUSED(ntree), bNode *node) +{ + NodeColorBalance *n = node->storage; + int c; + + for (c = 0; c < 3; ++c) { + n->slope[c] = (2.0f - n->lift[c]) * n->gain[c]; + n->offset[c] = (n->lift[c] - 1.0f) * n->gain[c]; + n->power[c] = (n->gamma[c] != 0.0f) ? 1.0f / n->gamma[c] : 1000000.0f; + } +} + +void ntreeCompositColorBalanceSyncFromCDL(bNodeTree *UNUSED(ntree), bNode *node) +{ + NodeColorBalance *n = node->storage; + int c; + + for (c = 0; c < 3; ++c) { + float d = n->slope[c] + n->offset[c]; + n->lift[c] = (d != 0.0f ? n->slope[c] + 2.0f * n->offset[c] / d : 0.0f); + n->gain[c] = d; + n->gamma[c] = (n->power[c] != 0.0f) ? 1.0f / n->power[c] : 1000000.0f; + } +} + static void node_composit_init_colorbalance(bNodeTree *UNUSED(ntree), bNode *node) { NodeColorBalance *n = node->storage = MEM_callocN(sizeof(NodeColorBalance), "node colorbalance"); @@ -53,6 +83,10 @@ static void node_composit_init_colorbalance(bNodeTree *UNUSED(ntree), bNode *nod n->lift[0] = n->lift[1] = n->lift[2] = 1.0f; n->gamma[0] = n->gamma[1] = n->gamma[2] = 1.0f; n->gain[0] = n->gain[1] = n->gain[2] = 1.0f; + + n->slope[0] = n->slope[1] = n->slope[2] = 1.0f; + n->offset[0] = n->offset[1] = n->offset[2] = 0.0f; + n->power[0] = n->power[1] = n->power[2] = 1.0f; } void register_node_type_cmp_colorbalance(void) diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c index d073abf112a..04a56a9f505 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.c +++ b/source/blender/nodes/composite/nodes/node_composite_image.c @@ -201,7 +201,7 @@ static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node) * fail and sockets detection will go wrong. * * So we manually construct image user to be sure first - * image from sequence (that one which is set as fileanme + * image from sequence (that one which is set as filename * for image datablock) is used for sockets detection */ load_iuser.ok = 1; diff --git a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c index b110cffd080..1d411aafe68 100644 --- a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c +++ b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c @@ -48,12 +48,12 @@ static bNodeSocketTemplate cmp_node_moviedistortion_out[] = { { -1, 0, "" } }; -static const char *label(bNode *node) +static void label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen) { if (node->custom1 == 0) - return IFACE_("Undistortion"); + BLI_strncpy(label, IFACE_("Undistortion"), maxlen); else - return IFACE_("Distortion"); + BLI_strncpy(label, IFACE_("Distortion"), maxlen); } static void init(const bContext *C, PointerRNA *ptr) diff --git a/source/blender/nodes/composite/nodes/node_composite_switch.c b/source/blender/nodes/composite/nodes/node_composite_switch.c index 3384f31bfd1..d7de26730d0 100644 --- a/source/blender/nodes/composite/nodes/node_composite_switch.c +++ b/source/blender/nodes/composite/nodes/node_composite_switch.c @@ -1,6 +1,4 @@ /* - * $Id$ - * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index a8133460628..a3298de5d59 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -82,9 +82,9 @@ bNodeSocket *node_group_find_output_socket(bNode *groupnode, const char *identif } /* groups display their internal tree name as label */ -const char *node_group_label(bNode *node) +void node_group_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen) { - return (node->id) ? node->id->name + 2 : IFACE_("Missing Datablock"); + BLI_strncpy(label, (node->id) ? node->id->name + 2 : IFACE_("Missing Datablock"), maxlen); } int node_group_poll_instance(bNode *node, bNodeTree *nodetree) diff --git a/source/blender/nodes/intern/node_common.h b/source/blender/nodes/intern/node_common.h index 498da607b91..df3937f5a3e 100644 --- a/source/blender/nodes/intern/node_common.h +++ b/source/blender/nodes/intern/node_common.h @@ -37,7 +37,7 @@ struct bNodeTree; -const char *node_group_label(struct bNode *node); +void node_group_label(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen); int node_group_poll_instance(struct bNode *node, struct bNodeTree *nodetree); void ntree_update_reroute_nodes(struct bNodeTree *ntree); diff --git a/source/blender/nodes/intern/node_exec.c b/source/blender/nodes/intern/node_exec.c index 812fe5b4ae7..37018b3a98d 100644 --- a/source/blender/nodes/intern/node_exec.c +++ b/source/blender/nodes/intern/node_exec.c @@ -207,6 +207,7 @@ bNodeTreeExec *ntree_exec_begin(bNodeExecContext *context, bNodeTree *ntree, bNo /* prepare all nodes for execution */ for (n = 0, nodeexec = exec->nodeexec; n < totnodes; ++n, ++nodeexec) { node = nodeexec->node = nodelist[n]; + nodeexec->freeexecfunc = node->typeinfo->freeexecfunc; /* tag inputs */ for (sock = node->inputs.first; sock; sock = sock->next) { @@ -245,9 +246,8 @@ void ntree_exec_end(bNodeTreeExec *exec) MEM_freeN(exec->stack); for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { - if (nodeexec->node->typeinfo) - if (nodeexec->node->typeinfo->freeexecfunc) - nodeexec->node->typeinfo->freeexecfunc(nodeexec->node, nodeexec->data.data); + if (nodeexec->freeexecfunc) + nodeexec->freeexecfunc(nodeexec->data.data); } if (exec->nodeexec) diff --git a/source/blender/nodes/intern/node_exec.h b/source/blender/nodes/intern/node_exec.h index 7d76ef34934..4101c6c4c4d 100644 --- a/source/blender/nodes/intern/node_exec.h +++ b/source/blender/nodes/intern/node_exec.h @@ -51,6 +51,8 @@ struct bNodeStack; typedef struct bNodeExec { struct bNode *node; /* backpointer to node */ bNodeExecData data; + + NodeFreeExecFunction freeexecfunc; /* free function, stored in exec itself to avoid dangling node pointer access */ } bNodeExec; /* Execution Data for each instance of node tree execution */ diff --git a/source/blender/nodes/intern/node_util.c b/source/blender/nodes/intern/node_util.c index e77f0a08331..3997d9cbcac 100644 --- a/source/blender/nodes/intern/node_util.c +++ b/source/blender/nodes/intern/node_util.c @@ -36,6 +36,7 @@ #include "DNA_node_types.h" #include "BLI_listbase.h" +#include "BLI_string.h" #include "BLI_utildefines.h" #include "BLF_translation.h" @@ -82,32 +83,32 @@ void *node_initexec_curves(bNodeExecContext *UNUSED(context), bNode *node, bNode /**** Labels ****/ -const char *node_blend_label(bNode *node) +void node_blend_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen) { const char *name; RNA_enum_name(ramp_blend_items, node->custom1, &name); - return IFACE_(name); + BLI_strncpy(label, IFACE_(name), maxlen); } -const char *node_math_label(bNode *node) +void node_math_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen) { const char *name; RNA_enum_name(node_math_items, node->custom1, &name); - return IFACE_(name); + BLI_strncpy(label, IFACE_(name), maxlen); } -const char *node_vect_math_label(bNode *node) +void node_vect_math_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen) { const char *name; RNA_enum_name(node_vec_math_items, node->custom1, &name); - return IFACE_(name); + BLI_strncpy(label, IFACE_(name), maxlen); } -const char *node_filter_label(bNode *node) +void node_filter_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen) { const char *name; RNA_enum_name(node_filter_items, node->custom1, &name); - return IFACE_(name); + BLI_strncpy(label, IFACE_(name), maxlen); } void node_update_internal_links_default(bNodeTree *ntree, bNode *node) diff --git a/source/blender/nodes/intern/node_util.h b/source/blender/nodes/intern/node_util.h index 2b3f84420f9..64b2028874b 100644 --- a/source/blender/nodes/intern/node_util.h +++ b/source/blender/nodes/intern/node_util.h @@ -71,10 +71,10 @@ extern void *node_initexec_curves(struct bNodeExecContext *context, struct bNode /**** Labels ****/ -const char *node_blend_label(struct bNode *node); -const char *node_math_label(struct bNode *node); -const char *node_vect_math_label(struct bNode *node); -const char *node_filter_label(struct bNode *node); +void node_blend_label(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen); +void node_math_label(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen); +void node_vect_math_label(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen); +void node_filter_label(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen); void node_update_internal_links_default(struct bNodeTree *ntree, struct bNode *node); diff --git a/source/blender/nodes/shader/nodes/node_shader_common.c b/source/blender/nodes/shader/nodes/node_shader_common.c index 72178018de4..e229fc75686 100644 --- a/source/blender/nodes/shader/nodes/node_shader_common.c +++ b/source/blender/nodes/shader/nodes/node_shader_common.c @@ -85,7 +85,7 @@ static void *group_initexec(bNodeExecContext *context, bNode *node, bNodeInstanc return exec; } -static void group_freeexec(bNode *UNUSED(node), void *nodedata) +static void group_freeexec(void *nodedata) { bNodeTreeExec *gexec = (bNodeTreeExec *)nodedata; diff --git a/source/blender/nodes/shader/nodes/node_shader_fresnel.c b/source/blender/nodes/shader/nodes/node_shader_fresnel.c index 1e5c10968a5..c22b0f41695 100644 --- a/source/blender/nodes/shader/nodes/node_shader_fresnel.c +++ b/source/blender/nodes/shader/nodes/node_shader_fresnel.c @@ -30,6 +30,7 @@ /* **************** Fresnel ******************** */ static bNodeSocketTemplate sh_node_fresnel_in[] = { { SOCK_FLOAT, 1, N_("IOR"), 1.45f, 0.0f, 0.0f, 0.0f, 1.0f, 1000.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; @@ -40,8 +41,10 @@ static bNodeSocketTemplate sh_node_fresnel_out[] = { static int node_shader_gpu_fresnel(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { - /* todo: is incoming vector normalized? */ - return GPU_stack_link(mat, "node_fresnel", in, out, GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_VIEW_POSITION)); + if (!in[1].link) + in[1].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_fresnel", in, out, GPU_builtin(GPU_VIEW_POSITION)); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_layer_weight.c b/source/blender/nodes/shader/nodes/node_shader_layer_weight.c index 9b9c3cf705b..832ce582b4b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_layer_weight.c +++ b/source/blender/nodes/shader/nodes/node_shader_layer_weight.c @@ -31,6 +31,7 @@ static bNodeSocketTemplate sh_node_layer_weight_in[] = { { SOCK_FLOAT, 1, N_("Blend"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; @@ -40,9 +41,12 @@ static bNodeSocketTemplate sh_node_layer_weight_out[] = { { -1, 0, "" } }; -static int node_shader_gpu_layer_weight(GPUMaterial *UNUSED(mat), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *UNUSED(in), GPUNodeStack *UNUSED(out)) +static int node_shader_gpu_layer_weight(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { - return 0; + if (!in[1].link) + in[1].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_layer_weight", in, out, GPU_builtin(GPU_VIEW_POSITION)); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c index 4200f515a80..820e0f479be 100644 --- a/source/blender/nodes/shader/nodes/node_shader_material.c +++ b/source/blender/nodes/shader/nodes/node_shader_material.c @@ -299,6 +299,7 @@ static int gpu_shader_material(GPUMaterial *mat, bNode *node, bNodeExecData *UNU if (node->type == SH_NODE_MATERIAL_EXT) { out[MAT_OUT_DIFFUSE].link = shr.diff; out[MAT_OUT_SPEC].link = shr.spec; + GPU_link(mat, "set_rgb_one", &out[MAT_OUT_AO].link); } return 1; diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c b/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c index 707e295241a..2c515d587c0 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c +++ b/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c @@ -44,13 +44,26 @@ static bNodeSocketTemplate sh_node_sephsv_out[] = { { -1, 0, "" } }; +static void node_shader_exec_sephsv(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out) +{ + rgb_to_hsv(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], + &out[0]->vec[0], &out[1]->vec[0], &out[2]->vec[0]); +} + +static int gpu_shader_sephsv(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) +{ + return GPU_stack_link(mat, "separate_hsv", in, out); +} + void register_node_type_sh_sephsv(void) { static bNodeType ntype; sh_node_type_base(&ntype, SH_NODE_SEPHSV, "Separate HSV", NODE_CLASS_CONVERTOR, 0); - node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING); node_type_socket_templates(&ntype, sh_node_sephsv_in, sh_node_sephsv_out); + node_type_exec(&ntype, NULL, NULL, node_shader_exec_sephsv); + node_type_gpu(&ntype, gpu_shader_sephsv); nodeRegisterType(&ntype); } @@ -68,13 +81,26 @@ static bNodeSocketTemplate sh_node_combhsv_out[] = { { -1, 0, "" } }; +static void node_shader_exec_combhsv(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out) +{ + hsv_to_rgb(in[0]->vec[0], in[1]->vec[0], in[2]->vec[0], + &out[0]->vec[0], &out[0]->vec[1], &out[0]->vec[2]); +} + +static int gpu_shader_combhsv(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) +{ + return GPU_stack_link(mat, "combine_hsv", in, out); +} + void register_node_type_sh_combhsv(void) { static bNodeType ntype; sh_node_type_base(&ntype, SH_NODE_COMBHSV, "Combine HSV", NODE_CLASS_CONVERTOR, 0); - node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING); node_type_socket_templates(&ntype, sh_node_combhsv_in, sh_node_combhsv_out); + node_type_exec(&ntype, NULL, NULL, node_shader_exec_combhsv); + node_type_gpu(&ntype, gpu_shader_combhsv); nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/texture/nodes/node_texture_common.c b/source/blender/nodes/texture/nodes/node_texture_common.c index fec6abbf062..7e65c472eef 100644 --- a/source/blender/nodes/texture/nodes/node_texture_common.c +++ b/source/blender/nodes/texture/nodes/node_texture_common.c @@ -72,7 +72,7 @@ static void *group_initexec(bNodeExecContext *context, bNode *node, bNodeInstanc return exec; } -static void group_freeexec(bNode *UNUSED(node), void *nodedata) +static void group_freeexec(void *nodedata) { bNodeTreeExec *gexec = (bNodeTreeExec *)nodedata; diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 92fb506497f..97d88c5d189 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -2879,8 +2879,7 @@ static PyObject *bpy_bmiter_next(BPy_BMIter *self) { BMHeader *ele = BM_iter_step(&self->iter); if (ele == NULL) { - PyErr_SetString(PyExc_StopIteration, - "bpy_bmiter_next stop"); + PyErr_SetNone(PyExc_StopIteration); return NULL; } else { @@ -3722,47 +3721,11 @@ char *BPy_BMElem_StringFromHType(const char htype) /* -------------------------------------------------------------------- */ /* keep at bottom */ -/* BAD INCLUDES */ - -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_editmesh.h" -#include "DNA_scene_types.h" -#include "DNA_object_types.h" -#include "DNA_mesh_types.h" -#include "MEM_guardedalloc.h" - -/* there are cases where this warning isnt needed, otherwise it could be made into an error */ -static void bm_dealloc_warn(const char *mesh_name) -{ - PySys_WriteStdout("Modified BMesh '%.200s' from a wrapped editmesh is freed without a call " - "to bmesh.update_edit_mesh(mesh, destructive=True), this is will likely cause a crash\n", - mesh_name); -} /* this function is called on free, it should stay quite fast */ static void bm_dealloc_editmode_warn(BPy_BMesh *self) { if (self->flag & BPY_BMFLAG_IS_WRAPPED) { - /* likely editmesh */ - BMesh *bm = self->bm; - Scene *scene; - for (scene = G.main->scene.first; scene; scene = scene->id.next) { - Base *base = scene->basact; - if (base && base->object->type == OB_MESH) { - Mesh *me = base->object->data; - BMEditMesh *em = me->edit_btmesh; - if (em && em->bm == bm) { - /* not foolproof, scripter may have added/removed verts */ - if (((em->vert_index && (MEM_allocN_len(em->vert_index) / sizeof(*em->vert_index)) != bm->totvert)) || - ((em->edge_index && (MEM_allocN_len(em->edge_index) / sizeof(*em->edge_index)) != bm->totedge)) || - ((em->face_index && (MEM_allocN_len(em->face_index) / sizeof(*em->face_index)) != bm->totface))) - { - bm_dealloc_warn(me->id.name + 2); - break; - } - } - } - } + /* currently nop - this works without warnings now */ } } diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c index 30902c615a1..0ba08f3e8d0 100644 --- a/source/blender/python/bmesh/bmesh_py_types_customdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c @@ -113,6 +113,9 @@ PyDoc_STRVAR(bpy_bmlayeraccess_collection__uv_doc, PyDoc_STRVAR(bpy_bmlayeraccess_collection__color_doc, "Accessor for vertex color layer.\n\ntype: :class:`BMLayerCollection`" ); +PyDoc_STRVAR(bpy_bmlayeraccess_collection__skin_doc, +"Accessor for skin layer.\n\ntype: :class:`BMLayerCollection`" +); #ifdef WITH_FREESTYLE PyDoc_STRVAR(bpy_bmlayeraccess_collection__freestyle_edge_doc, "Accessor for Freestyle edge layer.\n\ntype: :class:`BMLayerCollection`" @@ -192,6 +195,7 @@ static PyGetSetDef bpy_bmlayeraccess_vert_getseters[] = { {(char *)"shape", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__shape_doc, (void *)CD_SHAPEKEY}, {(char *)"bevel_weight", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__bevel_weight_doc, (void *)CD_BWEIGHT}, + {(char *)"skin", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__skin_doc, (void *)CD_MVERT_SKIN}, {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; @@ -1030,6 +1034,11 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer) ret = PyFloat_FromDouble(*(float *)value); break; } + case CD_MVERT_SKIN: + { + ret = BPy_BMVertSkin_CreatePyObject(value); + break; + } default: { ret = Py_NotImplemented; /* TODO */ @@ -1147,6 +1156,11 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj } break; } + case CD_MVERT_SKIN: + { + ret = BPy_BMVertSkin_AssignPyObject(value, py_value); + break; + } default: { PyErr_SetString(PyExc_AttributeError, "readonly / unsupported type"); diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c index 06b11f02b2a..80b07a926f4 100644 --- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c @@ -248,6 +248,115 @@ PyObject *BPy_BMLoopUV_CreatePyObject(struct MLoopUV *mloopuv) /* --- End Mesh Loop UV --- */ +/* Mesh Vert Skin + * ************ */ + +#define BPy_BMVertSkin_Check(v) (Py_TYPE(v) == &BPy_BMVertSkin_Type) + +typedef struct BPy_BMVertSkin { + PyObject_VAR_HEAD + MVertSkin *data; +} BPy_BMVertSkin; + +PyDoc_STRVAR(bpy_bmvertskin_radius_doc, +"Vert skin radii (as a 2D Vector).\n\n:type: :class:`mathutils.Vector`" +); +static PyObject *bpy_bmvertskin_radius_get(BPy_BMVertSkin *self, void *UNUSED(closure)) +{ + return Vector_CreatePyObject(self->data->radius, 2, Py_WRAP, NULL); +} + +static int bpy_bmvertskin_radius_set(BPy_BMVertSkin *self, PyObject *value, void *UNUSED(closure)) +{ + float tvec[2]; + if (mathutils_array_parse(tvec, 2, 2, value, "BMVertSkin.radius") != -1) { + copy_v2_v2(self->data->radius, tvec); + return 0; + } + else { + return -1; + } +} + +PyDoc_STRVAR(bpy_bmvertskin_flag__use_root_doc, +"Use as root vertex.\n\n:type: boolean" +); +PyDoc_STRVAR(bpy_bmvertskin_flag__use_loose_doc, +"Use loose vertex.\n\n:type: boolean" +); + +static PyObject *bpy_bmvertskin_flag_get(BPy_BMVertSkin *self, void *flag_p) +{ + const int flag = GET_INT_FROM_POINTER(flag_p); + return PyBool_FromLong(self->data->flag & flag); +} + +static int bpy_bmvertskin_flag_set(BPy_BMVertSkin *self, PyObject *value, void *flag_p) +{ + const int flag = GET_INT_FROM_POINTER(flag_p); + + switch (PyLong_AsLong(value)) { + case true: + self->data->flag |= flag; + return 0; + case false: + self->data->flag &= ~flag; + return 0; + default: + PyErr_SetString(PyExc_TypeError, + "expected a boolean type 0/1"); + return -1; + } +} + +/* XXX Todo: Make root settable, currently the code to disable all other verts as roots sits within the modifier */ +static PyGetSetDef bpy_bmvertskin_getseters[] = { + /* attributes match rna_mesh_gen */ + {(char *)"radius", (getter)bpy_bmvertskin_radius_get, (setter)bpy_bmvertskin_radius_set, (char *)bpy_bmvertskin_radius_doc, NULL}, + {(char *)"use_root", (getter)bpy_bmvertskin_flag_get, (setter)NULL, (char *)bpy_bmvertskin_flag__use_root_doc, (void *)MVERT_SKIN_ROOT}, + {(char *)"use_loose", (getter)bpy_bmvertskin_flag_get, (setter)bpy_bmvertskin_flag_set, (char *)bpy_bmvertskin_flag__use_loose_doc, (void *)MVERT_SKIN_LOOSE}, + + {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ +}; + +static PyTypeObject BPy_BMVertSkin_Type = {{{0}}}; /* bm.loops.layers.uv.active */ + +static void bm_init_types_bmvertskin(void) +{ + BPy_BMVertSkin_Type.tp_basicsize = sizeof(BPy_BMVertSkin); + + BPy_BMVertSkin_Type.tp_name = "BMVertSkin"; + + BPy_BMVertSkin_Type.tp_doc = NULL; // todo + + BPy_BMVertSkin_Type.tp_getset = bpy_bmvertskin_getseters; + + BPy_BMVertSkin_Type.tp_flags = Py_TPFLAGS_DEFAULT; + + PyType_Ready(&BPy_BMVertSkin_Type); +} + +int BPy_BMVertSkin_AssignPyObject(struct MVertSkin *mvertskin, PyObject *value) +{ + if (UNLIKELY(!BPy_BMVertSkin_Check(value))) { + PyErr_Format(PyExc_TypeError, "expected BMVertSkin, not a %.200s", Py_TYPE(value)->tp_name); + return -1; + } + else { + *((MVertSkin *)mvertskin) = *(((BPy_BMVertSkin *)value)->data); + return 0; + } +} + +PyObject *BPy_BMVertSkin_CreatePyObject(struct MVertSkin *mvertskin) +{ + BPy_BMVertSkin *self = PyObject_New(BPy_BMVertSkin, &BPy_BMVertSkin_Type); + self->data = mvertskin; + return (PyObject *)self; +} + +/* --- End Mesh Vert Skin --- */ + /* Mesh Loop Color * *************** */ @@ -692,5 +801,6 @@ void BPy_BM_init_types_meshdata(void) bm_init_types_bmloopuv(); bm_init_types_bmloopcol(); bm_init_types_bmdvert(); + bm_init_types_bmvertskin(); } diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.h b/source/blender/python/bmesh/bmesh_py_types_meshdata.h index 8280e5c3bc5..07d8a46cc65 100644 --- a/source/blender/python/bmesh/bmesh_py_types_meshdata.h +++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.h @@ -44,6 +44,7 @@ struct MTexPoly; struct MLoopUV; struct MLoopCol; struct MDeformVert; +struct MVertSkin; int BPy_BMTexPoly_AssignPyObject(struct MTexPoly *mloopuv, PyObject *value); PyObject *BPy_BMTexPoly_CreatePyObject(struct MTexPoly *mloopuv); @@ -51,6 +52,9 @@ PyObject *BPy_BMTexPoly_CreatePyObject(struct MTexPoly *mloopuv); int BPy_BMLoopUV_AssignPyObject(struct MLoopUV *data, PyObject *value); PyObject *BPy_BMLoopUV_CreatePyObject(struct MLoopUV *data); +int BPy_BMVertSkin_AssignPyObject(struct MVertSkin *data, PyObject *value); +PyObject *BPy_BMVertSkin_CreatePyObject(struct MVertSkin *data); + int BPy_BMLoopColor_AssignPyObject(struct MLoopCol *data, PyObject *value); PyObject *BPy_BMLoopColor_CreatePyObject(struct MLoopCol *data); diff --git a/source/blender/python/bmesh/bmesh_py_types_select.c b/source/blender/python/bmesh/bmesh_py_types_select.c index 5069670a665..1906fc8c90e 100644 --- a/source/blender/python/bmesh/bmesh_py_types_select.c +++ b/source/blender/python/bmesh/bmesh_py_types_select.c @@ -341,8 +341,7 @@ static PyObject *bpy_bmeditseliter_next(BPy_BMEditSelIter *self) { BMEditSelection *ese = self->ese; if (ese == NULL) { - PyErr_SetString(PyExc_StopIteration, - "bpy_bmiter_next stop"); + PyErr_SetNone(PyExc_StopIteration); return NULL; } else { diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c index f7ed5fec891..c3cbe7ddbf9 100644 --- a/source/blender/python/generic/idprop_py_api.c +++ b/source/blender/python/generic/idprop_py_api.c @@ -25,15 +25,16 @@ * \ingroup pygen */ - #include <Python.h> -#include "idprop_py_api.h" #include "MEM_guardedalloc.h" #include "BLI_string.h" #include "BLI_utildefines.h" +#include "idprop_py_api.h" + + #include "BKE_idprop.h" @@ -329,29 +330,48 @@ static int idp_sequence_type(PyObject *seq_fast) return type; } -/* note: group can be a pointer array or a group. - * assume we already checked key is a string. */ -const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group, PyObject *ob) +/** + * \note group can be a pointer array or a group. + * assume we already checked key is a string. + * + * \return success. + */ +bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group, PyObject *ob) { IDProperty *prop = NULL; IDPropertyTemplate val = {0}; - const char *name = ""; + const char *name; if (name_obj) { Py_ssize_t name_size; name = _PyUnicode_AsStringAndSize(name_obj, &name_size); + + if (name == NULL) { + PyErr_Format(PyExc_KeyError, + "invalid id-property key, expected a string, not a %.200s", + Py_TYPE(name_obj)->tp_name); + return false; + } + if (name_size > MAX_IDPROP_NAME) { - return "the length of IDProperty names is limited to 63 characters"; + PyErr_SetString(PyExc_KeyError, "the length of IDProperty names is limited to 63 characters"); + return false; } } + else { + name = ""; + } if (PyFloat_Check(ob)) { val.d = PyFloat_AsDouble(ob); prop = IDP_New(IDP_DOUBLE, &val, name); } else if (PyLong_Check(ob)) { - val.i = (int)PyLong_AsLong(ob); + val.i = _PyLong_AsInt(ob); + if (val.i == -1 && PyErr_Occurred()) { + return false; + } prop = IDP_New(IDP_INT, &val, name); } else if (PyUnicode_Check(ob)) { @@ -381,14 +401,13 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty int i; if (ob_seq_fast == NULL) { - PyErr_Print(); - PyErr_Clear(); - return "error converting the sequence"; + return false; } if ((val.array.type = idp_sequence_type(ob_seq_fast)) == -1) { Py_DECREF(ob_seq_fast); - return "only floats, ints and dicts are allowed in ID property arrays"; + PyErr_SetString(PyExc_TypeError, "only floats, ints and dicts are allowed in ID property arrays"); + return false; } /* validate sequence and derive type. @@ -399,35 +418,52 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty switch (val.array.type) { case IDP_DOUBLE: + { + double *prop_data; + prop = IDP_New(IDP_ARRAY, &val, name); + prop_data = IDP_Array(prop); for (i = 0; i < val.array.len; i++) { item = PySequence_Fast_GET_ITEM(ob_seq_fast, i); - ((double *)IDP_Array(prop))[i] = (float)PyFloat_AsDouble(item); + if (((prop_data[i] = PyFloat_AsDouble(item)) == -1.0) && PyErr_Occurred()) { + Py_DECREF(ob_seq_fast); + return false; + } } break; + } case IDP_INT: + { + int *prop_data; prop = IDP_New(IDP_ARRAY, &val, name); + prop_data = IDP_Array(prop); for (i = 0; i < val.array.len; i++) { item = PySequence_Fast_GET_ITEM(ob_seq_fast, i); - ((int *)IDP_Array(prop))[i] = (int)PyLong_AsLong(item); + if (((prop_data[i] = _PyLong_AsInt(item)) == -1) && PyErr_Occurred()) { + Py_DECREF(ob_seq_fast); + return false; + } } break; + } case IDP_IDPARRAY: + { prop = IDP_NewIDPArray(name); for (i = 0; i < val.array.len; i++) { - const char *error; item = PySequence_Fast_GET_ITEM(ob_seq_fast, i); - error = BPy_IDProperty_Map_ValidateAndCreate(NULL, prop, item); - if (error) { + if (BPy_IDProperty_Map_ValidateAndCreate(NULL, prop, item) == false) { Py_DECREF(ob_seq_fast); - return error; + return false; } } break; + } default: + /* should never happen */ Py_DECREF(ob_seq_fast); - return "internal error with idp array.type"; + PyErr_SetString(PyExc_RuntimeError, "internal error with idp array.type"); + return false; } Py_DECREF(ob_seq_fast); @@ -446,23 +482,15 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty for (i = 0; i < len; i++) { key = PySequence_GetItem(keys, i); pval = PySequence_GetItem(vals, i); - if (!PyUnicode_Check(key)) { - IDP_FreeProperty(prop); - MEM_freeN(prop); - Py_XDECREF(keys); - Py_XDECREF(vals); - Py_XDECREF(key); - Py_XDECREF(pval); - return "invalid element in subgroup dict template!"; - } - if (BPy_IDProperty_Map_ValidateAndCreate(key, prop, pval)) { + if (BPy_IDProperty_Map_ValidateAndCreate(key, prop, pval) == false) { IDP_FreeProperty(prop); MEM_freeN(prop); Py_XDECREF(keys); Py_XDECREF(vals); Py_XDECREF(key); Py_XDECREF(pval); - return "invalid element in subgroup dict template!"; + /* error is already set */ + return false; } Py_XDECREF(key); Py_XDECREF(pval); @@ -471,7 +499,10 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty Py_XDECREF(vals); } else { - return "invalid property value"; + PyErr_Format(PyExc_TypeError, + "invalid id-property type %.200s not supported", + Py_TYPE(ob)->tp_name); + return false; } if (group->type == IDP_IDPARRAY) { @@ -483,7 +514,7 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty IDP_ReplaceInGroup(group, prop); } - return NULL; + return true; } int BPy_Wrap_SetMapItem(IDProperty *prop, PyObject *key, PyObject *val) @@ -494,11 +525,19 @@ int BPy_Wrap_SetMapItem(IDProperty *prop, PyObject *key, PyObject *val) } if (val == NULL) { /* del idprop[key] */ - IDProperty *pkey = IDP_GetPropertyFromGroup(prop, _PyUnicode_AsString(key)); + IDProperty *pkey; + const char *name = _PyUnicode_AsString(key); + + if (name == NULL) { + PyErr_Format(PyExc_KeyError, + "expected a string, not %.200s", + Py_TYPE(key)->tp_name); + return -1; + } + + pkey = IDP_GetPropertyFromGroup(prop, name); if (pkey) { - IDP_RemFromGroup(prop, pkey); - IDP_FreeProperty(pkey); - MEM_freeN(pkey); + IDP_FreeFromGroup(prop, pkey); return 0; } else { @@ -507,16 +546,10 @@ int BPy_Wrap_SetMapItem(IDProperty *prop, PyObject *key, PyObject *val) } } else { - const char *err; - - if (!PyUnicode_Check(key)) { - PyErr_SetString(PyExc_TypeError, "only strings are allowed as subgroup keys"); - return -1; - } + bool ok; - err = BPy_IDProperty_Map_ValidateAndCreate(key, prop, val); - if (err) { - PyErr_SetString(PyExc_KeyError, err); + ok = BPy_IDProperty_Map_ValidateAndCreate(key, prop, val); + if (ok == false) { return -1; } @@ -670,7 +703,7 @@ static PyObject *BPy_IDGroup_Pop(BPy_IDProperty *self, PyObject *value) return NULL; } - IDP_RemFromGroup(self->prop, idprop); + IDP_RemoveFromGroup(self->prop, idprop); return pyform; } @@ -1054,10 +1087,6 @@ static PyObject *BPy_IDArray_GetItem(BPy_IDArray *self, int index) static int BPy_IDArray_SetItem(BPy_IDArray *self, int index, PyObject *value) { - int i; - float f; - double d; - if (index < 0 || index >= self->prop->len) { PyErr_SetString(PyExc_RuntimeError, "index out of range!"); return -1; @@ -1065,30 +1094,33 @@ static int BPy_IDArray_SetItem(BPy_IDArray *self, int index, PyObject *value) switch (self->prop->subtype) { case IDP_FLOAT: - f = (float)PyFloat_AsDouble(value); + { + const float f = (float)PyFloat_AsDouble(value); if (f == -1 && PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, "expected a float"); return -1; } ((float *)IDP_Array(self->prop))[index] = f; break; + } case IDP_DOUBLE: - d = PyFloat_AsDouble(value); + { + const double d = PyFloat_AsDouble(value); if (d == -1 && PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, "expected a float"); return -1; } ((double *)IDP_Array(self->prop))[index] = d; break; + } case IDP_INT: - i = PyLong_AsLong(value); + { + const int i = _PyLong_AsInt(value); if (i == -1 && PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, "expected an int type"); return -1; } ((int *)IDP_Array(self->prop))[index] = i; break; + } } return 0; } @@ -1365,7 +1397,7 @@ static PyObject *BPy_Group_Iter_Next(BPy_IDGroup_Iter *self) } } else { - PyErr_SetString(PyExc_StopIteration, "iterator at end"); + PyErr_SetNone(PyExc_StopIteration); return NULL; } } diff --git a/source/blender/python/generic/idprop_py_api.h b/source/blender/python/generic/idprop_py_api.h index cb82676c4d9..279dad40456 100644 --- a/source/blender/python/generic/idprop_py_api.h +++ b/source/blender/python/generic/idprop_py_api.h @@ -71,7 +71,7 @@ int BPy_Wrap_SetMapItem(struct IDProperty *prop, PyObject *key, PyObject *val); PyObject *BPy_IDGroup_WrapData(struct ID *id, struct IDProperty *prop, struct IDProperty *parent); -const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *key, struct IDProperty *group, PyObject *ob); +bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *key, struct IDProperty *group, PyObject *ob); void IDProp_Init_Types(void); diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index 63f66afd8a8..8e90d484a9d 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -887,3 +887,19 @@ PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag) return ret; } + +/* compat only */ +#if PY_VERSION_HEX < 0x03030200 +int +_PyLong_AsInt(PyObject *obj) +{ + int overflow; + long result = PyLong_AsLongAndOverflow(obj, &overflow); + if (overflow || result > INT_MAX || result < INT_MIN) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C int"); + return -1; + } + return (int)result; +} +#endif diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h index 8928642bc3e..c6792ddfc79 100644 --- a/source/blender/python/generic/py_capi_utils.h +++ b/source/blender/python/generic/py_capi_utils.h @@ -72,4 +72,8 @@ int PyC_FlagSet_ValueFromID(PyC_FlagSet *item, const char *identifier, int int PyC_FlagSet_ToBitfield(PyC_FlagSet *items, PyObject *value, int *r_value, const char *error_prefix); PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag); +#if PY_VERSION_HEX < 0x03030200 +int _PyLong_AsInt(PyObject *obj); +#endif + #endif /* __PY_CAPI_UTILS_H__ */ diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index 2edb0aee783..21767196e11 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -53,7 +53,11 @@ #ifdef BUILD_DATE extern char build_date[]; extern char build_time[]; -extern char build_rev[]; +extern unsigned long build_commit_timestamp; +extern char build_commit_date[]; +extern char build_commit_time[]; +extern char build_hash[]; +extern char build_branch[]; extern char build_platform[]; extern char build_type[]; extern char build_cflags[]; @@ -75,7 +79,11 @@ static PyStructSequence_Field app_info_fields[] = { /* buildinfo */ {(char *)"build_date", (char *)"The date this blender instance was built"}, {(char *)"build_time", (char *)"The time this blender instance was built"}, - {(char *)"build_revision", (char *)"The subversion revision this blender instance was built with"}, + {(char *)"build_commit_timestamp", (char *)"The unix timestamp of commit this blender instance was built"}, + {(char *)"build_commit_date", (char *)"The date of commit this blender instance was built"}, + {(char *)"build_commit_time", (char *)"The time of commit this blender instance was built"}, + {(char *)"build_hash", (char *)"The commit hash this blender instance was built with"}, + {(char *)"build_branch", (char *)"The branch this blender instance was built from"}, {(char *)"build_platform", (char *)"The platform this blender instance was built for"}, {(char *)"build_type", (char *)"The type of build (Release, Debug)"}, {(char *)"build_cflags", (char *)"C compiler flags"}, @@ -107,10 +115,8 @@ static PyObject *make_app_info(void) if (app_info == NULL) { return NULL; } -#if 0 #define SetIntItem(flag) \ PyStructSequence_SET_ITEM(app_info, pos++, PyLong_FromLong(flag)) -#endif #define SetStrItem(str) \ PyStructSequence_SET_ITEM(app_info, pos++, PyUnicode_FromString(str)) #define SetBytesItem(str) \ @@ -133,7 +139,11 @@ static PyObject *make_app_info(void) #ifdef BUILD_DATE SetBytesItem(build_date); SetBytesItem(build_time); - SetBytesItem(build_rev); + SetIntItem(build_commit_timestamp); + SetBytesItem(build_commit_date); + SetBytesItem(build_commit_time); + SetBytesItem(build_hash); + SetBytesItem(build_branch); SetBytesItem(build_platform); SetBytesItem(build_type); SetBytesItem(build_cflags); @@ -143,6 +153,10 @@ static PyObject *make_app_info(void) #else SetBytesItem("Unknown"); SetBytesItem("Unknown"); + SetIntItem(0); + SetBytesItem("Unknown"); + SetBytesItem("Unknown"); + SetBytesItem("Unknown"); SetBytesItem("Unknown"); SetBytesItem("Unknown"); SetBytesItem("Unknown"); diff --git a/source/blender/python/intern/bpy_app_ffmpeg.c b/source/blender/python/intern/bpy_app_ffmpeg.c index 61e12c1cea0..2f7577928c5 100644 --- a/source/blender/python/intern/bpy_app_ffmpeg.c +++ b/source/blender/python/intern/bpy_app_ffmpeg.c @@ -89,7 +89,7 @@ static PyObject *make_ffmpeg_info(void) PyStructSequence_SET_ITEM(ffmpeg_info, pos++, obj) #ifdef WITH_FFMPEG -# define FFMPEG_LIB_VERSION(lib) { \ +# define FFMPEG_LIB_VERSION(lib) { \ curversion = lib ## _version(); \ SetObjItem(Py_BuildValue("(iii)", \ curversion >> 16, (curversion >> 8) % 256, curversion % 256)); \ @@ -97,7 +97,7 @@ static PyObject *make_ffmpeg_info(void) curversion >> 16, (curversion >> 8) % 256, curversion % 256)); \ } (void)0 #else -# define FFMPEG_LIB_VERSION(lib) { \ +# define FFMPEG_LIB_VERSION(lib) { \ SetStrItem("Unknown"); \ SetStrItem("Unknown"); \ } (void)0 diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c index 959e4a788dd..f8725d61167 100644 --- a/source/blender/python/intern/bpy_app_handlers.c +++ b/source/blender/python/intern/bpy_app_handlers.c @@ -50,7 +50,7 @@ static PyStructSequence_Field app_cb_info_fields[] = { {(char *)"render_post", (char *)"Callback list - on render (after)"}, {(char *)"render_stats", (char *)"Callback list - on printing render statistics"}, {(char *)"render_complete", (char *)"Callback list - on completion of render job"}, - {(char *)"render_cancel", (char *)"Callback list - on cancelling a render job"}, + {(char *)"render_cancel", (char *)"Callback list - on canceling a render job"}, {(char *)"load_pre", (char *)"Callback list - on loading a new blend file (before)"}, {(char *)"load_post", (char *)"Callback list - on loading a new blend file (after)"}, {(char *)"save_pre", (char *)"Callback list - on saving a blend file (before)"}, diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index d13ec3c461a..754952cd65f 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -345,7 +345,7 @@ static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args) error_val = pyrna_pydict_to_props(&ptr, kw, 0, "Converting py args to operator properties: "); if (error_val == 0) - buf = WM_operator_pystring(C, ot, &ptr, all_args); + buf = WM_operator_pystring_ex(C, NULL, all_args, ot, &ptr); WM_operator_properties_free(&ptr); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 4d4d4873390..5a87870d198 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -6044,7 +6044,7 @@ static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self) static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self) { if (self->iter.valid == false) { - PyErr_SetString(PyExc_StopIteration, "pyrna_prop_collection_iter stop"); + PyErr_SetNone(PyExc_StopIteration); return NULL; } else { diff --git a/source/blender/python/intern/bpy_rna_callback.c b/source/blender/python/intern/bpy_rna_callback.c index 1043f68dbdb..9aefe5a733f 100644 --- a/source/blender/python/intern/bpy_rna_callback.c +++ b/source/blender/python/intern/bpy_rna_callback.c @@ -203,7 +203,7 @@ PyObject *pyrna_callback_classmethod_add(PyObject *UNUSED(self), PyObject *args) return NULL; } - /* class spesific callbacks */ + /* class specific callbacks */ if (RNA_struct_is_a(srna, &RNA_Space)) { if (!PyArg_ParseTuple(args, "OOO!ss:Space.draw_handler_add", &cls, &cb_func, /* already assigned, no matter */ diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c index 8b5b74c480a..584861d4c49 100644 --- a/source/blender/python/mathutils/mathutils_geometry.c +++ b/source/blender/python/mathutils/mathutils_geometry.c @@ -1563,7 +1563,7 @@ static PyObject *M_Geometry_convex_hull_2d(PyObject *UNUSED(self), PyObject *poi int *index_map; Py_ssize_t len_ret, i; - index_map = MEM_mallocN(sizeof(*index_map) * len, __func__); + index_map = MEM_mallocN(sizeof(*index_map) * len * 2, __func__); /* Non Python function */ len_ret = BLI_convexhull_2d((const float (*)[2])points, len, index_map); diff --git a/source/blender/quicktime/CMakeLists.txt b/source/blender/quicktime/CMakeLists.txt index 0c5c4d8a9f1..b0a8c92e559 100644 --- a/source/blender/quicktime/CMakeLists.txt +++ b/source/blender/quicktime/CMakeLists.txt @@ -41,23 +41,13 @@ set(INC_SYS ${QUICKTIME_INCLUDE_DIRS} ) -if(USE_QTKIT) - set(SRC - apple/qtkit_import.m - apple/qtkit_export.m +set(SRC + apple/qtkit_import.m + apple/qtkit_export.m - quicktime_export.h - quicktime_import.h - ) -else() - set(SRC - apple/quicktime_import.c - apple/quicktime_export.c - - quicktime_export.h - quicktime_import.h - ) -endif() + quicktime_export.h + quicktime_import.h +) add_definitions(-DWITH_QUICKTIME) diff --git a/source/blender/quicktime/SConscript b/source/blender/quicktime/SConscript index a6debf06226..1fc2bc96b21 100644 --- a/source/blender/quicktime/SConscript +++ b/source/blender/quicktime/SConscript @@ -28,12 +28,8 @@ Import ('env') -if env['USE_QTKIT']: - source_files = ['apple/qtkit_import.m', +source_files = ['apple/qtkit_import.m', 'apple/qtkit_export.m'] -else: - source_files = ['apple/quicktime_import.c', - 'apple/quicktime_export.c'] incs = ['.', @@ -58,8 +54,5 @@ priorities = [200,235] defs=['WITH_QUICKTIME'] -if env['WITH_GHOST_COCOA']: - defs.append('GHOST_COCOA') - env.BlenderLib ('bf_quicktime', sources=source_files, includes=incs, defines=defs, libtype=types, priority=priorities, cc_compilerchange='/usr/bin/gcc', cxx_compilerchange='/usr/bin/g++') # always use default-Apple-gcc for objC language, gnu-compilers do not support it fully yet -else: - env.BlenderLib ('bf_quicktime', sources=source_files, includes=incs, defines=defs, libtype=types, priority=priorities) +env.BlenderLib ('bf_quicktime', sources=source_files, includes=incs, defines=defs, libtype=types, priority=priorities, cc_compilerchange='/usr/bin/gcc', cxx_compilerchange='/usr/bin/g++') # always use default-Apple-gcc for objC language, gnu-compilers do not support it fully yet + diff --git a/source/blender/quicktime/apple/quicktime_export.c b/source/blender/quicktime/apple/quicktime_export.c deleted file mode 100644 index 52ef21e4f39..00000000000 --- a/source/blender/quicktime/apple/quicktime_export.c +++ /dev/null @@ -1,927 +0,0 @@ -/* - * ***** 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 written by Rob Haarsma (phase) - * - * Contributor(s): Stefan Gartner (sgefant) - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/quicktime/apple/quicktime_export.c - * \ingroup quicktime - * - * Code to create QuickTime Movies with Blender - */ - - -#ifdef WITH_QUICKTIME -#if defined(_WIN32) || defined(__APPLE__) -#ifndef USE_QTKIT - -#include "DNA_scene_types.h" -#include "DNA_windowmanager_types.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "BKE_context.h" -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_report.h" -#include "BKE_scene.h" - -#include "BLI_blenlib.h" - -#include "BLI_sys_types.h" - -#include "IMB_imbuf.h" -#include "IMB_imbuf_types.h" - -#include "MEM_guardedalloc.h" - -#include "quicktime_import.h" -#include "quicktime_export.h" - -#ifdef _WIN32 -#include <QTML.h> -#include <Movies.h> -#include <QuickTimeComponents.h> -#include <TextUtils.h> -#include <string.h> -#include <memory.h> - -#endif /* _WIN32 */ - -#ifdef __APPLE__ -/* evil */ -#ifndef __AIFF__ -#define __AIFF__ -#endif -#include <QuickTime/Movies.h> -#include <QuickTime/QuickTimeComponents.h> -#include <fcntl.h> /* open() */ -#include <unistd.h> /* close() */ -#include <sys/stat.h> /* file permissions */ -#endif /* __APPLE__ */ - -#define kMyCreatorType FOUR_CHAR_CODE('TVOD') -#define kTrackStart 0 -#define kMediaStart 0 - -static void QT_StartAddVideoSamplesToMedia(const Rect *trackFrame, int rectx, int recty, struct ReportList *reports); -static void QT_DoAddVideoSamplesToMedia(int frame, int *pixels, int rectx, int recty, struct ReportList *reports); -static void QT_EndAddVideoSamplesToMedia(void); -static void QT_CreateMyVideoTrack(int rectx, int recty, struct ReportList *reports); -static void QT_EndCreateMyVideoTrack(struct ReportList *reports); -static void check_renderbutton_framerate(struct RenderData *rd, struct ReportList *reports); -static int get_qtcodec_settings(struct RenderData *rd, struct ReportList *reports); - -typedef struct QuicktimeExport { - - FSSpec theSpec; - short resRefNum; - Str255 qtfilename; - - Media theMedia; - Movie theMovie; - Track theTrack; - - GWorldPtr theGWorld; - PixMapHandle thePixMap; - ImageDescription **anImageDescription; - - ImBuf *ibuf; /* imagedata for Quicktime's Gworld */ - ImBuf *ibuf2; /* copy of renderdata, to be Y-flipped */ - -} QuicktimeExport; - -typedef struct QuicktimeComponentData { - - ComponentInstance theComponent; - SCTemporalSettings gTemporalSettings; - SCSpatialSettings gSpatialSettings; - SCDataRateSettings aDataRateSetting; - TimeValue duration; - long kVideoTimeScale; - -} QuicktimeComponentData; - -static struct QuicktimeExport *qtexport; -static struct QuicktimeComponentData *qtdata; - -static int sframe; - -/* RNA functions */ - -static QuicktimeCodecTypeDesc qtVideoCodecList[] = { - {kRawCodecType, 1, "Uncompressed"}, - {kJPEGCodecType, 2, "JPEG"}, - {kMotionJPEGACodecType, 3, "M-JPEG A"}, - {kMotionJPEGBCodecType, 4, "M-JPEG B"}, - {kDVCPALCodecType, 5, "DV PAL"}, - {kDVCNTSCCodecType, 6, "DV/DVCPRO NTSC"}, - {kDVCPROHD720pCodecType, 7, "DVCPRO HD 720p"}, - {kDVCPROHD1080i50CodecType, 8, "DVCPRO HD 1080i50"}, - {kDVCPROHD1080i60CodecType, 9, "DVCPRO HD 1080i60"}, - {kMPEG4VisualCodecType, 10, "MPEG4"}, - {kH263CodecType, 11, "H.263"}, - {kH264CodecType, 12, "H.264"}, - {0, 0, NULL} -}; - -static int qtVideoCodecCount = 12; - -int quicktime_get_num_videocodecs() -{ - return qtVideoCodecCount; -} - -QuicktimeCodecTypeDesc *quicktime_get_videocodecType_desc(int indexValue) -{ - if ((indexValue >= 0) && (indexValue < qtVideoCodecCount)) - return &qtVideoCodecList[indexValue]; - else - return NULL; -} - -int quicktime_rnatmpvalue_from_videocodectype(int codecType) -{ - int i; - for (i = 0; i < qtVideoCodecCount; i++) { - if (qtVideoCodecList[i].codecType == codecType) - return qtVideoCodecList[i].rnatmpvalue; - } - - return 0; -} - -int quicktime_videocodecType_from_rnatmpvalue(int rnatmpvalue) -{ - int i; - for (i = 0; i < qtVideoCodecCount; i++) { - if (qtVideoCodecList[i].rnatmpvalue == rnatmpvalue) - return qtVideoCodecList[i].codecType; - } - - return 0; -} - - - -static void CheckError(OSErr err, char *msg, ReportList *reports) -{ - if (err != noErr) { - BKE_reportf(reports, RPT_ERROR, "%s: %d", msg, err); - } -} - - -static OSErr QT_SaveCodecSettingsToScene(RenderData *rd, ReportList *reports) -{ - QTAtomContainer myContainer = NULL; - ComponentResult myErr = noErr; - Ptr myPtr; - long mySize = 0; - - CodecInfo ci; - - QuicktimeCodecData *qcd = rd->qtcodecdata; - - /* check if current scene already has qtcodec settings, and clear them */ - if (qcd) { - free_qtcodecdata(qcd); - } - else { - qcd = rd->qtcodecdata = MEM_callocN(sizeof(QuicktimeCodecData), "QuicktimeCodecData"); - } - - /* obtain all current codec settings */ - SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings); - SCSetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings); - SCSetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting); - - /* retreive codecdata from quicktime in a atomcontainer */ - myErr = SCGetSettingsAsAtomContainer(qtdata->theComponent, &myContainer); - if (myErr != noErr) { - BKE_report(reports, RPT_ERROR, "Quicktime: SCGetSettingsAsAtomContainer failed"); - goto bail; - } - - /* get the size of the atomcontainer */ - mySize = GetHandleSize((Handle)myContainer); - - /* lock and convert the atomcontainer to a *valid* pointer */ - QTLockContainer(myContainer); - myPtr = *(Handle)myContainer; - - /* copy the Quicktime data into the blender qtcodecdata struct */ - if (myPtr) { - qcd->cdParms = MEM_mallocN(mySize, "qt.cdParms"); - memcpy(qcd->cdParms, myPtr, mySize); - qcd->cdSize = mySize; - - GetCodecInfo(&ci, qtdata->gSpatialSettings.codecType, 0); - } - else { - BKE_report(reports, RPT_ERROR, "Quicktime: QT_SaveCodecSettingsToScene failed"); - } - - QTUnlockContainer(myContainer); - -bail: - if (myContainer != NULL) - QTDisposeAtomContainer(myContainer); - - return((OSErr)myErr); -} - - -static OSErr QT_GetCodecSettingsFromScene(RenderData *rd, ReportList *reports) -{ - Handle myHandle = NULL; - ComponentResult myErr = noErr; - - QuicktimeCodecData *qcd = rd->qtcodecdata; - - /* if there is codecdata in the blendfile, convert it to a Quicktime handle */ - if (qcd) { - myHandle = NewHandle(qcd->cdSize); - PtrToHand(qcd->cdParms, &myHandle, qcd->cdSize); - } - - /* restore codecsettings to the quicktime component */ - if (qcd->cdParms && qcd->cdSize) { - myErr = SCSetSettingsFromAtomContainer((GraphicsExportComponent)qtdata->theComponent, (QTAtomContainer)myHandle); - if (myErr != noErr) { - BKE_report(reports, RPT_ERROR, "Quicktime: SCSetSettingsFromAtomContainer failed"); - goto bail; - } - - /* update runtime codecsettings for use with the codec dialog */ - SCGetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting); - SCGetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings); - SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings); - - - /* Fill the render QuicktimeCodecSettigns struct */ - rd->qtcodecsettings.codecTemporalQuality = (qtdata->gTemporalSettings.temporalQuality * 100) / codecLosslessQuality; - /* Do not override scene frame rate (qtdata->gTemporalSettings.framerate) */ - rd->qtcodecsettings.keyFrameRate = qtdata->gTemporalSettings.keyFrameRate; - - rd->qtcodecsettings.codecType = qtdata->gSpatialSettings.codecType; - rd->qtcodecsettings.codec = (int)qtdata->gSpatialSettings.codec; - rd->qtcodecsettings.colorDepth = qtdata->gSpatialSettings.depth; - rd->qtcodecsettings.codecSpatialQuality = (qtdata->gSpatialSettings.spatialQuality * 100) / codecLosslessQuality; - - rd->qtcodecsettings.bitRate = qtdata->aDataRateSetting.dataRate; - rd->qtcodecsettings.minSpatialQuality = (qtdata->aDataRateSetting.minSpatialQuality * 100) / codecLosslessQuality; - rd->qtcodecsettings.minTemporalQuality = (qtdata->aDataRateSetting.minTemporalQuality * 100) / codecLosslessQuality; - /* Frame duration is already known (qtdata->aDataRateSetting.frameDuration) */ - - } - else { - BKE_report(reports, RPT_ERROR, "Quicktime: QT_GetCodecSettingsFromScene failed"); - } -bail: - if (myHandle != NULL) - DisposeHandle(myHandle); - - return((OSErr)myErr); -} - - -static OSErr QT_AddUserDataTextToMovie(Movie theMovie, char *theText, OSType theType) -{ - UserData myUserData = NULL; - Handle myHandle = NULL; - long myLength = strlen(theText); - OSErr myErr = noErr; - - /* get the movie's user data list */ - myUserData = GetMovieUserData(theMovie); - if (myUserData == NULL) - return(paramErr); - - /* copy the specified text into a new handle */ - myHandle = NewHandleClear(myLength); - if (myHandle == NULL) - return(MemError()); - - BlockMoveData(theText, *myHandle, myLength); - - /* add the data to the movie's user data */ - myErr = AddUserDataText(myUserData, myHandle, theType, 1, (short)GetScriptManagerVariable(smRegionCode)); - - /* clean up */ - DisposeHandle(myHandle); - return(myErr); -} - - -static void QT_CreateMyVideoTrack(int rectx, int recty, ReportList *reports) -{ - OSErr err = noErr; - Rect trackFrame; -// MatrixRecord myMatrix; - - trackFrame.top = 0; - trackFrame.left = 0; - trackFrame.bottom = recty; - trackFrame.right = rectx; - - qtexport->theTrack = NewMovieTrack(qtexport->theMovie, - FixRatio(trackFrame.right, 1), - FixRatio(trackFrame.bottom, 1), - 0); - CheckError(GetMoviesError(), "NewMovieTrack error", reports); - - // SetIdentityMatrix(&myMatrix); - // ScaleMatrix(&myMatrix, fixed1, Long2Fix(-1), 0, 0); - // TranslateMatrix(&myMatrix, 0, Long2Fix(trackFrame.bottom)); - // SetMovieMatrix(qtexport->theMovie, &myMatrix); - - qtexport->theMedia = NewTrackMedia(qtexport->theTrack, - VideoMediaType, - qtdata->kVideoTimeScale, - nil, - 0); - CheckError(GetMoviesError(), "NewTrackMedia error", reports); - - err = BeginMediaEdits(qtexport->theMedia); - CheckError(err, "BeginMediaEdits error", reports); - - QT_StartAddVideoSamplesToMedia(&trackFrame, rectx, recty, reports); -} - - -static void QT_EndCreateMyVideoTrack(ReportList *reports) -{ - OSErr err = noErr; - - QT_EndAddVideoSamplesToMedia(); - - err = EndMediaEdits(qtexport->theMedia); - CheckError(err, "EndMediaEdits error", reports); - - err = InsertMediaIntoTrack(qtexport->theTrack, - kTrackStart, /* track start time */ - kMediaStart, /* media start time */ - GetMediaDuration(qtexport->theMedia), - fixed1); - CheckError(err, "InsertMediaIntoTrack error", reports); -} - - -static void QT_StartAddVideoSamplesToMedia(const Rect *trackFrame, int rectx, int recty, ReportList *reports) -{ - SCTemporalSettings gTemporalSettings; - OSErr err = noErr; - - qtexport->ibuf = IMB_allocImBuf(rectx, recty, 32, IB_rect); - qtexport->ibuf2 = IMB_allocImBuf(rectx, recty, 32, IB_rect); - - err = NewGWorldFromPtr(&qtexport->theGWorld, - k32ARGBPixelFormat, - trackFrame, - NULL, NULL, 0, - (Ptr)qtexport->ibuf->rect, - rectx * 4); - CheckError(err, "NewGWorldFromPtr error", reports); - - qtexport->thePixMap = GetGWorldPixMap(qtexport->theGWorld); - LockPixels(qtexport->thePixMap); - - SCDefaultPixMapSettings(qtdata->theComponent, qtexport->thePixMap, true); - - /* workaround for crash with H.264, which requires an upgrade to - * the new callback based api for proper encoding, but that's not - * really compatible with rendering out frames sequentially */ - gTemporalSettings = qtdata->gTemporalSettings; - if (qtdata->gSpatialSettings.codecType == kH264CodecType) { - if (gTemporalSettings.temporalQuality != codecMinQuality) { - BKE_report(reports, RPT_WARNING, "Only minimum quality compression supported for Quicktime H.264"); - gTemporalSettings.temporalQuality = codecMinQuality; - } - } - - SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &gTemporalSettings); - SCSetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings); - SCSetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting); - - err = SCCompressSequenceBegin(qtdata->theComponent, qtexport->thePixMap, NULL, &qtexport->anImageDescription); - CheckError(err, "SCCompressSequenceBegin error", reports); -} - - -static void QT_DoAddVideoSamplesToMedia(int frame, int *pixels, int rectx, int recty, ReportList *reports) -{ - OSErr err = noErr; - Rect imageRect; - - int index; - int boxsize; - unsigned char *from, *to; - - short syncFlag; - long dataSize; - Handle compressedData; - Ptr myPtr; - - - /* copy and flip renderdata */ - memcpy(qtexport->ibuf2->rect, pixels, 4 * rectx * recty); - IMB_flipy(qtexport->ibuf2); - - /* get pointers to parse bitmapdata */ - myPtr = GetPixBaseAddr(qtexport->thePixMap); - imageRect = (**qtexport->thePixMap).bounds; - - from = (unsigned char *) qtexport->ibuf2->rect; - to = (unsigned char *) myPtr; - - /* parse RGBA bitmap into Quicktime's ARGB GWorld */ - boxsize = rectx * recty; - for (index = 0; index < boxsize; index++) { - to[0] = from[3]; - to[1] = from[0]; - to[2] = from[1]; - to[3] = from[2]; - to += 4, from += 4; - } - - err = SCCompressSequenceFrame(qtdata->theComponent, - qtexport->thePixMap, - &imageRect, - &compressedData, - &dataSize, - &syncFlag); - CheckError(err, "SCCompressSequenceFrame error", reports); - - err = AddMediaSample(qtexport->theMedia, - compressedData, - 0, - dataSize, - qtdata->duration, - (SampleDescriptionHandle)qtexport->anImageDescription, - 1, - syncFlag, - NULL); - CheckError(err, "AddMediaSample error", reports); -} - - -static void QT_EndAddVideoSamplesToMedia(void) -{ - SCCompressSequenceEnd(qtdata->theComponent); - - UnlockPixels(qtexport->thePixMap); - if (qtexport->theGWorld) - DisposeGWorld(qtexport->theGWorld); - - if (qtexport->ibuf) - IMB_freeImBuf(qtexport->ibuf); - - if (qtexport->ibuf2) - IMB_freeImBuf(qtexport->ibuf2); -} - - -void filepath_qt(char *string, RenderData *rd) -{ - char txt[64]; - - if (string == 0) return; - - strcpy(string, rd->pic); - BLI_path_abs(string, G.main->name); - - BLI_make_existing_file(string); - - if (BLI_strcasecmp(string + strlen(string) - 4, ".mov")) { - sprintf(txt, "%04d-%04d.mov", (rd->sfra), (rd->efra)); - strcat(string, txt); - } -} - - -int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, ReportList *reports) -{ - OSErr err = noErr; - - char name[2048]; - char theFullPath[255]; - -#ifdef __APPLE__ - int myFile; - FSRef myRef; -#else - char *qtname; -#endif - int success = 1; - - if (qtexport == NULL) qtexport = MEM_callocN(sizeof(QuicktimeExport), "QuicktimeExport"); - - if (qtdata) { - if (qtdata->theComponent) CloseComponent(qtdata->theComponent); - free_qtcomponentdata(); - } - - qtdata = MEM_callocN(sizeof(QuicktimeComponentData), "QuicktimeCodecDataExt"); - - if (rd->qtcodecdata == NULL || rd->qtcodecdata->cdParms == NULL) { - get_qtcodec_settings(rd, reports); - } - else { - qtdata->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType); - - QT_GetCodecSettingsFromScene(rd, reports); - check_renderbutton_framerate(rd, reports); - } - - sframe = (rd->sfra); - - filepath_qt(name, rd); - -#ifdef __APPLE__ - EnterMoviesOnThread(0); - strcpy(theFullPath, name); - - /* hack: create an empty file to make FSPathMakeRef() happy */ - myFile = open(theFullPath, O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRUSR | S_IWUSR); - if (myFile < 0) { - BKE_report(reports, RPT_ERROR, "Error while creating movie file!"); - /* do something? */ - } - close(myFile); - err = FSPathMakeRef((const UInt8 *)theFullPath, &myRef, 0); - CheckError(err, "FsPathMakeRef error", reports); - err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &qtexport->theSpec, NULL); - CheckError(err, "FsGetCatalogInfoRef error", reports); -#endif -#ifdef _WIN32 - qtname = get_valid_qtname(name); - strcpy(theFullPath, qtname); - strcpy(name, qtname); - MEM_freeN(qtname); - - CopyCStringToPascal(theFullPath, qtexport->qtfilename); - err = FSMakeFSSpec(0, 0L, qtexport->qtfilename, &qtexport->theSpec); -#endif - - err = CreateMovieFile(&qtexport->theSpec, - kMyCreatorType, - smCurrentScript, - createMovieFileDeleteCurFile | createMovieFileDontCreateResFile, - &qtexport->resRefNum, - &qtexport->theMovie); - CheckError(err, "CreateMovieFile error", reports); - - if (err != noErr) { - BKE_reportf(reports, RPT_ERROR, "Unable to create Quicktime movie: %s", name); - success = 0; -#ifdef __APPLE__ - ExitMoviesOnThread(); -#endif - } - else { - /* printf("Created QuickTime movie: %s\n", name); */ - - QT_CreateMyVideoTrack(rectx, recty, reports); - } - - return success; -} - - -int append_qt(struct RenderData *rd, int start_frame, int frame, int *pixels, int rectx, int recty, ReportList *reports) -{ - QT_DoAddVideoSamplesToMedia(frame, pixels, rectx, recty, reports); - return 1; -} - - -void end_qt(void) -{ - OSErr err = noErr; - short resId = movieInDataForkResID; - - if (qtexport->theMovie) { - QT_EndCreateMyVideoTrack(NULL); - - err = AddMovieResource(qtexport->theMovie, qtexport->resRefNum, &resId, qtexport->qtfilename); - CheckError(err, "AddMovieResource error", NULL); - - err = QT_AddUserDataTextToMovie(qtexport->theMovie, "Made with Blender", kUserDataTextInformation); - CheckError(err, "AddUserDataTextToMovie error", NULL); - - err = UpdateMovieResource(qtexport->theMovie, qtexport->resRefNum, resId, qtexport->qtfilename); - CheckError(err, "UpdateMovieResource error", NULL); - - if (qtexport->resRefNum) CloseMovieFile(qtexport->resRefNum); - - DisposeMovie(qtexport->theMovie); - - /* printf("Finished QuickTime movie.\n"); */ - } - -#ifdef __APPLE__ - ExitMoviesOnThread(); -#endif - - if (qtexport) { - MEM_freeN(qtexport); - qtexport = NULL; - } -} - - -void free_qtcomponentdata(void) -{ - if (qtdata) { - if (qtdata->theComponent) CloseComponent(qtdata->theComponent); - MEM_freeN(qtdata); - qtdata = NULL; - } -} - - -static void check_renderbutton_framerate(RenderData *rd, ReportList *reports) -{ - /* to keep float framerates consistent between the codec dialog and frs/sec button. */ - OSErr err; - - err = SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings); - CheckError(err, "SCGetInfo fr error", reports); - - if ( (rd->frs_sec == 24 || rd->frs_sec == 30 || rd->frs_sec == 60) && - (qtdata->gTemporalSettings.frameRate == 1571553 || - qtdata->gTemporalSettings.frameRate == 1964113 || - qtdata->gTemporalSettings.frameRate == 3928227)) - { - /* do nothing */ - } - else { - if (rd->frs_sec_base > 0) - qtdata->gTemporalSettings.frameRate = - ((float)(rd->frs_sec << 16) / rd->frs_sec_base); - } - - err = SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings); - CheckError(err, "SCSetInfo error", reports); - - if (qtdata->gTemporalSettings.frameRate == 1571553) { /* 23.98 fps */ - qtdata->kVideoTimeScale = 24000; - qtdata->duration = 1001; - } - else if (qtdata->gTemporalSettings.frameRate == 1964113) { /* 29.97 fps */ - qtdata->kVideoTimeScale = 30000; - qtdata->duration = 1001; - } - else if (qtdata->gTemporalSettings.frameRate == 3928227) { /* 59.94 fps */ - qtdata->kVideoTimeScale = 60000; - qtdata->duration = 1001; - } - else { - qtdata->kVideoTimeScale = (qtdata->gTemporalSettings.frameRate >> 16) * 100; - qtdata->duration = 100; - } -} - -void quicktime_verify_image_type(RenderData *rd, ImageFormatData *imf) -{ - if (imf->imtype == R_IMF_IMTYPE_QUICKTIME) { - if ((rd->qtcodecsettings.codecType == 0) || - (rd->qtcodecsettings.codecSpatialQuality < 0) || - (rd->qtcodecsettings.codecSpatialQuality > 100)) - { - rd->qtcodecsettings.codecType = kJPEGCodecType; - rd->qtcodecsettings.codec = (int)anyCodec; - rd->qtcodecsettings.codecSpatialQuality = (codecHighQuality * 100) / codecLosslessQuality; - rd->qtcodecsettings.codecTemporalQuality = (codecHighQuality * 100) / codecLosslessQuality; - rd->qtcodecsettings.keyFrameRate = 25; - rd->qtcodecsettings.bitRate = 5000000; /* 5 Mbps */ - } - } -} - -int get_qtcodec_settings(RenderData *rd, ReportList *reports) -{ - OSErr err = noErr; - /* erase any existing codecsetting */ - if (qtdata) { - if (qtdata->theComponent) CloseComponent(qtdata->theComponent); - free_qtcomponentdata(); - } - - /* allocate new */ - qtdata = MEM_callocN(sizeof(QuicktimeComponentData), "QuicktimeComponentData"); - qtdata->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType); - - /* get previous selected codecsetting, from qtatom or detailed settings */ - if (rd->qtcodecdata && rd->qtcodecdata->cdParms) { - QT_GetCodecSettingsFromScene(rd, reports); - } - else { - SCGetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting); - SCGetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings); - SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings); - - qtdata->gSpatialSettings.codecType = rd->qtcodecsettings.codecType; - qtdata->gSpatialSettings.codec = (CodecComponent)rd->qtcodecsettings.codec; - qtdata->gSpatialSettings.spatialQuality = (rd->qtcodecsettings.codecSpatialQuality * codecLosslessQuality) / 100; - qtdata->gTemporalSettings.temporalQuality = (rd->qtcodecsettings.codecTemporalQuality * codecLosslessQuality) / 100; - qtdata->gTemporalSettings.keyFrameRate = rd->qtcodecsettings.keyFrameRate; - qtdata->aDataRateSetting.dataRate = rd->qtcodecsettings.bitRate; - qtdata->gSpatialSettings.depth = rd->qtcodecsettings.colorDepth; - qtdata->aDataRateSetting.minSpatialQuality = (rd->qtcodecsettings.minSpatialQuality * codecLosslessQuality) / 100; - qtdata->aDataRateSetting.minTemporalQuality = (rd->qtcodecsettings.minTemporalQuality * codecLosslessQuality) / 100; - - qtdata->aDataRateSetting.frameDuration = rd->frs_sec; - SetMovieTimeScale(qtexport->theMovie, rd->frs_sec_base * 1000); - - - err = SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings); - CheckError(err, "SCSetInfo1 error", reports); - err = SCSetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings); - CheckError(err, "SCSetInfo2 error", reports); - err = SCSetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting); - CheckError(err, "SCSetInfo3 error", reports); - } - - check_renderbutton_framerate(rd, reports); - - return err; -} - -static int request_qtcodec_settings_exec(bContext *C, wmOperator *op) -{ - OSErr err = noErr; - Scene *scene = CTX_data_scene(C); - RenderData *rd = &scene->r; - - /* erase any existing codecsetting */ - if (qtdata) { - if (qtdata->theComponent) CloseComponent(qtdata->theComponent); - free_qtcomponentdata(); - } - - /* allocate new */ - qtdata = MEM_callocN(sizeof(QuicktimeComponentData), "QuicktimeComponentData"); - qtdata->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType); - - /* get previous selected codecsetting, from qtatom or detailed settings */ - if (rd->qtcodecdata && rd->qtcodecdata->cdParms) { - QT_GetCodecSettingsFromScene(rd, op->reports); - } - else { - SCGetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting); - SCGetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings); - SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings); - - qtdata->gSpatialSettings.codecType = rd->qtcodecsettings.codecType; - qtdata->gSpatialSettings.codec = (CodecComponent)rd->qtcodecsettings.codec; - qtdata->gSpatialSettings.spatialQuality = (rd->qtcodecsettings.codecSpatialQuality * codecLosslessQuality) / 100; - qtdata->gTemporalSettings.temporalQuality = (rd->qtcodecsettings.codecTemporalQuality * codecLosslessQuality) / 100; - qtdata->gTemporalSettings.keyFrameRate = rd->qtcodecsettings.keyFrameRate; - qtdata->gTemporalSettings.frameRate = ((float)(rd->frs_sec << 16) / rd->frs_sec_base); - qtdata->aDataRateSetting.dataRate = rd->qtcodecsettings.bitRate; - qtdata->gSpatialSettings.depth = rd->qtcodecsettings.colorDepth; - qtdata->aDataRateSetting.minSpatialQuality = (rd->qtcodecsettings.minSpatialQuality * codecLosslessQuality) / 100; - qtdata->aDataRateSetting.minTemporalQuality = (rd->qtcodecsettings.minTemporalQuality * codecLosslessQuality) / 100; - - qtdata->aDataRateSetting.frameDuration = rd->frs_sec; - - err = SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings); - CheckError(err, "SCSetInfo1 error", op->reports); - err = SCSetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings); - CheckError(err, "SCSetInfo2 error", op->reports); - err = SCSetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting); - CheckError(err, "SCSetInfo3 error", op->reports); - } - /* put up the dialog box - it needs to be called from the main thread */ - err = SCRequestSequenceSettings(qtdata->theComponent); - - if (err == scUserCancelled) { - return OPERATOR_FINISHED; - } - - /* update runtime codecsettings for use with the codec dialog */ - SCGetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting); - SCGetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings); - SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings); - - - /* Fill the render QuicktimeCodecSettings struct */ - rd->qtcodecsettings.codecTemporalQuality = (qtdata->gTemporalSettings.temporalQuality * 100) / codecLosslessQuality; - /* Do not override scene frame rate (qtdata->gTemporalSettings.framerate) */ - rd->qtcodecsettings.keyFrameRate = qtdata->gTemporalSettings.keyFrameRate; - - rd->qtcodecsettings.codecType = qtdata->gSpatialSettings.codecType; - rd->qtcodecsettings.codec = (int)qtdata->gSpatialSettings.codec; - rd->qtcodecsettings.colorDepth = qtdata->gSpatialSettings.depth; - rd->qtcodecsettings.codecSpatialQuality = (qtdata->gSpatialSettings.spatialQuality * 100) / codecLosslessQuality; - - rd->qtcodecsettings.bitRate = qtdata->aDataRateSetting.dataRate; - rd->qtcodecsettings.minSpatialQuality = (qtdata->aDataRateSetting.minSpatialQuality * 100) / codecLosslessQuality; - rd->qtcodecsettings.minTemporalQuality = (qtdata->aDataRateSetting.minTemporalQuality * 100) / codecLosslessQuality; - /* Frame duration is already known (qtdata->aDataRateSetting.frameDuration) */ - - QT_SaveCodecSettingsToScene(rd, op->reports); - - /* framerate jugglin' */ - if (qtdata->gTemporalSettings.frameRate == 1571553) { /* 23.98 fps */ - qtdata->kVideoTimeScale = 24000; - qtdata->duration = 1001; - - rd->frs_sec = 24; - rd->frs_sec_base = 1.001; - } - else if (qtdata->gTemporalSettings.frameRate == 1964113) { /* 29.97 fps */ - qtdata->kVideoTimeScale = 30000; - qtdata->duration = 1001; - - rd->frs_sec = 30; - rd->frs_sec_base = 1.001; - } - else if (qtdata->gTemporalSettings.frameRate == 3928227) { /* 59.94 fps */ - qtdata->kVideoTimeScale = 60000; - qtdata->duration = 1001; - - rd->frs_sec = 60; - rd->frs_sec_base = 1.001; - } - else { - double fps = qtdata->gTemporalSettings.frameRate; - - qtdata->kVideoTimeScale = 60000; - qtdata->duration = qtdata->kVideoTimeScale / (qtdata->gTemporalSettings.frameRate / 65536); - - if ((qtdata->gTemporalSettings.frameRate & 0xffff) == 0) { - rd->frs_sec = fps / 65536; - rd->frs_sec_base = 1.0; - } - else { - /* we do our very best... */ - rd->frs_sec = fps / 65536; - rd->frs_sec_base = 1.0; - } - } - - return OPERATOR_FINISHED; -} - -static int ED_operator_setqtcodec(bContext *C) -{ - return G.have_quicktime != FALSE; -} - -#if defined(__APPLE__) && defined(GHOST_COCOA) -/* Need to set up a Cocoa NSAutoReleasePool to avoid memory leak - * And it must be done in an objC file, so use a GHOST_SystemCocoa.mm function for that */ -extern int cocoa_request_qtcodec_settings_exec(bContext *C, wmOperator *op); - -int fromcocoa_request_qtcodec_settings(bContext *C, wmOperator *op) -{ - return request_qtcodec_settings_exec(C, op); -} -#endif - - -void SCENE_OT_render_data_set_quicktime_codec(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Change Codec"; - ot->description = "Change Quicktime codec Settings"; - ot->idname = "SCENE_OT_render_data_set_quicktime_codec"; - - /* api callbacks */ -#if defined(__APPLE__) && defined(GHOST_COCOA) - ot->exec = cocoa_request_qtcodec_settings_exec; -#else - ot->exec = request_qtcodec_settings_exec; -#endif - ot->poll = ED_operator_setqtcodec; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -#endif /* USE_QTKIT */ -#endif /* _WIN32 || __APPLE__ */ -#endif /* WITH_QUICKTIME */ - diff --git a/source/blender/quicktime/apple/quicktime_import.c b/source/blender/quicktime/apple/quicktime_import.c deleted file mode 100644 index 511b62d856a..00000000000 --- a/source/blender/quicktime/apple/quicktime_import.c +++ /dev/null @@ -1,833 +0,0 @@ -/* - * ***** 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 written by Rob Haarsma (phase) - * - * Contributor(s): Stefan Gartner (sgefant) - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/quicktime/apple/quicktime_import.c - * \ingroup quicktime - * - * Code to use Quicktime to load images/movies as texture. - */ - -#ifdef WITH_QUICKTIME - -#if defined(_WIN32) || defined(__APPLE__) -#ifndef USE_QTKIT - -#include "MEM_guardedalloc.h" -#include "IMB_anim.h" -#include "BLI_sys_types.h" -#include "BKE_global.h" -#include "BLI_dynstr.h" -#include "BLI_path_util.h" - -#ifdef __APPLE__ -#include <QuickTime/Movies.h> -#include <QuickTime/QuickTimeComponents.h> -#endif - -#ifdef _WIN32 -#include <Movies.h> -#include <QTML.h> -#include <TextUtils.h> -#include <QuickTimeComponents.h> -#include <QTLoadLibraryUtils.h> -#endif /* _WIN32 */ - - -#include "quicktime_import.h" -#include "quicktime_export.h" - -#define RECT_WIDTH(r) (r.right - r.left) -#define RECT_HEIGHT(r) (r.bottom - r.top) - -#define QTIME_DEBUG 0 - -typedef struct _QuicktimeMovie { - - GWorldPtr offscreenGWorld; - PixMapHandle offscreenPixMap; - Movie movie; - Rect movieBounds; - short movieRefNum; - short movieResId; - int movWidth, movHeight; - - - int framecount; - - - ImBuf *ibuf; - - - TimeValue *frameIndex; - Media theMedia; - Track theTrack; - long trackIndex; - short depth; - - int have_gw; /* ugly */ -} QuicktimeMovie; - - - -void quicktime_init(void) -{ - OSErr nerr; -#ifdef _WIN32 - QTLoadLibrary("QTCF.dll"); - nerr = InitializeQTML(0); - if (nerr != noErr) { - G.have_quicktime = FALSE; - } - else - G.have_quicktime = TRUE; -#endif /* _WIN32 */ - - /* Initialize QuickTime */ -#if defined(_WIN32) || defined(__APPLE__) - nerr = EnterMovies(); - if (nerr != noErr) - G.have_quicktime = FALSE; - else -#endif /* _WIN32 || __APPLE__ */ -#ifdef __linux__ - /* inititalize quicktime codec registry */ - lqt_registry_init(); -#endif - G.have_quicktime = TRUE; -} - - -void quicktime_exit(void) -{ -#if defined(_WIN32) || defined(__APPLE__) -#ifdef WITH_QUICKTIME - if (G.have_quicktime) { - free_qtcomponentdata(); - ExitMovies(); -#ifdef _WIN32 - TerminateQTML(); -#endif /* _WIN32 */ - } -#endif /* WITH_QUICKTIME */ -#endif /* _WIN32 || __APPLE__ */ -} - - -#ifdef _WIN32 -char *get_valid_qtname(char *name) -{ - TCHAR Buffer[MAX_PATH]; - DWORD dwRet; - char *qtname; - DynStr *ds = BLI_dynstr_new(); - - dwRet = GetCurrentDirectory(MAX_PATH, Buffer); - - if (name[1] != ':') { - char drive[2]; - - if (name[0] == '/' || name[0] == '\\') { - drive[0] = Buffer[0]; - drive[1] = '\0'; - - BLI_dynstr_append(ds, drive); - BLI_dynstr_append(ds, ":"); - BLI_dynstr_append(ds, name); - } - else { - BLI_dynstr_append(ds, Buffer); - BLI_dynstr_append(ds, "/"); - BLI_dynstr_append(ds, name); - } - } - else { - BLI_dynstr_append(ds, name); - } - - qtname = BLI_dynstr_get_cstring(ds); - BLI_dynstr_free(ds); - - return qtname; -} -#endif /* _WIN32 */ - - -int anim_is_quicktime(const char *name) -{ - FSSpec theFSSpec; - char theFullPath[255]; - - Boolean isMovieFile = false; - AliasHandle myAlias = NULL; - Component myImporter = NULL; -#ifdef __APPLE__ - FInfo myFinderInfo; - FSRef myRef; -#else - char *qtname; - Str255 dst; -#endif - OSErr err = noErr; - - // don't let quicktime movie import handle these - if (BLI_testextensie(name, ".swf") || - BLI_testextensie(name, ".txt") || - BLI_testextensie(name, ".mpg") || - BLI_testextensie(name, ".avi") || /* wouldn't be appropriate ;) */ - BLI_testextensie(name, ".tga") || - BLI_testextensie(name, ".png") || - BLI_testextensie(name, ".bmp") || - BLI_testextensie(name, ".jpg") || - BLI_testextensie(name, ".tif") || - BLI_testextensie(name, ".exr") || - BLI_testextensie(name, ".wav") || - BLI_testextensie(name, ".zip") || - BLI_testextensie(name, ".mp3")) - { - return 0; - } - - if (QTIME_DEBUG) printf("qt: checking as movie: %s\n", name); - -#ifdef __APPLE__ - strcpy(theFullPath, name); - - err = FSPathMakeRef(theFullPath, &myRef, 0); - err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL); -#else - qtname = get_valid_qtname(name); - strcpy(theFullPath, qtname); - MEM_freeN(qtname); - - CopyCStringToPascal(theFullPath, dst); - err = FSMakeFSSpec(0, 0L, dst, &theFSSpec); -#endif - -#ifdef __APPLE__ - // see whether the file type is MovieFileType; to do this, get the Finder information - err = FSpGetFInfo(&theFSSpec, &myFinderInfo); - if (err == noErr) { - if (myFinderInfo.fdType == kQTFileTypeMovie) { - return(true); - } - } -#endif - -/* on mac os x this results in using quicktime for other formats as well - * not sure whether this is intended - */ - // if it isn't a movie file, see whether the file can be imported as a movie - err = QTNewAlias(&theFSSpec, &myAlias, true); - if (err == noErr) { - if (myAlias != NULL) { - err = GetMovieImporterForDataRef(rAliasType, (Handle)myAlias, kGetMovieImporterDontConsiderGraphicsImporters, &myImporter); - DisposeHandle((Handle)myAlias); - } - } - - if ((err == noErr) && (myImporter != NULL)) { /* this file is a movie file */ - isMovieFile = true; - } - - return(isMovieFile); -} - - -void free_anim_quicktime(struct anim *anim) -{ - if (anim == NULL) return; - if (anim->qtime == NULL) return; - - UnlockPixels(anim->qtime->offscreenPixMap); - - if (anim->qtime->have_gw) - DisposeGWorld(anim->qtime->offscreenGWorld); - if (anim->qtime->ibuf) - IMB_freeImBuf(anim->qtime->ibuf); - - DisposeMovie(anim->qtime->movie); - CloseMovieFile(anim->qtime->movieRefNum); - - if (anim->qtime->frameIndex) MEM_freeN(anim->qtime->frameIndex); - if (anim->qtime) MEM_freeN(anim->qtime); - - anim->qtime = NULL; - - anim->duration = 0; -} - - -static OSErr QT_get_frameIndexes(struct anim *anim) -{ - int i; - OSErr anErr = noErr; - OSType media = VideoMediaType; - TimeValue nextTime = 0; - TimeValue startPoint; - TimeValue tmpstartPoint; - long sampleCount = 0; - - startPoint = -1; - - GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample + nextTimeEdgeOK, (TimeValue)1, &media, 0, - 1, &startPoint, NULL); - - tmpstartPoint = startPoint; - - anim->qtime->framecount = 0; - - sampleCount = GetMediaSampleCount(anim->qtime->theMedia); - anErr = GetMoviesError(); - if (anErr != noErr) return anErr; - - anim->qtime->framecount = sampleCount; - - anim->qtime->frameIndex = (TimeValue *) MEM_callocN(sizeof(TimeValue) * anim->qtime->framecount, "qtframeindex"); - - //rewind - GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample, 1, &media, (TimeValue)1, 0, &tmpstartPoint, NULL); - - anim->qtime->frameIndex[0] = startPoint; - for (i = 1; i < anim->qtime->framecount; i++) { - nextTime = 0; - GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample, 1, &media, startPoint, 0, &nextTime, NULL); - startPoint = nextTime; - anim->qtime->frameIndex[i] = nextTime; - } - - anErr = GetMoviesError(); - return anErr; -} - - -ImBuf *qtime_fetchibuf(struct anim *anim, int position) -{ - PixMapHandle myPixMap = NULL; - Ptr myPtr; - - register int index; - register int boxsize; - - register uint32_t *readPos; - register uint32_t *changePos; - - ImBuf *ibuf = NULL; - unsigned int *rect; -#ifdef __APPLE__ - unsigned char *from, *to; -#endif -#ifdef _WIN32 - unsigned char *crect; -#endif - - if (anim == NULL) { - return (NULL); - } - - ibuf = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect); - rect = ibuf->rect; - - SetMovieTimeValue(anim->qtime->movie, anim->qtime->frameIndex[position]); - UpdateMovie(anim->qtime->movie); - MoviesTask(anim->qtime->movie, 0); - - - myPixMap = GetGWorldPixMap(anim->qtime->offscreenGWorld); - myPtr = GetPixBaseAddr(myPixMap); - - if (myPtr == NULL) { - printf("Error reading frame from Quicktime"); - IMB_freeImBuf(ibuf); - return NULL; - } - - boxsize = anim->x * anim->y; - readPos = (uint32_t *) myPtr; - changePos = (uint32_t *) rect; //textureIMBuf *THE* data pointerrr - -#ifdef __APPLE__ - // Swap alpha byte to the end, so ARGB become RGBA; - from = (unsigned char *)readPos; - to = (unsigned char *)changePos; - - for (index = 0; index < boxsize; index++, from += 4, to += 4) { - to[3] = from[0]; - to[0] = from[1]; - to[1] = from[2]; - to[2] = from[3]; - } -#endif - -#ifdef _WIN32 - for (index = 0; index < boxsize; index++, changePos++, readPos++) - *(changePos) = *(readPos); - - if (anim->qtime->depth < 32) { - //add alpha to ibuf - boxsize = anim->x * anim->y * 4; - crect = (unsigned char *) rect; - for (index = 0; index < boxsize; index += 4, crect += 4) { - crect[3] = 0xFF; - } - } -#endif - - IMB_flipy(ibuf); - return ibuf; -} - - -// following two functions only here to get movie pixeldepth - -static int GetFirstVideoMedia(struct anim *anim) -{ - long numTracks; - OSType mediaType; - - numTracks = GetMovieTrackCount(anim->qtime->movie); - - for (anim->qtime->trackIndex = 1; anim->qtime->trackIndex <= numTracks; (anim->qtime->trackIndex)++) { - anim->qtime->theTrack = GetMovieIndTrack(anim->qtime->movie, anim->qtime->trackIndex); - - if (anim->qtime->theTrack) - anim->qtime->theMedia = GetTrackMedia(anim->qtime->theTrack); - - if (anim->qtime->theMedia) - GetMediaHandlerDescription(anim->qtime->theMedia, &mediaType, nil, nil); - if (mediaType == VideoMediaType) return 1; - } - - anim->qtime->trackIndex = 0; // trackIndex can't be 0 - return 0; // went through all tracks and no video -} - -static short GetFirstVideoTrackPixelDepth(struct anim *anim) -{ - SampleDescriptionHandle imageDescH = (SampleDescriptionHandle)NewHandle(sizeof(Handle)); -// long trackIndex = 0; /*unused*/ - - if (!GetFirstVideoMedia(anim)) - return -1; - - if (!anim->qtime->trackIndex || !anim->qtime->theMedia) return -1; // we need both - GetMediaSampleDescription(anim->qtime->theMedia, anim->qtime->trackIndex, imageDescH); - - return (*(ImageDescriptionHandle)imageDescH)->depth; -} - - -int startquicktime(struct anim *anim) -{ - FSSpec theFSSpec; - - OSErr err = noErr; - char theFullPath[255]; -#ifdef __APPLE__ - FSRef myRef; -#else - char *qtname; - Str255 dst; -#endif - short depth = 0; - - anim->qtime = MEM_callocN(sizeof(QuicktimeMovie), "animqt"); - anim->qtime->have_gw = FALSE; - - if (anim->qtime == NULL) { - if (QTIME_DEBUG) printf("Can't alloc qtime: %s\n", anim->name); - return -1; - } - - if (QTIME_DEBUG) printf("qt: attempting to load as movie %s\n", anim->name); - -#ifdef __APPLE__ - strcpy(theFullPath, anim->name); - - err = FSPathMakeRef(theFullPath, &myRef, 0); - err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL); -#else - qtname = get_valid_qtname(anim->name); - strcpy(theFullPath, qtname); - MEM_freeN(qtname); - - CopyCStringToPascal(theFullPath, dst); - FSMakeFSSpec(0, 0L, dst, &theFSSpec); -#endif - - err = OpenMovieFile(&theFSSpec, &anim->qtime->movieRefNum, fsRdPerm); - - if (err == noErr) { - if (QTIME_DEBUG) printf("qt: movie opened\n"); - err = NewMovieFromFile(&anim->qtime->movie, - anim->qtime->movieRefNum, - &anim->qtime->movieResId, NULL, newMovieActive, NULL); - } - - if (err) { - if (QTIME_DEBUG) printf("qt: bad movie %s\n", anim->name); - if (anim->qtime->movie) { - DisposeMovie(anim->qtime->movie); - MEM_freeN(anim->qtime); - if (QTIME_DEBUG) printf("qt: can't load %s\n", anim->name); - return -1; - } - } - - GetMovieBox(anim->qtime->movie, &anim->qtime->movieBounds); - anim->x = anim->qtime->movWidth = RECT_WIDTH(anim->qtime->movieBounds); - anim->y = anim->qtime->movHeight = RECT_HEIGHT(anim->qtime->movieBounds); - if (QTIME_DEBUG) printf("qt: got bounds %s\n", anim->name); - - if (anim->x == 0 && anim->y == 0) { - if (QTIME_DEBUG) printf("qt: error, no dimensions\n"); - free_anim_quicktime(anim); - return -1; - } - - anim->qtime->ibuf = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect); - -#ifdef _WIN32 - err = NewGWorldFromPtr(&anim->qtime->offscreenGWorld, - k32RGBAPixelFormat, - &anim->qtime->movieBounds, - NULL, NULL, 0, - (unsigned char *)anim->qtime->ibuf->rect, - anim->x * 4); -#else - err = NewGWorldFromPtr(&anim->qtime->offscreenGWorld, - k32ARGBPixelFormat, - &anim->qtime->movieBounds, - NULL, NULL, 0, - (unsigned char *)anim->qtime->ibuf->rect, - anim->x * 4); -#endif /* _WIN32 */ - - if (err == noErr) { - anim->qtime->have_gw = TRUE; - - SetMovieGWorld(anim->qtime->movie, - anim->qtime->offscreenGWorld, - GetGWorldDevice(anim->qtime->offscreenGWorld)); - SetMoviePlayHints(anim->qtime->movie, hintsHighQuality, hintsHighQuality); - - // sets Media and Track! - depth = GetFirstVideoTrackPixelDepth(anim); - - QT_get_frameIndexes(anim); - } - - anim->qtime->offscreenPixMap = GetGWorldPixMap(anim->qtime->offscreenGWorld); - LockPixels(anim->qtime->offscreenPixMap); - - //fill blender's anim struct - anim->qtime->depth = depth; - - anim->duration = anim->qtime->framecount; - anim->params = 0; - - anim->interlacing = 0; - anim->orientation = 0; - anim->framesize = anim->x * anim->y * 4; - - anim->curposition = 0; - - if (QTIME_DEBUG) printf("qt: load %s %dx%dx%d frames %d\n", anim->name, anim->qtime->movWidth, - anim->qtime->movHeight, anim->qtime->depth, anim->qtime->framecount); - - return 0; -} - -int imb_is_a_quicktime(char *name) -{ - GraphicsImportComponent theImporter = NULL; - - FSSpec theFSSpec; -#ifdef _WIN32 - Str255 dst; /*unused*/ -#endif - char theFullPath[255]; - -// Boolean isMovieFile = false; /*unused*/ -// AliasHandle myAlias = NULL; /*unused*/ -// Component myImporter = NULL; /*unused*/ -#ifdef __APPLE__ -// FInfo myFinderInfo; /*unused*/ - FSRef myRef; -#endif - OSErr err = noErr; - - if (!G.have_quicktime) return 0; - - if (QTIME_DEBUG) printf("qt: checking as image %s\n", name); - - // don't let quicktime image import handle these - if (BLI_testextensie(name, ".swf") || - BLI_testextensie(name, ".txt") || - BLI_testextensie(name, ".mpg") || - BLI_testextensie(name, ".wav") || - BLI_testextensie(name, ".mov") || // not as image, doesn't work - BLI_testextensie(name, ".avi") || - BLI_testextensie(name, ".mp3")) - { - return 0; - } - - strcpy(theFullPath, name); -#ifdef __APPLE__ - err = FSPathMakeRef(theFullPath, &myRef, 0); - err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL); -#else - CopyCStringToPascal(theFullPath, dst); - err = FSMakeFSSpec(0, 0L, dst, &theFSSpec); -#endif - - GetGraphicsImporterForFile(&theFSSpec, &theImporter); - - if (theImporter != NULL) { - if (QTIME_DEBUG) printf("qt: %s valid\n", name); - CloseComponent(theImporter); - return 1; - } - - return 0; -} - -ImBuf *imb_quicktime_decode(unsigned char *mem, int size, int flags) -{ - Rect myRect; - OSErr err = noErr; - GraphicsImportComponent gImporter = NULL; - - ImageDescriptionHandle desc; - - ComponentInstance dataHandler; - PointerDataRef dataref; - - int x, y, depth; - int have_gw = FALSE; - ImBuf *ibuf = NULL; -// ImBuf *imbuf = NULL; /*unused*/ - GWorldPtr offGWorld; - PixMapHandle myPixMap = NULL; - -#ifdef __APPLE__ - Ptr myPtr; - - register int index; - register int boxsize; - - register uint32_t *readPos; - register uint32_t *changePos; - - ImBuf *wbuf = NULL; - unsigned int *rect; - unsigned char *from, *to; -#endif - - if (mem == NULL || !G.have_quicktime) - goto bail; - - if (QTIME_DEBUG) printf("qt: attempt to load mem as image\n"); - - dataref = (PointerDataRef)NewHandle(sizeof(PointerDataRefRecord)); - (**dataref).data = mem; - (**dataref).dataLength = size; - - err = OpenADataHandler((Handle)dataref, - PointerDataHandlerSubType, - nil, - (OSType)0, - nil, - kDataHCanRead, - &dataHandler); - if (err != noErr) { - if (QTIME_DEBUG) printf("no datahandler\n"); - goto bail; - } - - err = GetGraphicsImporterForDataRef((Handle)dataref, PointerDataHandlerSubType, &gImporter); - if (err != noErr) { - if (QTIME_DEBUG) printf("no graphimport\n"); - goto bail; - } - - err = GraphicsImportGetNaturalBounds(gImporter, &myRect); - if (err != noErr) { - if (QTIME_DEBUG) printf("no bounds\n"); - goto bail; - } - - err = GraphicsImportGetImageDescription(gImporter, &desc); - if (err != noErr) { - if (QTIME_DEBUG) printf("no imagedescription\n"); - goto bail; - } - - x = RECT_WIDTH(myRect); - y = RECT_HEIGHT(myRect); - depth = (**desc).depth; - - if (flags & IB_test) { - ibuf = IMB_allocImBuf(x, y, depth, 0); - ibuf->ftype = QUICKTIME; - DisposeHandle((Handle)dataref); - if (gImporter != NULL) CloseComponent(gImporter); - return ibuf; - } - -#ifdef __APPLE__ - ibuf = IMB_allocImBuf(x, y, 32, IB_rect); - wbuf = IMB_allocImBuf(x, y, 32, IB_rect); - - err = NewGWorldFromPtr(&offGWorld, - k32ARGBPixelFormat, - &myRect, NULL, NULL, 0, - (unsigned char *)wbuf->rect, x * 4); -#else - - ibuf = IMB_allocImBuf(x, y, 32, IB_rect); - - err = NewGWorldFromPtr(&offGWorld, - k32RGBAPixelFormat, - &myRect, NULL, NULL, 0, - (unsigned char *)ibuf->rect, x * 4); -#endif - - if (err != noErr) { - if (QTIME_DEBUG) printf("no newgworld\n"); - goto bail; - } - else { - have_gw = TRUE; - } - - GraphicsImportSetGWorld(gImporter, offGWorld, NULL); - GraphicsImportDraw(gImporter); - -#ifdef __APPLE__ - rect = ibuf->rect; - - myPixMap = GetGWorldPixMap(offGWorld); - LockPixels(myPixMap); - myPtr = GetPixBaseAddr(myPixMap); - - if (myPtr == NULL) { - printf("Error reading frame from Quicktime"); - IMB_freeImBuf(ibuf); - return NULL; - } - - boxsize = x * y; - readPos = (uint32_t *) myPtr; - changePos = (uint32_t *) rect; - - // Swap alpha byte to the end, so ARGB become RGBA; - from = (unsigned char *)readPos; - to = (unsigned char *)changePos; - - for (index = 0; index < boxsize; index++, from += 4, to += 4) { - to[3] = from[0]; - to[0] = from[1]; - to[1] = from[2]; - to[2] = from[3]; - } -#endif - -bail: - - DisposeHandle((Handle)dataref); - UnlockPixels(myPixMap); - if (have_gw) DisposeGWorld(offGWorld); - -#ifdef __APPLE__ - if (wbuf) { - IMB_freeImBuf(wbuf); - wbuf = NULL; - } -#endif - - if (gImporter != NULL) CloseComponent(gImporter); - - if (err != noErr) { - if (QTIME_DEBUG) printf("quicktime import unsuccesfull\n"); - if (ibuf) { - IMB_freeImBuf(ibuf); - ibuf = NULL; - } - } - - if (ibuf) { - -#ifdef _WIN32 -// add non transparent alpha layer, so images without alpha show up in the sequence editor -// exception for GIF images since these can be transparent without being 32 bit -// (might also be nescessary for OSX) - int i; - int box = x * y; - unsigned char *arect = (unsigned char *) ibuf->rect; - - if (depth < 32 && (**desc).cType != kGIFCodecType) { - for (i = 0; i < box; i++, arect += 4) - arect[3] = 0xFF; - } -#endif - - IMB_flipy(ibuf); - ibuf->ftype = QUICKTIME; - } - return ibuf; -} - -#endif /* USE_QTKIT */ -#endif /* _WIN32 || __APPLE__ */ - -#endif /* WITH_QUICKTIME */ - - -#if 0 - -struct ImageDescription { - long idSize; - CodecType cType; - long resvd1; - short resvd2; - short dataRefIndex; - short version; - short revisionLevel; - long vendor; - CodecQ temporalQuality; - CodecQ spatialQuality; - short width; - short height; - Fixed hRes; - Fixed vRes; - long dataSize; - short frameCount; - Str31 name; - short depth; - short clutID; -}; - -#endif // 0 diff --git a/source/blender/quicktime/quicktime_export.h b/source/blender/quicktime/quicktime_export.h index 55323c05278..35e424b9081 100644 --- a/source/blender/quicktime/quicktime_export.h +++ b/source/blender/quicktime/quicktime_export.h @@ -69,25 +69,18 @@ QuicktimeCodecTypeDesc *quicktime_get_videocodecType_desc(int indexValue); int quicktime_rnatmpvalue_from_videocodectype(int codecType); int quicktime_videocodecType_from_rnatmpvalue(int rnatmpvalue); -#ifdef USE_QTKIT /*Audio codec type*/ int quicktime_get_num_audiocodecs(void); QuicktimeCodecTypeDesc *quicktime_get_audiocodecType_desc(int indexValue); int quicktime_rnatmpvalue_from_audiocodectype(int codecType); int quicktime_audiocodecType_from_rnatmpvalue(int rnatmpvalue); -#endif - -#ifndef USE_QTKIT -void SCENE_OT_render_data_set_quicktime_codec(struct wmOperatorType *ot); //Operator to raise quicktime standard dialog to request codec settings -#endif - void free_qtcomponentdata(void); void makeqtstring(struct RenderData *rd, char *string); //for playanim.c -#if (defined(USE_QTKIT) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 && __LP64__) +#if (MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 && __LP64__) //Include the quicktime codec types constants that are missing in QTKitDefines.h enum { kRawCodecType = 'raw ', diff --git a/source/blender/quicktime/quicktime_import.h b/source/blender/quicktime/quicktime_import.h index 4ec435db982..e45720496cc 100644 --- a/source/blender/quicktime/quicktime_import.h +++ b/source/blender/quicktime/quicktime_import.h @@ -42,18 +42,6 @@ #include "../imbuf/IMB_imbuf.h" #include "../imbuf/IMB_imbuf_types.h" -#ifndef USE_QTKIT -# ifndef __MOVIES__ -# ifdef _WIN32 -# include <Movies.h> -# elif defined(__APPLE__) -# define __CARBONSOUND__ -# import <Carbon/Carbon.h> -# include <QuickTime/Movies.h> -# endif -# endif /* __MOVIES__ */ -#endif /* USE_QTKIT */ - #ifdef _WIN32 # ifndef __FIXMATH__ # include <FixMath.h> diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt index 94a95974009..db23cd97b74 100644 --- a/source/blender/render/CMakeLists.txt +++ b/source/blender/render/CMakeLists.txt @@ -98,7 +98,6 @@ set(SRC intern/include/raycounter.h intern/include/rayobject.h intern/include/rayintersection.h - intern/include/raycounter.h intern/include/render_types.h intern/include/render_result.h intern/include/rendercore.h diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 79826a63690..109524c9814 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -247,10 +247,6 @@ int RE_WriteEnvmapResult(struct ReportList *reports, struct Scene *scene, struct /* do a full sample buffer compo */ void RE_MergeFullSample(struct Render *re, struct Main *bmain, struct Scene *sce, struct bNodeTree *ntree); -/* ancient stars function... go away! */ -void RE_make_stars(struct Render *re, struct Scene *scenev3d, void (*initfunc)(void), - void (*vertexfunc)(const float *), void (*termfunc)(void)); - /* display and event callbacks */ void RE_display_init_cb (struct Render *re, void *handle, void (*f)(void *handle, RenderResult *rr)); void RE_display_clear_cb(struct Render *re, void *handle, void (*f)(void *handle, RenderResult *rr)); diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c index 72e47f89bb2..c150133b276 100644 --- a/source/blender/render/intern/source/bake.c +++ b/source/blender/render/intern/source/bake.c @@ -322,6 +322,10 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua if (bs->rect_mask) { bs->rect_mask[bs->rectx * y + x] = FILTER_MASK_USED; } + + if (bs->do_update) { + *bs->do_update = true; + } } static void bake_displacement(void *handle, ShadeInput *UNUSED(shi), float dist, int x, int y) @@ -1141,7 +1145,7 @@ struct Image *RE_bake_shade_get_image(void) static void add_single_heights_margin(const ImBuf *ibuf, const char *mask, float *heights_buffer) { - int x ,y; + int x, y; for (y = 0; y < ibuf->y; y++) { for (x = 0; x < ibuf->x; x++) { @@ -1200,11 +1204,11 @@ float RE_bake_make_derivative(ImBuf *ibuf, float *heights_buffer, const char *ma if (auto_range_fit) { /* If automatic range fitting is enabled. */ for (y = 0; y < ibuf->y; y++) { - const int Yu = y == (ibuf->y - 1) ? (ibuf->y - 1) : (y+1); + const int Yu = y == (ibuf->y - 1) ? (ibuf->y - 1) : (y + 1); const int Yc = y; const int Yd = y == 0 ? 0 : (y - 1); - for (x= 0; x < ibuf->x; x++) { + for (x = 0; x < ibuf->x; x++) { const int Xl = x == 0 ? 0 : (x - 1); const int Xc = x; const int Xr = x == (ibuf->x - 1) ? (ibuf->x - 1) : (x + 1); @@ -1244,11 +1248,11 @@ float RE_bake_make_derivative(ImBuf *ibuf, float *heights_buffer, const char *ma /* Output derivatives. */ auto_range_fit &= (max_num_deriv > 0); for (y = 0; y < ibuf->y; y++) { - const int Yu= y==(ibuf->y-1) ? (ibuf->y-1) : (y+1); - const int Yc= y; - const int Yd= y==0 ? 0 : (y-1); + const int Yu = y == (ibuf->y - 1) ? (ibuf->y - 1) : (y + 1); + const int Yc = y; + const int Yd = y == 0 ? 0 : (y - 1); - for(x= 0; x<ibuf->x; x++) { + for (x = 0; x < ibuf->x; x++) { const int Xl = x == 0 ? 0 : (x - 1); const int Xc = x; const int Xr = x == (ibuf->x - 1) ? (ibuf->x - 1) : (x + 1); @@ -1269,14 +1273,15 @@ float RE_bake_make_derivative(ImBuf *ibuf, float *heights_buffer, const char *ma /* Early out. */ index = ibuf->x * y + x; - if (mask[index] != FILTER_MASK_USED){ + if (mask[index] != FILTER_MASK_USED) { continue; } if (auto_range_fit) { deriv_x /= max_num_deriv; deriv_y /= max_num_deriv; - } else { + } + else { deriv_x *= (fmult / denom); deriv_y *= (fmult / denom); } @@ -1296,8 +1301,9 @@ float RE_bake_make_derivative(ImBuf *ibuf, float *heights_buffer, const char *ma rrgbf[1] = deriv_y; rrgbf[2] = 0.0f; rrgbf[3] = 1.0f; - } else { - char *rrgb = (char*)ibuf->rect + index * 4; + } + else { + char *rrgb = (char *)ibuf->rect + index * 4; rrgb[0] = FTOCHAR(deriv_x); rrgb[1] = FTOCHAR(deriv_y); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 18f658fb169..fb9f96b0ef7 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -135,206 +135,11 @@ #endif /* ------------------------------------------------------------------------- */ - -/* Stuff for stars. This sits here because it uses gl-things. Part of - * this code may move down to the converter. */ -/* ------------------------------------------------------------------------- */ -/* this is a bad beast, since it is misused by the 3d view drawing as well. */ - -static HaloRen *initstar(Render *re, ObjectRen *obr, const float vec[3], float hasize) -{ - HaloRen *har; - float hoco[4]; - - projectverto(vec, re->winmat, hoco); - - har= RE_findOrAddHalo(obr, obr->tothalo++); - - /* projectvert is done in function zbufvlaggen again, because of parts */ - copy_v3_v3(har->co, vec); - har->hasize= hasize; - - har->zd= 0.0; - har->pool = re->pool; - - return har; -} - -/* there must be a 'fixed' amount of stars generated between - * near and far - * all stars must by preference lie on the far and solely - * differ in clarity/color - */ - -void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void), - void (*vertexfunc)(const float *), void (*termfunc)(void)) -{ - extern unsigned char hash[512]; - ObjectRen *obr= NULL; - World *wrld= NULL; - HaloRen *har; - Scene *scene; - Object *camera; - Camera *cam; - RNG *rng; - double dblrand, hlfrand; - float vec[4], fx, fy, fz; - float fac, starmindist, clipend; - float mat[4][4], stargrid, maxrand, maxjit, force, alpha; - int x, y, z, sx, sy, sz, ex, ey, ez, done = FALSE; - unsigned int totstar= 0; - - if (initfunc) { - scene= scenev3d; - wrld= scene->world; - } - else { - scene= re->scene; - wrld= &(re->wrld); - } - - stargrid = wrld->stardist; /* distance between stars */ - maxrand = 2.0; /* amount a star can be shifted (in grid units) */ - maxjit = (wrld->starcolnoise); /* amount a color is being shifted */ - - /* size of stars */ - force = ( wrld->starsize ); - - /* minimal free space (starting at camera) */ - starmindist= wrld->starmindist; - - if (stargrid <= 0.10f) return; - - if (re) re->flag |= R_HALO; - else stargrid *= 1.0f; /* then it draws fewer */ - - if (re) invert_m4_m4(mat, re->viewmat); - else unit_m4(mat); - - /* BOUNDING BOX CALCULATION - * bbox goes from z = loc_near_var | loc_far_var, - * x = -z | +z, - * y = -z | +z - */ - - camera= re ? RE_GetCamera(re) : scene->camera; - - if (camera==NULL || camera->type != OB_CAMERA) - return; - - cam = camera->data; - clipend = cam->clipend; - - /* convert to grid coordinates */ - - sx = ((mat[3][0] - clipend) / stargrid) - maxrand; - sy = ((mat[3][1] - clipend) / stargrid) - maxrand; - sz = ((mat[3][2] - clipend) / stargrid) - maxrand; - - ex = ((mat[3][0] + clipend) / stargrid) + maxrand; - ey = ((mat[3][1] + clipend) / stargrid) + maxrand; - ez = ((mat[3][2] + clipend) / stargrid) + maxrand; - - dblrand = maxrand * stargrid; - hlfrand = 2.0 * dblrand; - - if (initfunc) { - initfunc(); - } - - if (re) /* add render object for stars */ - obr= RE_addRenderObject(re, NULL, NULL, 0, 0, 0); - - rng = BLI_rng_new(0); - - for (x = sx, fx = sx * stargrid; x <= ex; x++, fx += stargrid) { - for (y = sy, fy = sy * stargrid; y <= ey; y++, fy += stargrid) { - for (z = sz, fz = sz * stargrid; z <= ez; z++, fz += stargrid) { - - BLI_rng_seed(rng, (hash[z & 0xff] << 24) + (hash[y & 0xff] << 16) + (hash[x & 0xff] << 8)); - vec[0] = fx + (hlfrand * BLI_rng_get_double(rng)) - dblrand; - vec[1] = fy + (hlfrand * BLI_rng_get_double(rng)) - dblrand; - vec[2] = fz + (hlfrand * BLI_rng_get_double(rng)) - dblrand; - vec[3] = 1.0; - - if (vertexfunc) { - if (done & 1) vertexfunc(vec); - done++; - } - else { - if (re) - mul_m4_v3(re->viewmat, vec); - - /* in vec are global coordinates - * calculate distance to camera - * and using that, define the alpha - */ - alpha = len_v3(vec); - - if (alpha >= clipend) alpha = 0.0; - else if (alpha <= starmindist) alpha = 0.0; - else if (alpha <= 2.0f * starmindist) { - alpha = (alpha - starmindist) / starmindist; - } - else { - alpha -= 2.0f * starmindist; - alpha /= (clipend - 2.0f * starmindist); - alpha = 1.0f - alpha; - } - - - if (alpha != 0.0f) { - fac = force * BLI_rng_get_double(rng); - - har = initstar(re, obr, vec, fac); - - if (har) { - har->alfa = sqrt(sqrt(alpha)); - har->add= 255; - har->r = har->g = har->b = 1.0; - if (maxjit) { - har->r += ((maxjit * BLI_rng_get_double(rng)) ) - maxjit; - har->g += ((maxjit * BLI_rng_get_double(rng)) ) - maxjit; - har->b += ((maxjit * BLI_rng_get_double(rng)) ) - maxjit; - } - har->hard = 32; - har->lay= -1; - har->type |= HA_ONLYSKY; - done++; - } - } - } - - /* break out of the loop if generating stars takes too long */ - if (re && !(totstar % 1000000)) { - if (re->test_break(re->tbh)) { - x= ex + 1; - y= ey + 1; - z= ez + 1; - } - } - - totstar++; - } - /* do not call blender_test_break() here, since it is used in UI as well, confusing the callback system */ - /* main cause is G.is_break of course, a global again... (ton) */ - } - } - if (termfunc) termfunc(); - - if (obr) - re->tothalo += obr->tothalo; - - BLI_rng_free(rng); -} - - -/* ------------------------------------------------------------------------- */ /* tool functions/defines for ad hoc simplification and possible future * cleanup */ /* ------------------------------------------------------------------------- */ -#define UVTOINDEX(u,v) (startvlak + (u) * sizev + (v)) +#define UVTOINDEX(u, v) (startvlak + (u) * sizev + (v)) /* * * NOTE THAT U/V COORDINATES ARE SOMETIMES SWAPPED !! @@ -860,28 +665,13 @@ static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[4][4], int /* Orco hash and Materials */ /* ------------------------------------------------------------------------- */ -static float *get_object_orco(Render *re, Object *ob) +static float *get_object_orco(Render *re, void *ob) { - float *orco; - - if (!re->orco_hash) - re->orco_hash = BLI_ghash_ptr_new("get_object_orco gh"); - - orco = BLI_ghash_lookup(re->orco_hash, ob); - - if (!orco) { - if (ELEM(ob->type, OB_CURVE, OB_FONT)) { - orco = BKE_curve_make_orco(re->scene, ob, NULL); - } - else if (ob->type==OB_SURF) { - orco = BKE_curve_surf_make_orco(ob); - } - - if (orco) - BLI_ghash_insert(re->orco_hash, ob, orco); + if (!re->orco_hash) { + return NULL; } - return orco; + return BLI_ghash_lookup(re->orco_hash, ob); } static void set_object_orco(Render *re, void *ob, float *orco) @@ -1676,8 +1466,11 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if (path_nbr) { if (!ELEM(ma->material_type, MA_TYPE_HALO, MA_TYPE_WIRE)) { - sd.orco = MEM_mallocN(3*sizeof(float)*(totpart+totchild), "particle orcos"); - set_object_orco(re, psys, sd.orco); + sd.orco = get_object_orco(re, psys); + if (!sd.orco) { + sd.orco = MEM_mallocN(3*sizeof(float)*(totpart+totchild), "particle orcos"); + set_object_orco(re, psys, sd.orco); + } } } @@ -1848,9 +1641,11 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if (strandbuf) { int orignum = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, cpa->num) : cpa->num; - if (orignum > sbound - strandbuf->bound) { - sbound= strandbuf->bound + orignum; - sbound->start= sbound->end= obr->totstrand; + if ((orignum > sbound - strandbuf->bound) && + (orignum < strandbuf->totbound)) + { + sbound = &strandbuf->bound[orignum]; + sbound->start = sbound->end = obr->totstrand; } } } @@ -2829,9 +2624,12 @@ static void init_render_surf(Render *re, ObjectRen *obr, int timeoffset) if (dm) { if (need_orco) { - orco= BKE_displist_make_orco(re->scene, ob, dm, 1, 1); - if (orco) { - set_object_orco(re, ob, orco); + orco = get_object_orco(re, ob); + if (!orco) { + orco= BKE_displist_make_orco(re->scene, ob, dm, 1, 1); + if (orco) { + set_object_orco(re, ob, orco); + } } } @@ -2840,7 +2638,11 @@ static void init_render_surf(Render *re, ObjectRen *obr, int timeoffset) } else { if (need_orco) { - orco= get_object_orco(re, ob); + orco = get_object_orco(re, ob); + if (!orco) { + orco = BKE_curve_surf_make_orco(ob); + set_object_orco(re, ob, orco); + } } /* walk along displaylist and create rendervertices/-faces */ @@ -2900,9 +2702,12 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) if (dm) { if (need_orco) { - orco= BKE_displist_make_orco(re->scene, ob, dm, 1, 1); - if (orco) { - set_object_orco(re, ob, orco); + orco = get_object_orco(re, ob); + if (!orco) { + orco = BKE_displist_make_orco(re->scene, ob, dm, 1, 1); + if (orco) { + set_object_orco(re, ob, orco); + } } } @@ -2912,6 +2717,10 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) else { if (need_orco) { orco = get_object_orco(re, ob); + if (!orco) { + orco = BKE_curve_make_orco(re->scene, ob, NULL); + set_object_orco(re, ob, orco); + } } while (dl) { @@ -3401,10 +3210,13 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) if (dm==NULL) return; /* in case duplicated object fails? */ if (mask & CD_MASK_ORCO) { - orco= dm->getVertDataArray(dm, CD_ORCO); - if (orco) { - orco= MEM_dupallocN(orco); - set_object_orco(re, ob, orco); + orco = get_object_orco(re, ob); + if (!orco) { + orco= dm->getVertDataArray(dm, CD_ORCO); + if (orco) { + orco= MEM_dupallocN(orco); + set_object_orco(re, ob, orco); + } } } @@ -5361,15 +5173,7 @@ void RE_Database_Preprocess(Render *re) if (!re->test_break(re->tbh)) { int tothalo; - /* don't sort stars */ tothalo= re->tothalo; - if (!re->test_break(re->tbh)) { - if (re->wrld.mode & WO_STARS) { - re->i.infostr = IFACE_("Creating Starfield"); - re->stats_draw(re->sdh, &re->i); - RE_make_stars(re, NULL, NULL, NULL, NULL); - } - } sort_halos(re, tothalo); init_camera_inside_volumes(re); diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 6cac2fa3fa6..28932d0e93b 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -555,7 +555,7 @@ void RE_parts_init(Render *re, int do_crop) /* this is render info for caller, is not reset when parts are freed! */ re->i.totpart = 0; re->i.curpart = 0; - re->i.partsdone = FALSE; + re->i.partsdone = 0; /* just for readable code.. */ xminb = re->disprect.xmin; @@ -608,7 +608,7 @@ void RE_parts_init(Render *re, int do_crop) RenderPart *pa = MEM_callocN(sizeof(RenderPart), "new part"); /* Non-box filters need 2 pixels extra to work */ - if (do_crop && (re->r.filtertype || (re->r.mode & R_EDGE))) { + if (do_crop && re->r.filtertype) { pa->crop = 2; disprect.xmin -= pa->crop; disprect.ymin -= pa->crop; diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c index 3259608c18f..3ae075b4936 100644 --- a/source/blender/render/intern/source/multires_bake.c +++ b/source/blender/render/intern/source/multires_bake.c @@ -95,6 +95,7 @@ typedef struct { char *texels; const MResolvePixelData *data; MFlushPixel flush_pixel; + short *do_update; } MBakeRast; typedef struct { @@ -162,7 +163,8 @@ static void multiresbake_get_normal(const MResolvePixelData *data, float norm[], } } -static void init_bake_rast(MBakeRast *bake_rast, const ImBuf *ibuf, const MResolvePixelData *data, MFlushPixel flush_pixel) +static void init_bake_rast(MBakeRast *bake_rast, const ImBuf *ibuf, const MResolvePixelData *data, + MFlushPixel flush_pixel, short *do_update) { BakeImBufuserData *userdata = (BakeImBufuserData *) ibuf->userdata; @@ -173,6 +175,7 @@ static void init_bake_rast(MBakeRast *bake_rast, const ImBuf *ibuf, const MResol bake_rast->h = ibuf->y; bake_rast->data = data; bake_rast->flush_pixel = flush_pixel; + bake_rast->do_update = do_update; } static void flush_pixel(const MResolvePixelData *data, const int x, const int y) @@ -240,6 +243,9 @@ static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int if ((bake_rast->texels[y * w + x]) == 0) { bake_rast->texels[y * w + x] = FILTER_MASK_USED; flush_pixel(bake_rast->data, x, y); + if (bake_rast->do_update) { + *bake_rast->do_update = true; + } } } } @@ -529,7 +535,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, int require_ta handle->height_min = FLT_MAX; handle->height_max = -FLT_MAX; - init_bake_rast(&handle->bake_rast, ibuf, &handle->data, flush_pixel); + init_bake_rast(&handle->bake_rast, ibuf, &handle->data, flush_pixel, bkr->do_update); if (tot_thread > 1) BLI_insert_thread(&threads, handle); diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index fa05f8dd18d..d11f4615698 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1600,6 +1600,7 @@ static void tag_scenes_for_render(Render *re) /* check for render-layers nodes using other scenes, we tag them LIB_DOIT */ for (node = re->scene->nodetree->nodes.first; node; node = node->next) { + node->flag &= ~NODE_TEST; if (node->type == CMP_NODE_R_LAYERS) { if (node->id) { if (!MAIN_VERSION_ATLEAST(re->main, 265, 5)) { @@ -1617,8 +1618,12 @@ static void tag_scenes_for_render(Render *re) } } - if (node->id != (ID *)re->scene) - node->id->flag |= LIB_DOIT; + if (node->id != (ID *)re->scene) { + if ((node->id->flag & LIB_DOIT) == 0) { + node->flag |= NODE_TEST; + node->id->flag |= LIB_DOIT; + } + } } } } @@ -1640,12 +1645,12 @@ static void ntree_render_scenes(Render *re) for (node = re->scene->nodetree->nodes.first; node; node = node->next) { if (node->type == CMP_NODE_R_LAYERS) { if (node->id && node->id != (ID *)re->scene) { - if (node->id->flag & LIB_DOIT) { + if (node->flag & NODE_TEST) { Scene *scene = (Scene *)node->id; render_scene(re, scene, cfra); restore_scene = (scene != re->scene); - node->id->flag &= ~LIB_DOIT; + node->flag &= ~NODE_TEST; nodeUpdate(re->scene->nodetree, node); } @@ -1679,7 +1684,7 @@ static void add_freestyle(Render *re, int render) * real bmain uses. This is needed because freestyle's * bmain could be used to tag scenes for update, which * implies call of ED_render_scene_update in some cases - * and that function requires proper windoew manager + * and that function requires proper window manager * to present (sergey) */ re->freestyle_bmain.wm = re->main->wm; @@ -2288,13 +2293,6 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *r BKE_report(reports, RPT_ERROR, "Cannot save render buffers, check the temp default path"); return 0; } - - /* no fullsample and edge */ - if ((scemode & R_FULL_SAMPLE) && (scene->r.mode & R_EDGE)) { - BKE_report(reports, RPT_ERROR, "Full sample does not support edge enhance"); - return 0; - } - } if (scemode & R_DOCOMP) { diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c index 43e052a6efc..feaf68a8c4a 100644 --- a/source/blender/render/intern/source/pixelshading.c +++ b/source/blender/render/intern/source/pixelshading.c @@ -289,7 +289,6 @@ int shadeHaloFloat(HaloRen *har, float col[4], int zz, if (R.wrld.mode & WO_MIST) { if (har->type & HA_ONLYSKY) { - /* stars but no mist */ alpha= har->alfa; } else { diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index 37587d89ce0..487de42515d 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -1124,7 +1124,13 @@ ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd) */ if (ibuf->rect) { if (BKE_imtype_valid_depths(rd->im_format.imtype) & (R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16 | R_IMF_CHAN_DEPTH_24 | R_IMF_CHAN_DEPTH_32)) { - IMB_float_from_rect(ibuf); + if (rd->im_format.depth == R_IMF_CHAN_DEPTH_8) { + /* Higher depth bits are supported but not needed for current file output. */ + ibuf->rect_float = NULL; + } + else { + IMB_float_from_rect(ibuf); + } } else { /* ensure no float buffer remained from previous frame */ diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 49052150fe3..049d7e5a732 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -1724,7 +1724,7 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, const float bf = -0.04f*Tnor*mtex->norfac; int rgbnor; /* disable internal bump eval */ - float* nvec = texres->nor; + float *nvec = texres->nor; texres->nor = NULL; /* du & dv estimates, constant value defaults */ du = dv = 0.01f; @@ -3558,12 +3558,15 @@ Material *RE_init_sample_material(Material *orig_mat, Scene *scene) /* strip material copy from unsupported flags */ for (tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) { - if (mat->septex & (1<<tex_nr)) continue; if (mat->mtex[tex_nr]) { MTex *mtex = mat->mtex[tex_nr]; - if (!mtex->tex) continue; + /* just in case make all non-used mtexes empty*/ + Tex *cur_tex = mtex->tex; + mtex->tex = NULL; + + if (mat->septex & (1<<tex_nr) || !cur_tex) continue; /* only keep compatible texflags */ mtex->texflag = mtex->texflag & (MTEX_RGBTOINT | MTEX_STENCIL | MTEX_NEGATIVE | MTEX_ALPHAMIX); @@ -3598,7 +3601,7 @@ Material *RE_init_sample_material(Material *orig_mat, Scene *scene) } /* copy texture */ - tex= mtex->tex = localize_texture(mtex->tex); + tex= mtex->tex = localize_texture(cur_tex); /* update texture anims */ BKE_animsys_evaluate_animdata(scene, &tex->id, tex->adt, BKE_scene_frame_get(scene), ADT_RECALC_ANIM); @@ -3646,7 +3649,8 @@ void RE_free_sample_material(Material *mat) } } - BKE_material_free(mat); + /* don't update user counts as we are freeing a duplicate */ + BKE_material_free_ex(mat, false); MEM_freeN(mat); } diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 89d8345a0d7..8791af55792 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -967,25 +967,6 @@ static void addps(ListBase *lb, intptr_t *rd, int obi, int facenr, int z, int ma ps->shadfac= 0; } -static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect) -{ - float addcol[4]; - int pix; - - if (arect==NULL) - return; - - for (pix= pa->rectx*pa->recty; pix>0; pix--, arect++, rectf+=4) { - if (*arect != 0.0f) { - addcol[0]= *arect * R.r.edgeR; - addcol[1]= *arect * R.r.edgeG; - addcol[2]= *arect * R.r.edgeB; - addcol[3]= *arect; - addAlphaOverFloat(rectf, addcol); - } - } -} - /* clamp alpha and RGB to 0..1 and 0..inf, can go outside due to filter */ static void clamp_alpha_rgb_range(RenderPart *pa, RenderLayer *rl) { @@ -1010,67 +991,6 @@ static void clamp_alpha_rgb_range(RenderPart *pa, RenderLayer *rl) } } -/* adds only alpha values */ -static void edge_enhance_tile(RenderPart *pa, float *rectf, int *rectz) -{ - /* use zbuffer to define edges, add it to the image */ - int y, x, col, *rz, *rz1, *rz2, *rz3; - int zval1, zval2, zval3; - float *rf; - - /* shift values in zbuffer 4 to the right (anti overflows), for filter we need multiplying with 12 max */ - rz= rectz; - if (rz==NULL) return; - - for (y=0; y<pa->recty; y++) - for (x=0; x<pa->rectx; x++, rz++) (*rz)>>= 4; - - rz1= rectz; - rz2= rz1+pa->rectx; - rz3= rz2+pa->rectx; - - rf= rectf+pa->rectx+1; - - for (y=0; y<pa->recty-2; y++) { - for (x=0; x<pa->rectx-2; x++, rz1++, rz2++, rz3++, rf++) { - - /* prevent overflow with sky z values */ - zval1= rz1[0] + 2*rz1[1] + rz1[2]; - zval2= 2*rz2[0] + 2*rz2[2]; - zval3= rz3[0] + 2*rz3[1] + rz3[2]; - - col= ( 4*rz2[1] - (zval1 + zval2 + zval3)/3 ); - if (col<0) col= -col; - - col >>= 5; - if (col > (1<<16)) col= (1<<16); - else col= (R.r.edgeint*col)>>8; - - if (col>0) { - float fcol; - - if (col>255) fcol= 1.0f; - else fcol= (float)col/255.0f; - - if (R.osa) - *rf+= fcol/(float)R.osa; - else - *rf= fcol; - } - } - rz1+= 2; - rz2+= 2; - rz3+= 2; - rf+= 2; - } - - /* shift back zbuf values, we might need it still */ - rz= rectz; - for (y=0; y<pa->recty; y++) - for (x=0; x<pa->rectx; x++, rz++) (*rz)<<= 4; - -} - static void reset_sky_speed(RenderPart *pa, RenderLayer *rl) { /* for all pixels with max speed, set to zero */ @@ -1149,7 +1069,6 @@ static void addAlphaOverFloatMask(float *dest, float *source, unsigned short dma typedef struct ZbufSolidData { RenderLayer *rl; ListBase *psmlist; - float *edgerect; } ZbufSolidData; static void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data) @@ -1171,10 +1090,6 @@ static void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *da } } } - - if (sdata->rl->layflag & SCE_LAY_EDGE) - if (R.r.mode & R_EDGE) - edge_enhance_tile(pa, sdata->edgerect, zspan->rectz); } /* main call for shading Delta Accum, for OSA */ @@ -1184,7 +1099,6 @@ void zbufshadeDA_tile(RenderPart *pa) RenderResult *rr= pa->result; RenderLayer *rl; ListBase psmlist= {NULL, NULL}; - float *edgerect= NULL; /* allocate the necessary buffers */ /* zbuffer inits these rects */ @@ -1195,21 +1109,16 @@ void zbufshadeDA_tile(RenderPart *pa) if ((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK)) pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask"); - /* initialize pixelstructs and edge buffer */ + /* initialize pixelstructs */ addpsmain(&psmlist); pa->rectdaps= MEM_callocN(sizeof(intptr_t)*pa->rectx*pa->recty+4, "zbufDArectd"); - if (rl->layflag & SCE_LAY_EDGE) - if (R.r.mode & R_EDGE) - edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge"); - /* always fill visibility */ for (pa->sample=0; pa->sample<R.osa; pa->sample+=4) { ZbufSolidData sdata; sdata.rl= rl; sdata.psmlist= &psmlist; - sdata.edgerect= edgerect; zbuffer_solid(pa, rl, make_pixelstructs, &sdata); if (R.test_break(R.tbh)) break; } @@ -1276,18 +1185,12 @@ void zbufshadeDA_tile(RenderPart *pa) } /* sun/sky */ - if (rl->layflag & SCE_LAY_SKY) + if (rl->layflag & SCE_LAY_SKY) { atm_tile(pa, rl); - - /* sky before edge */ - if (rl->layflag & SCE_LAY_SKY) sky_tile(pa, rl); + } - /* extra layers */ - if (rl->layflag & SCE_LAY_EDGE) - if (R.r.mode & R_EDGE) - edge_enhance_add(pa, rl->rectf, edgerect); - + /* extra layers */ if (rl->passflag & SCE_PASS_VECTOR) reset_sky_speed(pa, rl); @@ -1297,9 +1200,6 @@ void zbufshadeDA_tile(RenderPart *pa) /* free stuff within loop! */ MEM_freeN(pa->rectdaps); pa->rectdaps= NULL; freeps(&psmlist); - - if (edgerect) MEM_freeN(edgerect); - edgerect= NULL; if (pa->rectmask) { MEM_freeN(pa->rectmask); @@ -1328,7 +1228,6 @@ void zbufshade_tile(RenderPart *pa) RenderResult *rr= pa->result; RenderLayer *rl; PixStr ps; - float *edgerect= NULL; /* fake pixel struct, to comply to osa render */ ps.next= NULL; @@ -1350,14 +1249,6 @@ void zbufshade_tile(RenderPart *pa) if (!R.test_break(R.tbh)) { /* NOTE: this if () is not consistent */ - /* edges only for solid part, ztransp doesn't support it yet anti-aliased */ - if (rl->layflag & SCE_LAY_EDGE) { - if (R.r.mode & R_EDGE) { - edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge"); - edge_enhance_tile(pa, edgerect, pa->rectz); - } - } - /* initialize scanline updates for main thread */ rr->renrect.ymin = 0; rr->renlay= rl; @@ -1438,24 +1329,13 @@ void zbufshade_tile(RenderPart *pa) } /* sun/sky */ - if (rl->layflag & SCE_LAY_SKY) + if (rl->layflag & SCE_LAY_SKY) { atm_tile(pa, rl); - - /* sky before edge */ - if (rl->layflag & SCE_LAY_SKY) sky_tile(pa, rl); - - if (!R.test_break(R.tbh)) { - if (rl->layflag & SCE_LAY_EDGE) - if (R.r.mode & R_EDGE) - edge_enhance_add(pa, rl->rectf, edgerect); } if (rl->passflag & SCE_PASS_VECTOR) reset_sky_speed(pa, rl); - - if (edgerect) MEM_freeN(edgerect); - edgerect= NULL; if (pa->rectmask) { MEM_freeN(pa->rectmask); diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 114961394c4..dbc9c47446f 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -1789,18 +1789,20 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) } /* AO pass */ - if (R.wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) { - if (((passflag & SCE_PASS_COMBINED) && (shi->combinedflag & (SCE_PASS_AO|SCE_PASS_ENVIRONMENT|SCE_PASS_INDIRECT))) || - (passflag & (SCE_PASS_AO|SCE_PASS_ENVIRONMENT|SCE_PASS_INDIRECT))) - { - if (R.r.mode & R_SHADOW) { - /* AO was calculated for scanline already */ - if (shi->depth || shi->volume_depth) - ambient_occlusion(shi); - copy_v3_v3(shr->ao, shi->ao); - copy_v3_v3(shr->env, shi->env); /* XXX multiply */ - copy_v3_v3(shr->indirect, shi->indirect); /* XXX multiply */ - } + if (((passflag & SCE_PASS_COMBINED) && (shi->combinedflag & (SCE_PASS_AO|SCE_PASS_ENVIRONMENT|SCE_PASS_INDIRECT))) || + (passflag & (SCE_PASS_AO|SCE_PASS_ENVIRONMENT|SCE_PASS_INDIRECT))) { + if ((R.wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) && (R.r.mode & R_SHADOW)) { + /* AO was calculated for scanline already */ + if (shi->depth || shi->volume_depth) + ambient_occlusion(shi); + copy_v3_v3(shr->ao, shi->ao); + copy_v3_v3(shr->env, shi->env); /* XXX multiply */ + copy_v3_v3(shr->indirect, shi->indirect); /* XXX multiply */ + } + else { + shr->ao[0]= shr->ao[1]= shr->ao[2]= 1.0f; + zero_v3(shr->env); + zero_v3(shr->indirect); } } diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c index 732892ed357..3ec487f63dc 100644 --- a/source/blender/render/intern/source/sss.c +++ b/source/blender/render/intern/source/sss.c @@ -878,7 +878,7 @@ static void sss_create_tree_mat(Render *re, Material *mat) re->r.mode &= ~R_OSA; re->sss_points= &points; re->sss_mat= mat; - re->i.partsdone = FALSE; + re->i.partsdone = 0; if (!(re->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))) re->result= NULL; diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c index 6912f998e7a..e5e3aff573d 100644 --- a/source/blender/render/intern/source/volume_precache.c +++ b/source/blender/render/intern/source/volume_precache.c @@ -495,7 +495,7 @@ typedef struct VolPrecacheState { int totparts; } VolPrecacheState; -static void vol_precache_part(TaskPool *pool, void *taskdata, int threadid) +static void vol_precache_part(TaskPool *pool, void *taskdata, int UNUSED(threadid)) { VolPrecacheState *state = (VolPrecacheState *)BLI_task_pool_userdata(pool); VolPrecachePart *pa = (VolPrecachePart *)taskdata; @@ -513,7 +513,7 @@ static void vol_precache_part(TaskPool *pool, void *taskdata, int threadid) if (re->test_break && re->test_break(re->tbh)) return; - printf("thread id %d\n", threadid); + //printf("thread id %d\n", threadid); res[0]= pa->res[0]; res[1]= pa->res[1]; diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt index b9a5b5ffaae..5f993297840 100644 --- a/source/blender/windowmanager/CMakeLists.txt +++ b/source/blender/windowmanager/CMakeLists.txt @@ -124,14 +124,6 @@ if(WITH_GAMEENGINE) add_definitions(-DWITH_GAMEENGINE) endif() -if(APPLE) - if(NOT WITH_COCOA) - list(APPEND SRC - intern/wm_apple.c - ) - endif() -endif() - if(WITH_BUILDINFO) add_definitions(-DWITH_BUILDINFO) endif() diff --git a/source/blender/windowmanager/SConscript b/source/blender/windowmanager/SConscript index 0a2f48f0488..00d363e1539 100644 --- a/source/blender/windowmanager/SConscript +++ b/source/blender/windowmanager/SConscript @@ -66,9 +66,6 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', ' incs += ' ' + env['BF_PTHREADS_INC'] incs += ' ../../intern/utfconv' -if env['OURPLATFORM'] != 'darwin' or env['WITH_GHOST_COCOA']: - sources.remove('intern' + os.sep + 'wm_apple.c') - if env['BF_BUILDINFO']: defs.append('WITH_BUILDINFO') diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index c338d49fe17..1f38368399a 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -272,7 +272,9 @@ bool WM_operator_last_properties_store(struct wmOperator *op); /* operator as a python command (resultuing string must be freed) */ -char *WM_operator_pystring(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *opptr, int all_args); +char *WM_operator_pystring_ex(struct bContext *C, struct wmOperator *op, const bool all_args, + struct wmOperatorType *ot, struct PointerRNA *opptr); +char *WM_operator_pystring(struct bContext *C, struct wmOperator *op, const bool all_args); char *WM_prop_pystring_assign(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int index); void WM_operator_bl_idname(char *to, const char *from); void WM_operator_py_idname(char *to, const char *from); @@ -294,20 +296,20 @@ void WM_menutype_free(void); /* default operator callbacks for border/circle/lasso */ int WM_border_select_invoke (struct bContext *C, struct wmOperator *op, const struct wmEvent *event); int WM_border_select_modal (struct bContext *C, struct wmOperator *op, const struct wmEvent *event); -int WM_border_select_cancel(struct bContext *C, struct wmOperator *op); +void WM_border_select_cancel(struct bContext *C, struct wmOperator *op); int WM_gesture_circle_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event); int WM_gesture_circle_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event); -int WM_gesture_circle_cancel(struct bContext *C, struct wmOperator *op); +void WM_gesture_circle_cancel(struct bContext *C, struct wmOperator *op); int WM_gesture_lines_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event); int WM_gesture_lines_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event); -int WM_gesture_lines_cancel(struct bContext *C, struct wmOperator *op); +void WM_gesture_lines_cancel(struct bContext *C, struct wmOperator *op); int WM_gesture_lasso_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event); int WM_gesture_lasso_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event); -int WM_gesture_lasso_cancel(struct bContext *C, struct wmOperator *op); +void WM_gesture_lasso_cancel(struct bContext *C, struct wmOperator *op); const int (*WM_gesture_lasso_path_to_array(struct bContext *C, struct wmOperator *op, int *mcords_tot))[2]; int WM_gesture_straightline_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event); int WM_gesture_straightline_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event); -int WM_gesture_straightline_cancel(struct bContext *C, struct wmOperator *op); +void WM_gesture_straightline_cancel(struct bContext *C, struct wmOperator *op); /* Gesture manager API */ struct wmGesture *WM_gesture_new(struct bContext *C, const struct wmEvent *event, int type); @@ -378,6 +380,7 @@ int WM_jobs_test(struct wmWindowManager *wm, void *owner, int job_type); float WM_jobs_progress(struct wmWindowManager *wm, void *owner); char *WM_jobs_name(struct wmWindowManager *wm, void *owner); void *WM_jobs_customdata(struct wmWindowManager *wm, void *owner); +void *WM_jobs_customdata_from_type(struct wmWindowManager *wm, int job_type); int WM_jobs_is_running(struct wmJob *); void *WM_jobs_customdata_get(struct wmJob *); diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h index eab27286709..ce6481c8929 100644 --- a/source/blender/windowmanager/WM_keymap.h +++ b/source/blender/windowmanager/WM_keymap.h @@ -91,6 +91,7 @@ void WM_modalkeymap_assign(struct wmKeyMap *km, const char *opname); void WM_keymap_restore_to_default(struct wmKeyMap *keymap, struct bContext *C); void WM_keymap_properties_reset(struct wmKeyMapItem *kmi, struct IDProperty *properties); void WM_keymap_restore_item_to_default(struct bContext *C, struct wmKeyMap *keymap, struct wmKeyMapItem *kmi); +int WM_keymap_map_type_get(struct wmKeyMapItem *kmi); /* Key Event */ diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index ac9af832671..dabb90b2ba0 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -311,7 +311,6 @@ typedef struct wmNotifier { /* NC_WORLD World */ #define ND_WORLD_DRAW (45<<16) -#define ND_WORLD_STARS (46<<16) /* NC_TEXT Text */ #define ND_CURSOR (50<<16) @@ -535,7 +534,7 @@ typedef struct wmOperatorType { * canceled due to some external reason, cancel is called * - see defines below for return values */ int (*invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT; - int (*cancel)(struct bContext *, struct wmOperator *); + void (*cancel)(struct bContext *, struct wmOperator *); int (*modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT; /* verify if the operator can be executed in the current context, note diff --git a/source/blender/windowmanager/intern/wm_apple.c b/source/blender/windowmanager/intern/wm_apple.c deleted file mode 100644 index 842fc353699..00000000000 --- a/source/blender/windowmanager/intern/wm_apple.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * ***** 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) 2007 Blender Foundation. - * All rights reserved. - * - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/windowmanager/intern/wm_apple.c - * \ingroup wm - */ - -/* note, this file builds on apple-carbon only! */ - -#include "BKE_context.h" -#include "BKE_global.h" -#include "WM_api.h" - -#include <OpenGL/OpenGL.h> -#define __CARBONSOUND__ -/* XXX BIG WARNING: carbon.h can not be included in blender code, it conflicts with struct ID */ -#define ID ID_ -#include <Carbon/Carbon.h> - -/* To avoid killing small end comps, we want to allow - * blender to start maximized if all the followings are true : - * - Renderer is OpenGL capable - * - Hardware acceleration - * - VRAM > 16 Mo - * - * We will bail out if VRAM is less than 8Mo - */ - -/* bad global, used in wm_window.c to open windows */ -int macPrefState = 0; - -static int checkAppleVideoCard(void) -{ - CGLRendererInfoObj rend; - long theErr; - unsigned long display_mask; - long nrend; - int j; - long value; - long maxvram = 0; /* we get always more than 1 renderer, check one, at least, has 8 Mo */ - - display_mask = CGDisplayIDToOpenGLDisplayMask(CGMainDisplayID() ); - - theErr = CGLQueryRendererInfo(display_mask, &rend, &nrend); - if (theErr == 0) { - theErr = CGLDescribeRenderer(rend, 0, kCGLRPRendererCount, &nrend); - if (theErr == 0) { - for (j = 0; j < nrend; j++) { - theErr = CGLDescribeRenderer(rend, j, kCGLRPVideoMemory, &value); - if (value > maxvram) - maxvram = value; - if ((theErr == 0) && (value >= 20000000)) { - theErr = CGLDescribeRenderer(rend, j, kCGLRPAccelerated, &value); - if ((theErr == 0) && (value != 0)) { - theErr = CGLDescribeRenderer(rend, j, kCGLRPCompliant, &value); - if ((theErr == 0) && (value != 0)) { - /*fprintf(stderr, "make it big\n");*/ - CGLDestroyRendererInfo(rend); - macPrefState = 8; - return 1; - } - } - } - } - } - } - if (maxvram < 7500000) { /* put a standard alert and quit*/ - SInt16 junkHit; - char inError[] = "* Not enough VRAM "; - char inText[] = "* blender needs at least 8Mb "; - inError[0] = 16; - inText[0] = 28; - - fprintf(stderr, " vram is %li . not enough, aborting\n", maxvram); - StandardAlert(kAlertStopAlert, (ConstStr255Param) & inError, (ConstStr255Param) & inText, NULL, &junkHit); - abort(); - } - CGLDestroyRendererInfo(rend); - return 0; -} - -static void getMacAvailableBounds(short *top, short *left, short *bottom, short *right) -{ - Rect outAvailableRect; - - GetAvailableWindowPositioningBounds(GetMainDevice(), &outAvailableRect); - - *top = outAvailableRect.top; - *left = outAvailableRect.left; - *bottom = outAvailableRect.bottom; - *right = outAvailableRect.right; -} - - -void wm_set_apple_prefsize(int scr_x, int scr_y) -{ - - /* first let us check if we are hardware accelerated and with VRAM > 16 Mo */ - - if (checkAppleVideoCard()) { - short top, left, bottom, right; - - getMacAvailableBounds(&top, &left, &bottom, &right); - WM_init_state_size_set(left + 10, scr_y - bottom + 10, right - left - 20, bottom - 64); - G.windowstate = 0; - - } - else { - - /* 40 + 684 + (headers) 22 + 22 = 768, the powerbook screen height */ - WM_init_state_size_set(120, 40, 850, 684); - G.windowstate = 0; - } -} diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 825c1ca9252..d60901f1325 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -491,7 +491,7 @@ int WM_operator_poll_context(bContext *C, wmOperatorType *ot, short context) static void wm_operator_print(bContext *C, wmOperator *op) { /* context is needed for enum function */ - char *buf = WM_operator_pystring(C, op->type, op->ptr, false); + char *buf = WM_operator_pystring(C, op, false); printf("%s\n", buf); MEM_freeN(buf); } @@ -626,7 +626,7 @@ static void wm_operator_reports(bContext *C, wmOperator *op, int retval, int cal if (op->type->flag & OPTYPE_REGISTER) { if (G.background == 0) { /* ends up printing these in the terminal, gets annoying */ /* Report the python string representation of the operator */ - char *buf = WM_operator_pystring(C, op->type, op->ptr, false); + char *buf = WM_operator_pystring(C, op, false); BKE_report(CTX_wm_reports(C), RPT_OPERATOR, buf); MEM_freeN(buf); } @@ -660,7 +660,7 @@ static void wm_operator_finished(bContext *C, wmOperator *op, int repeat) if (repeat == 0) { if (G.debug & G_DEBUG_WM) { - char *buf = WM_operator_pystring(C, op->type, op->ptr, false); + char *buf = WM_operator_pystring(C, op, false); BKE_report(CTX_wm_reports(C), RPT_OPERATOR, buf); MEM_freeN(buf); } diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index 05ee23e2361..4d4d46d063a 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -293,13 +293,15 @@ static void draw_filled_lasso(wmWindow *win, wmGesture *gt) } -static void wm_gesture_draw_lasso(wmWindow *win, wmGesture *gt) +static void wm_gesture_draw_lasso(wmWindow *win, wmGesture *gt, bool filled) { short *lasso = (short *)gt->customdata; int i; - draw_filled_lasso(win, gt); - + if (filled) { + draw_filled_lasso(win, gt); + } + glEnable(GL_LINE_STIPPLE); glColor3ub(96, 96, 96); glLineStipple(1, 0xAAAA); @@ -365,9 +367,9 @@ void wm_gesture_draw(wmWindow *win) wm_gesture_draw_cross(win, gt); } else if (gt->type == WM_GESTURE_LINES) - wm_gesture_draw_lasso(win, gt); + wm_gesture_draw_lasso(win, gt, false); else if (gt->type == WM_GESTURE_LASSO) - wm_gesture_draw_lasso(win, gt); + wm_gesture_draw_lasso(win, gt, true); else if (gt->type == WM_GESTURE_STRAIGHTLINE) wm_gesture_draw_line(gt); } diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index c9c3d2df788..b3856a2aa9c 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -166,22 +166,27 @@ static void wm_job_main_thread_yield(wmJob *wm_job, bool ending) } /* finds: - * if type, compare for it, otherwise any matching job + * if type or owner, compare for it, otherwise any matching job */ static wmJob *wm_job_find(wmWindowManager *wm, void *owner, const int job_type) { wmJob *wm_job; - for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) - if (wm_job->owner == owner) { - - if (job_type) { - if ( wm_job->job_type == job_type) - return wm_job; - } - else + if (owner && job_type) { + for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) + if (wm_job->owner == owner && wm_job->job_type == job_type) return wm_job; - } + } + else if (owner) { + for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) + if (wm_job->owner == owner) + return wm_job; + } + else if (job_type) { + for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) + if (wm_job->job_type == job_type) + return wm_job; + } return NULL; } @@ -263,7 +268,16 @@ void *WM_jobs_customdata(wmWindowManager *wm, void *owner) return WM_jobs_customdata_get(wm_job); return NULL; +} +void *WM_jobs_customdata_from_type(wmWindowManager *wm, int job_type) +{ + wmJob *wm_job = wm_job_find(wm, NULL, job_type); + + if (wm_job) + return WM_jobs_customdata_get(wm_job); + + return NULL; } int WM_jobs_is_running(wmJob *wm_job) @@ -509,9 +523,9 @@ void WM_jobs_kill(wmWindowManager *wm, void *owner, void (*startjob)(void *, sho wm_job = wm->jobs.first; while (wm_job) { if (wm_job->owner == owner || wm_job->startjob == startjob) { - wmJob *bill = wm_job; + wmJob *wm_job_kill = wm_job; wm_job = wm_job->next; - wm_jobs_kill_job(wm, bill); + wm_jobs_kill_job(wm, wm_job_kill); } else { wm_job = wm_job->next; diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index f6ba3a29344..8e202eb93f0 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -139,6 +139,30 @@ void WM_keymap_properties_reset(wmKeyMapItem *kmi, struct IDProperty *properties wm_keymap_item_properties_set(kmi); } +int WM_keymap_map_type_get(wmKeyMapItem *kmi) +{ + if (ISTIMER(kmi->type)) { + return KMI_TYPE_TIMER; + } + if (ISKEYBOARD(kmi->type)) { + return KMI_TYPE_KEYBOARD; + } + if (ISTWEAK(kmi->type)) { + return KMI_TYPE_TWEAK; + } + if (ISMOUSE(kmi->type)) { + return KMI_TYPE_MOUSE; + } + if (ISNDOF(kmi->type)) { + return KMI_TYPE_NDOF; + } + if (kmi->type == KM_TEXTINPUT) { + return KMI_TYPE_TEXTINPUT; + } + return KMI_TYPE_KEYBOARD; +} + + /**************************** Keymap Diff Item ********************************* * Item in a diff keymap, used for saving diff of keymaps in user preferences */ @@ -686,11 +710,13 @@ wmKeyMap *WM_modalkeymap_add(wmKeyConfig *keyconf, const char *idname, EnumPrope if (!items) { /* init modal items from default config */ wmWindowManager *wm = G.main->wm.first; - wmKeyMap *defaultkm = WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, 0, 0); + if (wm->defaultconf) { + wmKeyMap *defaultkm = WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, 0, 0); - if (defaultkm) { - km->modal_items = defaultkm->modal_items; - km->poll = defaultkm->poll; + if (defaultkm) { + km->modal_items = defaultkm->modal_items; + km->poll = defaultkm->poll; + } } } @@ -779,6 +805,10 @@ static void wm_user_modal_keymap_set_items(wmWindowManager *wm, wmKeyMap *km) int propvalue; if (km && (km->flag & KEYMAP_MODAL) && !km->modal_items) { + if (wm->defaultconf == NULL) { + return; + } + defaultkm = WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, 0, 0); if (!defaultkm) @@ -1091,7 +1121,7 @@ static wmKeyMap *wm_keymap_preset(wmWindowManager *wm, wmKeyMap *km) wmKeyMap *keymap; keymap = WM_keymap_list_find(&keyconf->keymaps, km->idname, km->spaceid, km->regionid); - if (!keymap) + if (!keymap && wm->defaultconf) keymap = WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, km->spaceid, km->regionid); return keymap; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 6091ec4a371..50575095825 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -341,14 +341,14 @@ static int wm_macro_modal(bContext *C, wmOperator *op, const wmEvent *event) return wm_macro_end(op, retval); } -static int wm_macro_cancel(bContext *C, wmOperator *op) +static void wm_macro_cancel(bContext *C, wmOperator *op) { /* call cancel on the current modal operator, if any */ if (op->opm && op->opm->type->cancel) { op->opm->type->cancel(C, op->opm); } - return wm_macro_end(op, OPERATOR_CANCELLED); + wm_macro_end(op, OPERATOR_CANCELLED); } /* Names have to be static for now */ @@ -521,13 +521,14 @@ void WM_operator_bl_idname(char *to, const char *from) to[0] = 0; } -/* print a string representation of the operator, with the args that it runs - * so python can run it again, +/* Print a string representation of the operator, with the args that it runs so python can run it again. * - * When calling from an existing wmOperator do. - * WM_operator_pystring(op->type, op->ptr); + * When calling from an existing wmOperator, better to use simple version: + * WM_operator_pystring(C, op); + * + * Note: both op and opptr may be NULL (op is only used for macro operators). */ -char *WM_operator_pystring(bContext *C, wmOperatorType *ot, PointerRNA *opptr, int all_args) +char *WM_operator_pystring_ex(bContext *C, wmOperator *op, const bool all_args, wmOperatorType *ot, PointerRNA *opptr) { char idname_py[OP_MAX_TYPENAME]; @@ -539,24 +540,53 @@ char *WM_operator_pystring(bContext *C, wmOperatorType *ot, PointerRNA *opptr, i /* arbitrary, but can get huge string with stroke painting otherwise */ int max_prop_length = 10; - /* only to get the orginal props for comparisons */ - PointerRNA opptr_default; + WM_operator_py_idname(idname_py, ot->idname); + BLI_dynstr_appendf(dynstr, "bpy.ops.%s(", idname_py); + + if (op && op->macro.first) { + /* Special handling for macros, else we only get default values in this case... */ + wmOperator *opm; + bool first_op = true; + for (opm = op->macro.first; opm; opm = opm->next) { + PointerRNA *opmptr = opm->ptr; + PointerRNA opmptr_default; + if (opmptr == NULL) { + WM_operator_properties_create_ptr(&opmptr_default, opm->type); + opmptr = &opmptr_default; + } - if (opptr == NULL) { - WM_operator_properties_create_ptr(&opptr_default, ot); - opptr = &opptr_default; + cstring_args = RNA_pointer_as_string_id(C, opmptr); + if (first_op) { + BLI_dynstr_appendf(dynstr, "%s=%s", opm->type->idname, cstring_args); + first_op = false; + } + else { + BLI_dynstr_appendf(dynstr, ", %s=%s", opm->type->idname, cstring_args); + } + MEM_freeN(cstring_args); + + if (opmptr == &opmptr_default) { + WM_operator_properties_free(&opmptr_default); + } + } } + else { + /* only to get the orginal props for comparisons */ + PointerRNA opptr_default; - WM_operator_py_idname(idname_py, ot->idname); - BLI_dynstr_appendf(dynstr, "bpy.ops.%s(", idname_py); + if (opptr == NULL) { + WM_operator_properties_create_ptr(&opptr_default, ot); + opptr = &opptr_default; + } - cstring_args = RNA_pointer_as_string_keywords(C, opptr, false, - all_args, max_prop_length); - BLI_dynstr_append(dynstr, cstring_args); - MEM_freeN(cstring_args); + cstring_args = RNA_pointer_as_string_keywords(C, opptr, false, all_args, max_prop_length); + BLI_dynstr_append(dynstr, cstring_args); + MEM_freeN(cstring_args); - if (opptr == &opptr_default) - WM_operator_properties_free(&opptr_default); + if (opptr == &opptr_default) { + WM_operator_properties_free(&opptr_default); + } + } BLI_dynstr_append(dynstr, ")"); @@ -565,6 +595,11 @@ char *WM_operator_pystring(bContext *C, wmOperatorType *ot, PointerRNA *opptr, i return cstring; } +char *WM_operator_pystring(bContext *C, wmOperator *op, const bool all_args) +{ + return WM_operator_pystring_ex(C, op, all_args, op->type, op->ptr); +} + /* return NULL if no match is found */ #if 0 static char *wm_prop_pystring_from_context(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index) @@ -1396,12 +1431,19 @@ static uiBlock *wm_operator_ui_create(bContext *C, ARegion *ar, void *userData) return block; } -static void wm_operator_ui_popup_cancel(struct bContext *UNUSED(C), void *userData) +static void wm_operator_ui_popup_cancel(struct bContext *C, void *userData) { wmOpPopUp *data = userData; - if (data->free_op && data->op) { - wmOperator *op = data->op; - WM_operator_free(op); + wmOperator *op = data->op; + + if (op) { + if (op->type->cancel) { + op->type->cancel(C, op); + } + + if (data->free_op) { + WM_operator_free(op); + } } MEM_freeN(data); @@ -1634,18 +1676,20 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar #ifdef WITH_BUILDINFO - int ver_width, rev_width; - char version_buf[128]; - char revision_buf[128]; - extern char build_rev[]; - - BLI_snprintf(version_buf, sizeof(version_buf), - "%d.%02d.%d", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION); - BLI_snprintf(revision_buf, sizeof(revision_buf), "r%s", build_rev); + int label_delta = 0; + int hash_width, date_width; + char date_buf[128] = "\0"; + char hash_buf[128] = "\0"; + extern unsigned long build_commit_timestamp; + extern char build_hash[], build_commit_date[], build_commit_time[], build_branch[]; + + /* Builds made from tag only shows tag sha */ + BLI_snprintf(hash_buf, sizeof(hash_buf), "Hash: %s", build_hash); + BLI_snprintf(date_buf, sizeof(date_buf), "Date: %s %s", build_commit_date, build_commit_time); BLF_size(style->widgetlabel.uifont_id, style->widgetlabel.points, U.pixelsize * U.dpi); - ver_width = (int)BLF_width(style->widgetlabel.uifont_id, version_buf) + 0.5f * U.widget_unit; - rev_width = (int)BLF_width(style->widgetlabel.uifont_id, revision_buf) + 0.5f * U.widget_unit; + hash_width = (int)BLF_width(style->widgetlabel.uifont_id, hash_buf) + 0.5f * U.widget_unit; + date_width = (int)BLF_width(style->widgetlabel.uifont_id, date_buf) + 0.5f * U.widget_unit; #endif /* WITH_BUILDINFO */ block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS); @@ -1660,9 +1704,20 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar uiButSetFunc(but, wm_block_splash_close, block, NULL); uiBlockSetFunc(block, wm_block_splash_refreshmenu, block, NULL); -#ifdef WITH_BUILDINFO - uiDefBut(block, LABEL, 0, version_buf, U.pixelsize * 494 - ver_width, U.pixelsize * 258, ver_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); - uiDefBut(block, LABEL, 0, revision_buf, U.pixelsize * 494 - rev_width, U.pixelsize * 246, rev_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); +#ifdef WITH_BUILDINFO + if (build_commit_timestamp != 0) { + uiDefBut(block, LABEL, 0, date_buf, U.pixelsize * 494 - date_width, U.pixelsize * 270, date_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); + label_delta = 12; + } + uiDefBut(block, LABEL, 0, hash_buf, U.pixelsize * 494 - hash_width, U.pixelsize * (270 - label_delta), hash_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); + + if (!STREQ(build_branch, "master")) { + char branch_buf[128] = "\0"; + int branch_width; + BLI_snprintf(branch_buf, sizeof(branch_buf), "Branch: %s", build_branch); + branch_width = (int)BLF_width(style->widgetlabel.uifont_id, branch_buf) + 0.5f * U.widget_unit; + uiDefBut(block, LABEL, 0, branch_buf, U.pixelsize * 494 - branch_width, U.pixelsize * (258 - label_delta), branch_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); + } #endif /* WITH_BUILDINFO */ layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, U.pixelsize * 480, U.pixelsize * 110, style); @@ -1686,11 +1741,11 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar col = uiLayoutColumn(split, FALSE); uiItemL(col, IFACE_("Links"), ICON_NONE); uiItemStringO(col, IFACE_("Donations"), ICON_URL, "WM_OT_url_open", "url", - "http://www.blender.org/blenderorg/blender-foundation/donation-payment"); + "http://www.blender.org/foundation/donation-payment/"); uiItemStringO(col, IFACE_("Credits"), ICON_URL, "WM_OT_url_open", "url", - "http://www.blender.org/development/credits"); + "http://www.blender.org/about/credits/"); uiItemStringO(col, IFACE_("Release Log"), ICON_URL, "WM_OT_url_open", "url", - "http://www.blender.org/development/release-logs/blender-269"); + "http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.70"); uiItemStringO(col, IFACE_("Manual"), ICON_URL, "WM_OT_url_open", "url", "http://wiki.blender.org/index.php/Doc:2.6/Manual"); uiItemStringO(col, IFACE_("Blender Website"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org"); @@ -1745,7 +1800,7 @@ static void WM_OT_splash(wmOperatorType *ot) { ot->name = "Splash Screen"; ot->idname = "WM_OT_splash"; - ot->description = "Opens a blocking popup region with release info"; + ot->description = "Opens the splash screen with release info"; ot->invoke = wm_splash_invoke; ot->poll = WM_operator_winactive; @@ -2844,11 +2899,9 @@ int WM_border_select_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -int WM_border_select_cancel(bContext *C, wmOperator *op) +void WM_border_select_cancel(bContext *C, wmOperator *op) { wm_gesture_end(C, op); - - return OPERATOR_CANCELLED; } /* **************** circle gesture *************** */ @@ -2961,11 +3014,9 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -int WM_gesture_circle_cancel(bContext *C, wmOperator *op) +void WM_gesture_circle_cancel(bContext *C, wmOperator *op) { wm_gesture_end(C, op); - - return OPERATOR_CANCELLED; } #if 0 @@ -3188,18 +3239,14 @@ int WM_gesture_lines_modal(bContext *C, wmOperator *op, const wmEvent *event) return WM_gesture_lasso_modal(C, op, event); } -int WM_gesture_lasso_cancel(bContext *C, wmOperator *op) +void WM_gesture_lasso_cancel(bContext *C, wmOperator *op) { wm_gesture_end(C, op); - - return OPERATOR_CANCELLED; } -int WM_gesture_lines_cancel(bContext *C, wmOperator *op) +void WM_gesture_lines_cancel(bContext *C, wmOperator *op) { wm_gesture_end(C, op); - - return OPERATOR_CANCELLED; } /** @@ -3365,11 +3412,9 @@ int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *ev return OPERATOR_RUNNING_MODAL; } -int WM_gesture_straightline_cancel(bContext *C, wmOperator *op) +void WM_gesture_straightline_cancel(bContext *C, wmOperator *op) { wm_gesture_end(C, op); - - return OPERATOR_CANCELLED; } #if 0 @@ -3803,7 +3848,7 @@ static void radial_control_set_value(RadialControl *rc, float val) } } -static int radial_control_cancel(bContext *C, wmOperator *op) +static void radial_control_cancel(bContext *C, wmOperator *op) { RadialControl *rc = op->customdata; wmWindowManager *wm = CTX_wm_manager(C); @@ -3821,8 +3866,6 @@ static int radial_control_cancel(bContext *C, wmOperator *op) glDeleteTextures(1, &rc->gltex); MEM_freeN(rc); - - return OPERATOR_CANCELLED; } static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *event) @@ -4255,6 +4298,7 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "UV_OT_circle_select"); WM_modalkeymap_assign(keymap, "CLIP_OT_select_circle"); WM_modalkeymap_assign(keymap, "MASK_OT_select_circle"); + WM_modalkeymap_assign(keymap, "NODE_OT_select_circle"); } diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 9e89c17e024..5f344340643 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -133,10 +133,6 @@ static void wm_window_check_position(rcti *rect) wm_get_screensize(&width, &height); -#if defined(__APPLE__) && !defined(GHOST_COCOA) - height -= 70; -#endif - if (rect->xmin < 0) { rect->xmax -= rect->xmin; rect->xmin = 0; @@ -338,12 +334,6 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win) * in case of OS application terminate request (e.g. OS Shortcut Alt+F4, Cmd+Q, (...), or session end) */ GHOST_SetWindowModifiedState(win->ghostwin, (GHOST_TUns8) !wm->file_saved); -#if defined(__APPLE__) && !defined(GHOST_COCOA) - if (wm->file_saved) - GHOST_SetWindowState(win->ghostwin, GHOST_kWindowStateUnModified); - else - GHOST_SetWindowState(win->ghostwin, GHOST_kWindowStateModified); -#endif } } @@ -428,20 +418,12 @@ void wm_window_add_ghostwindows(wmWindowManager *wm) if (wm_init_state.size_x == 0) { wm_get_screensize(&wm_init_state.size_x, &wm_init_state.size_y); -#if defined(__APPLE__) && !defined(GHOST_COCOA) - /* Cocoa provides functions to get correct max window size */ - { - extern void wm_set_apple_prefsize(int, int); /* wm_apple.c */ - - wm_set_apple_prefsize(wm_init_state.size_x, wm_init_state.size_y); - } -#else - /* note!, this isnt quite correct, active screen maybe offset 1000s if PX, - * we'd need a wm_get_screensize like function that gives offset, - * in practice the window manager will likely move to the correct monitor */ - wm_init_state.start_x = 0; - wm_init_state.start_y = 0; -#endif + /* note!, this isnt quite correct, active screen maybe offset 1000s if PX, + * we'd need a wm_get_screensize like function that gives offset, + * in practice the window manager will likely move to the correct monitor */ + wm_init_state.start_x = 0; + wm_init_state.start_y = 0; + #if !defined(__APPLE__) && !defined(WIN32) /* X11 */ /* X11, start maximized but use default sane size */ |