diff options
author | Daniel Genrich <daniel.genrich@gmx.net> | 2012-08-06 13:59:24 +0400 |
---|---|---|
committer | Daniel Genrich <daniel.genrich@gmx.net> | 2012-08-06 13:59:24 +0400 |
commit | b8905ba0a6731d2aba6f3487be58b338f35df5f7 (patch) | |
tree | e3dc4fc0ac799aec6d7f28dcfb16d87c53ec5506 /source | |
parent | 79f638791d5a0ab6c07cd21c82decdc24329d825 (diff) | |
parent | 3b743582ec282cfffc84c5e235f58fe2745327c9 (diff) |
Merge from trunk r49109-r49601
Diffstat (limited to 'source')
414 files changed, 10488 insertions, 7282 deletions
diff --git a/source/blender/avi/intern/avi.c b/source/blender/avi/intern/avi.c index cceba82aca7..9d4704cf0f2 100644 --- a/source/blender/avi/intern/avi.c +++ b/source/blender/avi/intern/avi.c @@ -857,9 +857,9 @@ AviError AVI_open_compress(char *name, AviMovie *movie, int streams, ...) #if 0 if (movie->streams[i].format == AVI_FORMAT_MJPEG) { AviMJPEGUnknown *tmp; - - tmp = (AviMJPEGUnknown *) ((char*) movie->streams[i].sf +sizeof(AviBitmapInfoHeader)); - + + tmp = (AviMJPEGUnknown *)((char *) movie->streams[i].sf + sizeof(AviBitmapInfoHeader)); + tmp->a = 44; tmp->b = 24; tmp->c = 0; @@ -965,11 +965,15 @@ AviError AVI_write_frame(AviMovie *movie, int frame_num, ...) /* Allocate the new memory for the index entry */ if (frame_num + 1 > movie->index_entries) { - temp = (AviIndexEntry *) MEM_mallocN((frame_num + 1) * - (movie->header->Streams + 1) * sizeof(AviIndexEntry), "newidxentry"); + const size_t entry_size = (movie->header->Streams + 1) * sizeof(AviIndexEntry); + if (movie->entries != NULL) { - memcpy(temp, movie->entries, movie->index_entries * (movie->header->Streams + 1) * sizeof(AviIndexEntry)); - MEM_freeN(movie->entries); + temp = (AviIndexEntry *)MEM_reallocN(movie->entries, (frame_num + 1) * entry_size); + /* clear new bytes */ + memset(&temp[movie->index_entries + 1], 0, (frame_num - movie->index_entries) * entry_size); + } + else { + temp = (AviIndexEntry *) MEM_callocN((frame_num + 1) * entry_size, "newidxentry"); } movie->entries = temp; diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c index 9e8884ad94d..b37180d499c 100644 --- a/source/blender/blenfont/intern/blf_lang.c +++ b/source/blender/blenfont/intern/blf_lang.c @@ -82,7 +82,7 @@ static const char *locales[] = { "spanish", "es", "catalan", "ca_AD", "czech", "cs_CZ", - "ptb", "pt", + "portuguese", "pt", #if defined(_WIN32) && !defined(FREE_WINDOWS) "Chinese (Simplified)_China.1252", "zh_CN", "Chinese (Traditional)_China.1252", "zh_TW", diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 48c7103d8fd..dec4d3cb8cb 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,9 +42,11 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 263 -#define BLENDER_SUBVERSION 14 +#define BLENDER_SUBVERSION 17 -#define BLENDER_MINVERSION 250 +/* 262 was the last editmesh release but its has compatibility code for bmesh data, + * so set the minversion to 2.61 */ +#define BLENDER_MINVERSION 261 #define BLENDER_MINSUBVERSION 0 /* used by packaging tools */ diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h index eeebcdafe48..d7882d8e7ec 100644 --- a/source/blender/blenkernel/BKE_cdderivedmesh.h +++ b/source/blender/blenkernel/BKE_cdderivedmesh.h @@ -61,12 +61,14 @@ DerivedMesh *CDDM_from_BMEditMesh(struct BMEditMesh *em, struct Mesh *me, int us /* merge verts */ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap); +DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, struct Object *ob); + /* creates a CDDerivedMesh from the given curve object */ struct DerivedMesh *CDDM_from_curve(struct Object *ob); /* creates a CDDerivedMesh from the given curve object and specified dispbase */ /* useful for OrcoDM creation for curves with constructive modifiers */ -DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispbase); +DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispbase, int **orco_index_ptr); /* Copies the given DerivedMesh with verts, faces & edges stored as * custom element data. diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index bcda970e60c..facbcb23dd6 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -181,7 +181,7 @@ typedef enum { //////////////////////////////////////////////// // needed for implicit.c -int cloth_bvh_objcollision (struct Object *ob, struct ClothModifierData * clmd, float step, float dt ); +int cloth_bvh_objcollision (struct Object *ob, struct ClothModifierData *clmd, float step, float dt ); //////////////////////////////////////////////// diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 3dc68edf12b..8d486218d21 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -310,7 +310,7 @@ int CustomData_layertype_is_singleton(int type); /* make sure the name of layer at index is unique */ void CustomData_set_layer_unique_name(struct CustomData *data, int index); -void CustomData_validate_layer_name(const struct CustomData *data, int type, char *name, char *outname); +void CustomData_validate_layer_name(const struct CustomData *data, int type, const char *name, char *outname); /* for file reading compatibility, returns false if the layer was freed, * only after this test passes, layer->data should be assigned */ diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h index 6636a70e94d..938a13483d5 100644 --- a/source/blender/blenkernel/BKE_font.h +++ b/source/blender/blenkernel/BKE_font.h @@ -46,7 +46,7 @@ struct TmpFont; struct CharInfo; struct Main; -struct chartrans { +struct CharTrans { float xof, yof; float rot; short linenr, charnr; @@ -71,15 +71,19 @@ typedef struct EditFont { } EditFont; +int BKE_vfont_is_builtin(struct VFont *vfont); void BKE_vfont_builtin_register(void *mem, int size); +void BKE_vfont_free_data(struct VFont *vfont); void BKE_vfont_free(struct VFont *sc); void BKE_vfont_free_global_ttf(void); struct VFont *BKE_vfont_builtin_get(void); struct VFont *BKE_vfont_load(struct Main *bmain, const char *name); -struct TmpFont *BKE_vfont_find_tmpfont(struct VFont *vfont); -struct chartrans *BKE_vfont_to_curve(struct Main *bmain, struct Scene *scene, struct Object *ob, int mode); +struct TmpFont *BKE_vfont_tmpfont_find(struct VFont *vfont); +void BKE_vfont_tmpfont_remove(struct VFont *vfont); + +struct CharTrans *BKE_vfont_to_curve(struct Main *bmain, struct Scene *scene, struct Object *ob, int mode); int BKE_vfont_select_get(struct Object *ob, int *start, int *end); diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 9a4f30c853f..a1a306c1b2c 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -64,19 +64,19 @@ void BKE_mask_layer_copy_list(struct ListBase *masklayers_new, struct ListBase * /* splines */ struct MaskSpline *BKE_mask_spline_add(struct MaskLayer *masklay); -int BKE_mask_spline_resolution(struct MaskSpline *spline, int width, int height); -int BKE_mask_spline_feather_resolution(struct MaskSpline *spline, int width, int height); +unsigned int BKE_mask_spline_resolution(struct MaskSpline *spline, int width, int height); +unsigned int BKE_mask_spline_feather_resolution(struct MaskSpline *spline, int width, int height); -int BKE_mask_spline_differentiate_calc_total(const struct MaskSpline *spline, const int resol); +int BKE_mask_spline_differentiate_calc_total(const struct MaskSpline *spline, const unsigned int resol); float (*BKE_mask_spline_differentiate(struct MaskSpline *spline, int *tot_diff_point))[2]; float (*BKE_mask_spline_feather_differentiated_points(struct MaskSpline *spline, int *tot_feather_point))[2]; float (*BKE_mask_spline_differentiate_with_resolution_ex(struct MaskSpline *spline, int *tot_diff_point, - const int resol))[2]; + const unsigned int resol))[2]; float (*BKE_mask_spline_differentiate_with_resolution(struct MaskSpline *spline, int width, int height, int *tot_diff_point))[2]; float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(struct MaskSpline *spline, int *tot_feather_point, - const int resol, const int do_collapse))[2]; + const unsigned int resol, const int do_collapse))[2]; float (*BKE_mask_spline_feather_differentiated_points_with_resolution(struct MaskSpline *spline, int width, int height, int *tot_feather_point))[2]; float (*BKE_mask_spline_feather_points(struct MaskSpline *spline, int *tot_feather_point))[2]; @@ -98,16 +98,18 @@ void BKE_mask_point_handle(struct MaskSplinePoint *point, float handle[2]); void BKE_mask_point_set_handle(struct MaskSplinePoint *point, float loc[2], int keep_direction, float orig_handle[2], float orig_vec[3][3]); -float *BKE_mask_point_segment_diff(struct MaskSpline *spline, struct MaskSplinePoint *point, int *tot_diff_point); +float *BKE_mask_point_segment_diff(struct MaskSpline *spline, struct MaskSplinePoint *point, + unsigned int *tot_diff_point); float *BKE_mask_point_segment_feather_diff(struct MaskSpline *spline, struct MaskSplinePoint *point, - int *tot_feather_point); + unsigned int *tot_feather_point); float *BKE_mask_point_segment_diff_with_resolution(struct MaskSpline *spline, struct MaskSplinePoint *point, - int width, int height, int *tot_diff_point); + int width, int height, + unsigned int *tot_diff_point); float *BKE_mask_point_segment_feather_diff_with_resolution(struct MaskSpline *spline, struct MaskSplinePoint *point, int width, int height, - int *tot_feather_point); + unsigned int *tot_feather_point); void BKE_mask_point_segment_co(struct MaskSpline *spline, struct MaskSplinePoint *point, float u, float co[2]); void BKE_mask_point_normal(struct MaskSpline *spline, struct MaskSplinePoint *point, @@ -122,12 +124,16 @@ void BKE_mask_point_select_set_handle(struct MaskSplinePoint *point, const short /* general */ struct Mask *BKE_mask_new(const char *name); +struct Mask *BKE_mask_copy_nolib(struct Mask *mask); +struct Mask *BKE_mask_copy(struct Mask *mask); void BKE_mask_free(struct Mask *mask); void BKE_mask_unlink(struct Main *bmain, struct Mask *mask); void BKE_mask_coord_from_movieclip(struct MovieClip *clip, struct MovieClipUser *user, float r_co[2], const float co[2]); +void BKE_mask_coord_from_frame(float r_co[2], const float co[2], const float frame_size[2]); void BKE_mask_coord_to_movieclip(struct MovieClip *clip, struct MovieClipUser *user, float r_co[2], const float co[2]); +void BKE_mask_coord_to_frame(float r_co[2], const float co[2], const float frame_size[2]); /* parenting */ @@ -181,23 +187,8 @@ void BKE_mask_layer_shape_changed_add(struct MaskLayer *masklay, int index, void BKE_mask_layer_shape_changed_remove(struct MaskLayer *masklay, int index, int count); -/* rasterization */ int BKE_mask_get_duration(struct Mask *mask); -void BKE_mask_rasterize_layers(struct ListBase *masklayers, int width, int height, float *buffer, - const short do_aspect_correct, const short do_mask_aa, - const short do_feather); - -void BKE_mask_rasterize(struct Mask *mask, int width, int height, float *buffer, - const short do_aspect_correct, const short do_mask_aa, - const short do_feather); - -/* initialization for tiling */ -#ifdef __PLX_RASKTER_MT__ -void BKE_mask_init_layers(Mask *mask, struct layer_init_data *mlayer_data, int width, int height, - const short do_aspect_correct); -#endif - #define MASKPOINT_ISSEL_ANY(p) ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT) #define MASKPOINT_ISSEL_KNOT(p) ( (p)->bezt.f2 & SELECT) #define MASKPOINT_ISSEL_HANDLE_ONLY(p) ( (((p)->bezt.f1 | (p)->bezt.f2) & SELECT) && (((p)->bezt.f2 & SELECT) == 0) ) @@ -210,11 +201,9 @@ void BKE_mask_init_layers(Mask *mask, struct layer_init_data *mlayer_data, int w #define MASKPOINT_SEL_HANDLE(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0 #define MASKPOINT_DESEL_HANDLE(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0 -/* disable to test alternate rasterizer */ -/* #define USE_RASKTER */ +#define MASK_RESOL_MAX 128 /* mask_rasterize.c */ -#ifndef USE_RASKTER struct MaskRasterHandle; typedef struct MaskRasterHandle MaskRasterHandle; @@ -225,6 +214,9 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, str const short do_aspect_correct, const short do_mask_aa, const short do_feather); float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2]); -#endif /* USE_RASKTER */ + +void BKE_maskrasterize_buffer(MaskRasterHandle *mr_handle, + const unsigned int width, const unsigned int height, + float *buffer); #endif /* __BKE_MASK_H__ */ diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 6fac915d520..954fb47806b 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -143,9 +143,13 @@ int BKE_mesh_nurbs_to_mdata(struct Object *ob, struct MVert **allvert, int *tot int *totloop, int *totpoly); int BKE_mesh_nurbs_displist_to_mdata(struct Object *ob, struct ListBase *dispbase, struct MVert **allvert, int *_totvert, struct MEdge **alledge, int *_totedge, struct MLoop **allloop, struct MPoly **allpoly, - int *_totloop, int *_totpoly); + int *_totloop, int *_totpoly, int **orco_index_ptr); +void BKE_mesh_nurbs_to_mdata_orco(struct MPoly *mpoly, int totpoly, + struct MLoop *mloops, struct MLoopUV *mloopuvs, + float (*orco)[3], int (*orco_index)[4]); void BKE_mesh_from_nurbs(struct Object *ob); -void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase); +void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase, + int **orco_index_ptr); void BKE_mesh_from_curve(struct Scene *scene, struct Object *ob); void free_dverts(struct MDeformVert *dvert, int totvert); void copy_dverts(struct MDeformVert *dst, struct MDeformVert *src, int totvert); /* __NLA */ @@ -157,8 +161,8 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(struct ID *id, struct CustomData *fdata, struct CustomData *ldata, struct CustomData *pdata, int totedge_i, int totface_i, int totloop_i, int totpoly_i, struct MEdge *medge, struct MFace *mface, - int *totloop_r, int *totpoly_r, - struct MLoop **mloop_r, struct MPoly **mpoly_r); + int *totloop_r, int *totpoly_r, + struct MLoop **mloop_r, struct MPoly **mpoly_r); void BKE_mesh_calc_normals_tessface(struct MVert *mverts, int numVerts, struct MFace *mfaces, int numFaces, float (*faceNors_r)[3]); diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 7bd9f75b2dd..0d867bbbb51 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -88,8 +88,8 @@ typedef struct bNodeSocketTemplate { } bNodeSocketTemplate; typedef void (*NodeSocketButtonFunction)(const struct bContext *C, struct uiBlock *block, - struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock, - const char *name, int x, int y, int width); + struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock, + const char *name, int x, int y, int width); /** Defines a socket type. * Defines the appearance and behavior of a socket in the UI. @@ -301,36 +301,36 @@ struct bNodeType *ntreeGetNodeType(struct bNodeTree *ntree); struct bNodeSocketType *ntreeGetSocketType(int type); struct bNodeTree *ntreeAddTree(const char *name, int type, int nodetype); -void ntreeInitTypes(struct bNodeTree *ntree); +void ntreeInitTypes(struct bNodeTree *ntree); -void ntreeFreeTree(struct bNodeTree *ntree); +void ntreeFreeTree(struct bNodeTree *ntree); struct bNodeTree *ntreeCopyTree(struct bNodeTree *ntree); -void ntreeSwitchID(struct bNodeTree *ntree, struct ID *sce_from, struct ID *sce_to); -void ntreeMakeLocal(struct bNodeTree *ntree); -int ntreeHasType(struct bNodeTree *ntree, int type); +void ntreeSwitchID(struct bNodeTree *ntree, struct ID *sce_from, struct ID *sce_to); +void ntreeMakeLocal(struct bNodeTree *ntree); +int ntreeHasType(struct bNodeTree *ntree, int type); -void ntreeUpdateTree(struct bNodeTree *ntree); +void ntreeUpdateTree(struct bNodeTree *ntree); /* XXX Currently each tree update call does call to ntreeVerifyNodes too. * Some day this should be replaced by a decent depsgraph automatism! */ -void ntreeVerifyNodes(struct Main *main, struct ID *id); +void ntreeVerifyNodes(struct Main *main, struct ID *id); -void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***deplist, int *totnodes); +void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***deplist, int *totnodes); /* XXX old trees handle output flags automatically based on special output node types and last active selection. * new tree types have a per-output socket flag to indicate the final output to use explicitly. */ -void ntreeSetOutput(struct bNodeTree *ntree); -void ntreeInitPreview(struct bNodeTree *, int xsize, int ysize); -void ntreeClearPreview(struct bNodeTree *ntree); +void ntreeSetOutput(struct bNodeTree *ntree); +void ntreeInitPreview(struct bNodeTree *, int xsize, int ysize); +void ntreeClearPreview(struct bNodeTree *ntree); -void ntreeFreeCache(struct bNodeTree *ntree); +void ntreeFreeCache(struct bNodeTree *ntree); -int ntreeNodeExists(struct bNodeTree *ntree, struct bNode *testnode); -int ntreeOutputExists(struct bNode *node, struct bNodeSocket *testsock); +int ntreeNodeExists(struct bNodeTree *ntree, struct bNode *testnode); +int ntreeOutputExists(struct bNode *node, struct bNodeSocket *testsock); struct bNodeTree *ntreeLocalize(struct bNodeTree *ntree); -void ntreeLocalSync(struct bNodeTree *localtree, struct bNodeTree *ntree); -void ntreeLocalMerge(struct bNodeTree *localtree, struct bNodeTree *ntree); +void ntreeLocalSync(struct bNodeTree *localtree, struct bNodeTree *ntree); +void ntreeLocalMerge(struct bNodeTree *localtree, struct bNodeTree *ntree); /* ************** GENERIC API, NODES *************** */ @@ -339,98 +339,108 @@ struct bNodeSocket *nodeInsertSocket(struct bNodeTree *ntree, struct bNode *node void nodeRemoveSocket(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock); void nodeRemoveAllSockets(struct bNodeTree *ntree, struct bNode *node); -void nodeAddToPreview(struct bNode *node, float col[4], int x, int y, int do_manage); +void nodeAddToPreview(struct bNode *node, float col[4], int x, int y, int do_manage); struct bNode *nodeAddNode(struct bNodeTree *ntree, struct bNodeTemplate *ntemp); -void nodeUnlinkNode(struct bNodeTree *ntree, struct bNode *node); -void nodeUniqueName(struct bNodeTree *ntree, struct bNode *node); +void nodeUnlinkNode(struct bNodeTree *ntree, struct bNode *node); +void nodeUniqueName(struct bNodeTree *ntree, struct bNode *node); -void nodeRegisterType(struct bNodeTreeType *ttype, struct bNodeType *ntype); -void nodeMakeDynamicType(struct bNode *node); -int nodeDynamicUnlinkText(struct ID *txtid); +void nodeRegisterType(struct bNodeTreeType *ttype, struct bNodeType *ntype); +void nodeMakeDynamicType(struct bNode *node); +int nodeDynamicUnlinkText(struct ID *txtid); -void nodeFreeNode(struct bNodeTree *ntree, struct bNode *node); +void nodeFreeNode(struct bNodeTree *ntree, struct bNode *node); struct bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node); struct bNodeLink *nodeAddLink(struct bNodeTree *ntree, struct bNode *fromnode, struct bNodeSocket *fromsock, struct bNode *tonode, struct bNodeSocket *tosock); -void nodeRemLink(struct bNodeTree *ntree, struct bNodeLink *link); -void nodeRemSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock); -void nodeInternalRelink(struct bNodeTree *ntree, struct bNode *node); +void nodeRemLink(struct bNodeTree *ntree, struct bNodeLink *link); +void nodeRemSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock); +void nodeInternalRelink(struct bNodeTree *ntree, struct bNode *node); -void nodeToView(struct bNode *node, float x, float y, float *rx, float *ry); -void nodeFromView(struct bNode *node, float x, float y, float *rx, float *ry); -void nodeAttachNode(struct bNode *node, struct bNode *parent); -void nodeDetachNode(struct bNode *node); +void nodeToView(struct bNode *node, float x, float y, float *rx, float *ry); +void nodeFromView(struct bNode *node, float x, float y, float *rx, float *ry); +int nodeAttachNodeCheck(struct bNode *node, struct bNode *parent); +void nodeAttachNode(struct bNode *node, struct bNode *parent); +void nodeDetachNode(struct bNode *node); -struct bNode *nodeFindNodebyName(struct bNodeTree *ntree, const char *name); -int nodeFindNode(struct bNodeTree *ntree, struct bNodeSocket *sock, struct bNode **nodep, int *sockindex, int *in_out); +struct bNode *nodeFindNodebyName(struct bNodeTree *ntree, const char *name); +int nodeFindNode(struct bNodeTree *ntree, struct bNodeSocket *sock, struct bNode **nodep, int *sockindex, int *in_out); struct bNodeLink *nodeFindLink(struct bNodeTree *ntree, struct bNodeSocket *from, struct bNodeSocket *to); -int nodeCountSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock); +int nodeCountSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock); -void nodeSetActive(struct bNodeTree *ntree, struct bNode *node); -struct bNode *nodeGetActive(struct bNodeTree *ntree); -struct bNode *nodeGetActiveID(struct bNodeTree *ntree, short idtype); -int nodeSetActiveID(struct bNodeTree *ntree, short idtype, struct ID *id); -void nodeClearActive(struct bNodeTree *ntree); -void nodeClearActiveID(struct bNodeTree *ntree, short idtype); -struct bNode *nodeGetActiveTexture(struct bNodeTree *ntree); +void nodeSetActive(struct bNodeTree *ntree, struct bNode *node); +struct bNode *nodeGetActive(struct bNodeTree *ntree); +struct bNode *nodeGetActiveID(struct bNodeTree *ntree, short idtype); +int nodeSetActiveID(struct bNodeTree *ntree, short idtype, struct ID *id); +void nodeClearActive(struct bNodeTree *ntree); +void nodeClearActiveID(struct bNodeTree *ntree, short idtype); +struct bNode *nodeGetActiveTexture(struct bNodeTree *ntree); -void nodeUpdate(struct bNodeTree *ntree, struct bNode *node); -int nodeUpdateID(struct bNodeTree *ntree, struct ID *id); +void nodeUpdate(struct bNodeTree *ntree, struct bNode *node); +int nodeUpdateID(struct bNodeTree *ntree, struct ID *id); -void nodeFreePreview(struct bNode *node); +void nodeFreePreview(struct bNode *node); -int nodeSocketIsHidden(struct bNodeSocket *sock); -void nodeSocketSetType(struct bNodeSocket *sock, int type); +int nodeSocketIsHidden(struct bNodeSocket *sock); +void nodeSocketSetType(struct bNodeSocket *sock, int type); + +/* Node Clipboard */ +void BKE_node_clipboard_init(struct bNodeTree *ntree); +void BKE_node_clipboard_clear(void); +void BKE_node_clipboard_add_node(struct bNode *node); +void BKE_node_clipboard_add_link(struct bNodeLink *link); +const struct ListBase *BKE_node_clipboard_get_nodes(void); +const struct ListBase *BKE_node_clipboard_get_links(void); +int BKE_node_clipboard_get_type(void); /* ************** NODE TYPE ACCESS *************** */ struct bNodeTemplate nodeMakeTemplate(struct bNode *node); -int nodeValid(struct bNodeTree *ntree, struct bNodeTemplate *ntemp); -const char* nodeLabel(struct bNode *node); +int nodeValid(struct bNodeTree *ntree, struct bNodeTemplate *ntemp); +const char *nodeLabel(struct bNode *node); struct bNodeTree *nodeGroupEditGet(struct bNode *node); struct bNodeTree *nodeGroupEditSet(struct bNode *node, int edit); -void nodeGroupEditClear(struct bNode *node); +void nodeGroupEditClear(struct bNode *node); /* Init a new node type struct with default values and callbacks */ -void node_type_base(struct bNodeTreeType *ttype, struct bNodeType *ntype, int type, +void node_type_base(struct bNodeTreeType *ttype, struct bNodeType *ntype, int type, const char *name, short nclass, short flag); -void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs); -void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwidth); -void node_type_init(struct bNodeType *ntype, void (*initfunc)(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp)); -void node_type_valid(struct bNodeType *ntype, int (*validfunc)(struct bNodeTree *ntree, struct bNodeTemplate *ntemp)); -void node_type_storage(struct bNodeType *ntype, - const char *storagename, - void (*freestoragefunc)(struct bNode *), - void (*copystoragefunc)(struct bNode *, struct bNode *)); -void node_type_label(struct bNodeType *ntype, const char *(*labelfunc)(struct bNode *)); -void node_type_template(struct bNodeType *ntype, struct bNodeTemplate (*templatefunc)(struct bNode *)); -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)); -void node_type_tree(struct bNodeType *ntype, - void (*inittreefunc)(struct bNodeTree *), - void (*updatetreefunc)(struct bNodeTree *)); -void node_type_group_edit(struct bNodeType *ntype, - struct bNodeTree *(*group_edit_get)(struct bNode *node), - struct bNodeTree *(*group_edit_set)(struct bNode *node, int edit), - void (*group_edit_clear)(struct bNode *node)); - -void node_type_exec(struct bNodeType *ntype, void (*execfunc)(void *data, struct bNode *, struct bNodeStack **, +void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs); +void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwidth); +void node_type_init(struct bNodeType *ntype, void (*initfunc)(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp)); +void node_type_valid(struct bNodeType *ntype, int (*validfunc)(struct bNodeTree *ntree, struct bNodeTemplate *ntemp)); +void node_type_storage(struct bNodeType *ntype, + const char *storagename, + void (*freestoragefunc)(struct bNode *), + void (*copystoragefunc)(struct bNode *, struct bNode *)); +void node_type_label(struct bNodeType *ntype, const char *(*labelfunc)(struct bNode *)); +void node_type_template(struct bNodeType *ntype, struct bNodeTemplate (*templatefunc)(struct bNode *)); +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)); +void node_type_tree(struct bNodeType *ntype, + void (*inittreefunc)(struct bNodeTree *), + void (*updatetreefunc)(struct bNodeTree *)); +void node_type_group_edit(struct bNodeType *ntype, + struct bNodeTree *(*group_edit_get)(struct bNode *node), + struct bNodeTree *(*group_edit_set)(struct bNode *node, int edit), + void (*group_edit_clear)(struct bNode *node)); + +void node_type_exec(struct bNodeType *ntype, void (*execfunc)(void *data, struct bNode *, struct bNodeStack **, struct bNodeStack **)); -void node_type_exec_new(struct bNodeType *ntype, - void *(*initexecfunc)(struct bNode *node), - void (*freeexecfunc)(struct bNode *node, void *nodedata), - void (*newexecfunc)(void *data, int thread, struct bNode *, void *nodedata, - struct bNodeStack **, struct bNodeStack **)); -void node_type_internal_connect(struct bNodeType *ntype, ListBase (*internal_connect)(struct bNodeTree *, struct bNode *)); -void node_type_gpu(struct bNodeType *ntype, int (*gpufunc)(struct GPUMaterial *mat, struct bNode *node, +void node_type_exec_new(struct bNodeType *ntype, + void *(*initexecfunc)(struct bNode *node), + void (*freeexecfunc)(struct bNode *node, void *nodedata), + void (*newexecfunc)(void *data, int thread, struct bNode *, void *nodedata, + struct bNodeStack **, struct bNodeStack **)); +void node_type_internal_connect(struct bNodeType *ntype, ListBase (*internal_connect)(struct bNodeTree *, struct bNode *)); +void node_type_gpu(struct bNodeType *ntype, int (*gpufunc)(struct GPUMaterial *mat, struct bNode *node, struct GPUNodeStack *in, struct GPUNodeStack *out)); -void node_type_gpu_ext(struct bNodeType *ntype, int (*gpuextfunc)(struct GPUMaterial *mat, struct bNode *node, +void node_type_gpu_ext(struct bNodeType *ntype, int (*gpuextfunc)(struct GPUMaterial *mat, struct bNode *node, void *nodedata, struct GPUNodeStack *in, struct GPUNodeStack *out)); -void node_type_compatibility(struct bNodeType *ntype, short compatibility); +void node_type_compatibility(struct bNodeType *ntype, short compatibility); /* ************** COMMON NODES *************** */ @@ -545,16 +555,16 @@ struct ShadeResult; /* API */ struct bNodeTreeExec *ntreeShaderBeginExecTree(struct bNodeTree *ntree, int use_tree_data); -void ntreeShaderEndExecTree(struct bNodeTreeExec *exec, int use_tree_data); -void ntreeShaderExecTree(struct bNodeTree *ntree, struct ShadeInput *shi, struct ShadeResult *shr); -void ntreeShaderGetTexcoMode(struct bNodeTree *ntree, int osa, short *texco, int *mode); -void nodeShaderSynchronizeID(struct bNode *node, int copyto); +void ntreeShaderEndExecTree(struct bNodeTreeExec *exec, int use_tree_data); +void ntreeShaderExecTree(struct bNodeTree *ntree, struct ShadeInput *shi, struct ShadeResult *shr); +void ntreeShaderGetTexcoMode(struct bNodeTree *ntree, int osa, short *texco, int *mode); +void nodeShaderSynchronizeID(struct bNode *node, int copyto); - /* switch material render loop */ +/* switch material render loop */ extern void (*node_shader_lamp_loop)(struct ShadeInput *, struct ShadeResult *); -void set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, struct ShadeResult *)); +void set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, struct ShadeResult *)); -void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat); +void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat); /* ************** COMPOSITE NODES *************** */ diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 419fb4cedae..a93e542fe15 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -51,10 +51,11 @@ extern const char PAINT_CURSOR_VERTEX_PAINT[3]; extern const char PAINT_CURSOR_WEIGHT_PAINT[3]; extern const char PAINT_CURSOR_TEXTURE_PAINT[3]; -void paint_init(struct Paint *p, const char col[3]); -void free_paint(struct Paint *p); -void copy_paint(struct Paint *src, struct Paint *tar); +void BKE_paint_init(struct Paint *p, const char col[3]); +void BKE_paint_free(struct Paint *p); +void BKE_paint_copy(struct Paint *src, struct Paint *tar); +/* TODO, give these BKE_ prefix too */ struct Paint *paint_get_active(struct Scene *sce); struct Paint *paint_get_active_from_context(const struct bContext *C); struct Brush *paint_brush(struct Paint *paint); diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index d6c1a26fdba..a8890d5a37e 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -182,7 +182,7 @@ struct Sequence *BKE_sequencer_active_get(struct Scene *scene); int BKE_sequencer_active_get_pair(struct Scene *scene, struct Sequence **seq_act, struct Sequence **seq_other); void BKE_sequencer_active_set(struct Scene *scene, struct Sequence *seq); - +struct Mask *BKE_sequencer_mask_get(struct Scene *scene); /* apply functions recursively */ int seqbase_recursive_apply(struct ListBase *seqbase, int (*apply_func)(struct Sequence *seq, void *), void *arg); diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 2b30c845754..c14476a3b59 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -110,6 +110,8 @@ struct MovieTrackingMarker *BKE_tracking_marker_ensure(struct MovieTrackingTrack void BKE_tracking_marker_pattern_minmax(const struct MovieTrackingMarker *marker, float min[2], float max[2]); +void BKE_tracking_marker_get_subframe_position(struct MovieTrackingTrack *track, float framenr, float pos[2]); + /* **** Object **** */ struct MovieTrackingObject *BKE_tracking_object_add(struct MovieTracking *tracking, const char *name); void BKE_tracking_object_delete(struct MovieTracking *tracking, struct MovieTrackingObject *object); @@ -146,8 +148,8 @@ struct ImBuf *BKE_tracking_distortion_exec(struct MovieDistortion *distortion, s struct ImBuf *ibuf, int width, int height, float overscan, int undistort); void BKE_tracking_distortion_free(struct MovieDistortion *distortion); -void BKE_tracking_distort_v2(struct MovieTracking *tracking, float co[2], float nco[2]); -void BKE_tracking_undistort_v2(struct MovieTracking *tracking, float co[2], float nco[2]); +void BKE_tracking_distort_v2(struct MovieTracking *tracking, const float co[2], float r_co[2]); +void BKE_tracking_undistort_v2(struct MovieTracking *tracking, const float co[2], float r_co[2]); struct ImBuf *BKE_tracking_undistort_frame(struct MovieTracking *tracking, struct ImBuf *ibuf, int calibration_width, int calibration_height, float overscan); diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 16ff1646f43..a52e37d5034 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -1458,12 +1458,18 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p /* particle rotation uses x-axis as the aligned axis, so pre-rotate the object accordingly */ if ((part->draw & PART_DRAW_ROTATE_OB) == 0) { - float xvec[3], q[4]; + float xvec[3], q[4], size_mat[4][4], original_size[3]; + + mat4_to_size(original_size, obmat); + size_to_mat4(size_mat, original_size); + xvec[0] = -1.f; xvec[1] = xvec[2] = 0; vec_to_quat(q, xvec, ob->trackflag, ob->upflag); quat_to_mat4(obmat, q); obmat[3][3] = 1.0f; + + mult_m4_m4m4(obmat, obmat, size_mat); } /* Normal particles and cached hair live in global space so we need to @@ -1543,7 +1549,7 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_inde { Object *ob, *obar[256] = {NULL}; Curve *cu; - struct chartrans *ct, *chartransdata; + struct CharTrans *ct, *chartransdata; float vec[3], obmat[4][4], pmat[4][4], fsize, xof, yof; int slen, a; diff --git a/source/blender/blenkernel/intern/bmfont.c b/source/blender/blenkernel/intern/bmfont.c index 722dc1834dd..18161bc6fcb 100644 --- a/source/blender/blenkernel/intern/bmfont.c +++ b/source/blender/blenkernel/intern/bmfont.c @@ -75,7 +75,7 @@ void calcAlpha(ImBuf * ibuf) if (ibuf) { rect = (char *) ibuf->rect; - for (i = ibuf->x * ibuf->y ; i > 0 ; i--) { + for (i = ibuf->x * ibuf->y; i > 0; i--) { rect[3] = MAX3(rect[0], rect[1], rect[2]); rect += 4; } diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index edb3120cf87..e6259cc9faf 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -1168,7 +1168,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) /* constrain direction with maximum angular velocity */ angle = saacos(dot_v3v3(old_dir, wanted_dir)); - angle = MIN2(angle, val.max_ave); + angle = minf(angle, val.max_ave); cross_v3_v3v3(nor, old_dir, wanted_dir); axis_angle_to_quat(q, nor, angle); diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 53a9057116c..468861242d0 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -1052,13 +1052,13 @@ void BKE_brush_painter_break_stroke(BrushPainter *painter) static void brush_pressure_apply(BrushPainter *painter, Brush *brush, float pressure) { if (BKE_brush_use_alpha_pressure(painter->scene, brush)) - brush_alpha_set(painter->scene, brush, MAX2(0.0f, painter->startalpha * pressure)); + brush_alpha_set(painter->scene, brush, maxf(0.0f, painter->startalpha * pressure)); if (BKE_brush_use_size_pressure(painter->scene, brush)) - BKE_brush_size_set(painter->scene, brush, MAX2(1.0f, painter->startsize * pressure)); + BKE_brush_size_set(painter->scene, brush, maxf(1.0f, painter->startsize * pressure)); if (brush->flag & BRUSH_JITTER_PRESSURE) - brush->jitter = MAX2(0.0f, painter->startjitter * pressure); + brush->jitter = maxf(0.0f, painter->startjitter * pressure); if (brush->flag & BRUSH_SPACING_PRESSURE) - brush->spacing = MAX2(1.0f, painter->startspacing * (1.5f - pressure)); + brush->spacing = maxf(1.0f, painter->startspacing * (1.5f - pressure)); } void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2], float jitterpos[2]) @@ -1066,7 +1066,7 @@ void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2], int use_jitter = brush->jitter != 0; /* jitter-ed brush gives weird and unpredictable result for this - * kinds of stroke, so manyally disable jitter usage (sergey) */ + * kinds of stroke, so manually disable jitter usage (sergey) */ use_jitter &= (brush->flag & (BRUSH_RESTORE_MESH | BRUSH_ANCHORED)) == 0; if (use_jitter) { @@ -1158,7 +1158,7 @@ int BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, const float p /* compute brush spacing adapted to brush radius, spacing may depend * on pressure, so update it */ brush_pressure_apply(painter, brush, painter->lastpressure); - spacing = MAX2(1.0f, radius) * brush->spacing * 0.01f; + spacing = maxf(1.0f, radius) * brush->spacing * 0.01f; /* setup starting distance, direction vector and accumulated distance */ startdistance = painter->accumdistance; @@ -1176,7 +1176,7 @@ int BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, const float p t = step / len; press = (1.0f - t) * painter->lastpressure + t * pressure; brush_pressure_apply(painter, brush, press); - spacing = MAX2(1.0f, radius) * brush->spacing * 0.01f; + spacing = maxf(1.0f, radius) * brush->spacing * 0.01f; BKE_brush_jitter_pos(scene, brush, paintpos, finalpos); diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index b19b9db8749..88748d5f0b8 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -52,6 +52,7 @@ #include "BKE_paint.h" #include "BKE_utildefines.h" #include "BKE_tessmesh.h" +#include "BKE_curve.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -1709,10 +1710,49 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob)) DerivedMesh *CDDM_from_curve(Object *ob) { - return CDDM_from_curve_displist(ob, &ob->disp); + return CDDM_from_curve_displist(ob, &ob->disp, NULL); } -DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase) +DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, Object *ob) +{ + int *orco_index_ptr = NULL; + int (*orco_index)[4] = NULL; + float (*orco)[3] = NULL; + DerivedMesh *dm = CDDM_from_curve_displist(ob, &ob->disp, &orco_index_ptr); + + if (orco_index_ptr) { + orco = (float (*)[3])BKE_curve_make_orco(scene, ob); + } + + if (orco && orco_index_ptr) { + const char *uvname = "Orco"; + + int totpoly = dm->getNumPolys(dm); + + MPoly *mpolys = dm->getPolyArray(dm); + MLoop *mloops = dm->getLoopArray(dm); + + MLoopUV *mloopuvs; + + CustomData_add_layer_named(&dm->polyData, CD_MTEXPOLY, CD_DEFAULT, NULL, dm->numPolyData, uvname); + mloopuvs = CustomData_add_layer_named(&dm->loopData, CD_MLOOPUV, CD_DEFAULT, NULL, dm->numLoopData, uvname); + + BKE_mesh_nurbs_to_mdata_orco(mpolys, totpoly, + mloops, mloopuvs, + orco, orco_index); + } + + if (orco_index) { + MEM_freeN(orco_index); + } + if (orco) { + MEM_freeN(orco); + } + + return dm; +} + +DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr) { DerivedMesh *dm; CDDerivedMesh *cddm; @@ -1723,7 +1763,7 @@ DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase) int totvert, totedge, totloop, totpoly; if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge, - &totedge, &allloop, &allpoly, &totloop, &totpoly) != 0) + &totedge, &allloop, &allpoly, &totloop, &totpoly, orco_index_ptr) != 0) { /* Error initializing mdata. This often happens when curve is empty */ return CDDM_new(0, 0, 0, 0, 0); diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 31ad4d0380a..20fae973756 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -66,10 +66,10 @@ CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, floa cumap->flag = CUMA_DO_CLIP; if (tot == 4) cumap->cur = 3; /* rhms, hack for 'col' curve? */ - clipminx = MIN2(minx, maxx); - clipminy = MIN2(miny, maxy); - clipmaxx = MAX2(minx, maxx); - clipmaxy = MAX2(miny, maxy); + clipminx = minf(minx, maxx); + clipminy = minf(miny, maxy); + clipmaxx = maxf(minx, maxx); + clipmaxy = maxf(miny, maxy); BLI_rctf_init(&cumap->curr, clipminx, clipmaxx, clipminy, clipmaxy); cumap->clipr = cumap->curr; @@ -463,8 +463,8 @@ static void curvemap_make_table(CurveMap *cuma, rctf *clipr) bezt = MEM_callocN(cuma->totpoint * sizeof(BezTriple), "beztarr"); for (a = 0; a < cuma->totpoint; a++) { - cuma->mintable = MIN2(cuma->mintable, cmp[a].x); - cuma->maxtable = MAX2(cuma->maxtable, cmp[a].x); + cuma->mintable = minf(cuma->mintable, cmp[a].x); + cuma->maxtable = maxf(cuma->maxtable, cmp[a].x); bezt[a].vec[1][0] = cmp[a].x; bezt[a].vec[1][1] = cmp[a].y; if (cmp[a].flag & CUMA_VECTOR) @@ -655,13 +655,13 @@ void curvemapping_changed(CurveMapping *cumap, int rem_doubles) for (a = 0; a < cuma->totpoint; a++) { if (cmp[a].flag & CUMA_SELECT) { if (cmp[a].x < clipr->xmin) - dx = MIN2(dx, cmp[a].x - clipr->xmin); + dx = minf(dx, cmp[a].x - clipr->xmin); else if (cmp[a].x > clipr->xmax) - dx = MAX2(dx, cmp[a].x - clipr->xmax); + dx = maxf(dx, cmp[a].x - clipr->xmax); if (cmp[a].y < clipr->ymin) - dy = MIN2(dy, cmp[a].y - clipr->ymin); + dy = minf(dy, cmp[a].y - clipr->ymin); else if (cmp[a].y > clipr->ymax) - dy = MAX2(dy, cmp[a].y - clipr->ymax); + dy = maxf(dy, cmp[a].y - clipr->ymax); } } for (a = 0; a < cuma->totpoint; a++) { @@ -961,7 +961,7 @@ void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const short hist->channels = 3; hist->x_resolution = 256; hist->xmax = 1.0f; - hist->ymax = 1.0f; + /* hist->ymax = 1.0f; */ /* now do this on the operator _only_ */ if (ibuf->rect == NULL && ibuf->rect_float == NULL) return; diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index c2b38442a6b..8298023161b 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -3624,7 +3624,7 @@ static void damptrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t cross_v3_v3v3(raxis, obvec, tarvec); rangle = dot_v3v3(obvec, tarvec); - rangle = acos(MAX2(-1.0f, MIN2(1.0f, rangle)) ); + rangle = acos(maxf(-1.0f, minf(1.0f, rangle))); /* construct rotation matrix from the axis-angle rotation found above * - this call takes care to make sure that the axis provided is a unit vector first diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index ff2dd27e0c9..be81c70f261 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -242,6 +242,8 @@ static void *ctx_wm_python_context_get(const bContext *C, const char *member, vo if (result.ptr.data) return result.ptr.data; } +#else + (void)C, (void)member; #endif return fall_through; @@ -370,8 +372,15 @@ PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, Stru { PointerRNA ptr = CTX_data_pointer_get(C, member); - if (ptr.data && RNA_struct_is_a(ptr.type, type)) - return ptr; + if (ptr.data) { + if (RNA_struct_is_a(ptr.type, type)) { + return ptr; + } + else { + printf("%s: warning, member '%s' is '%s', not '%s'\n", + __func__, member, RNA_struct_identifier(ptr.type), RNA_struct_identifier(type)); + } + } return PointerRNA_NULL; } diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 8dd3b3da705..d92c4ca8632 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2793,7 +2793,7 @@ void CustomData_set_layer_unique_name(CustomData *data, int index) BLI_uniquename_cb(customdata_unique_check, &data_arg, typeInfo->defaultname, '.', nlayer->name, sizeof(nlayer->name)); } -void CustomData_validate_layer_name(const CustomData *data, int type, char *name, char *outname) +void CustomData_validate_layer_name(const CustomData *data, int type, const char *name, char *outname) { int index = -1; diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 4026d3f06d3..87ebc597ecd 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -352,10 +352,9 @@ static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Material *ma); /* recursive handling for material nodetree drivers */ -static void dag_add_material_nodetree_driver_relations(DagForest *dag, DagNode *node, bNodeTree *ntree, Material *rootma) +static void dag_add_material_nodetree_driver_relations(DagForest *dag, DagNode *node, bNodeTree *ntree) { bNode *n; - Material *ma; /* nodetree itself */ if (ntree->adt) { @@ -364,14 +363,13 @@ static void dag_add_material_nodetree_driver_relations(DagForest *dag, DagNode * /* nodetree's nodes... */ for (n = ntree->nodes.first; n; n = n->next) { - if (n->id && GS(n->id->name) == ID_MA) { - ma = (Material *)n->id; - if (ma != rootma) { - dag_add_material_driver_relations(dag, node, ma); + if (n->id) { + if (GS(n->id->name) == ID_MA) { + dag_add_material_driver_relations(dag, node, (Material *)n->id); + } + else if (n->type == NODE_GROUP) { + dag_add_material_nodetree_driver_relations(dag, node, (bNodeTree *)n->id); } - } - else if (n->type == NODE_GROUP && n->id) { - dag_add_material_nodetree_driver_relations(dag, node, (bNodeTree *)n->id, rootma); } } } @@ -379,6 +377,15 @@ static void dag_add_material_nodetree_driver_relations(DagForest *dag, DagNode * /* recursive handling for material drivers */ static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Material *ma) { + /* Prevent infinite recursion by checking (and tagging the material) as having been visited + * already (see build_dag()). This assumes ma->id.flag & LIB_DOIT isn't set by anything else + * in the meantime... [#32017] + */ + if (ma->id.flag & LIB_DOIT) + return; + else + ma->id.flag |= LIB_DOIT; + /* material itself */ if (ma->adt) { dag_add_driver_relation(ma->adt, dag, node, 1); @@ -390,7 +397,7 @@ static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Mat /* material's nodetree */ if (ma->nodetree) { - dag_add_material_nodetree_driver_relations(dag, node, ma->nodetree, ma); + dag_add_material_nodetree_driver_relations(dag, node, ma->nodetree); } } @@ -804,6 +811,9 @@ DagForest *build_dag(Main *bmain, Scene *sce, short mask) sce->theDag = dag; } + /* clear "LIB_DOIT" flag from all materials, to prevent infinite recursion problems later [#32017] */ + tag_main_idcode(bmain, ID_MA, FALSE); + /* add base node for scene. scene is always the first node in DAG */ scenenode = dag_add_node(dag, sce); @@ -2836,6 +2846,18 @@ void DAG_id_tag_update(ID *id, short flag) } } } + else if (idtype == ID_VF) { + /* this is weak still, should be done delayed as well */ + for (ob = bmain->object.first; ob; ob = ob->id.next) { + if (ob->type == OB_FONT) { + Curve *cu = ob->data; + + if (ELEM4((struct VFont *)id, cu->vfont, cu->vfontb, cu->vfonti, cu->vfontbi)) { + ob->recalc |= (flag & OB_RECALC_ALL); + } + } + } + } else { /* disable because this is called on various ID types automatically. * where printing warning is not useful. for now just ignore */ diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 8011efebaac..00a76e87d83 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -948,7 +948,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba curve_to_filledpoly(cu, nurb, dispbase); } - dm = CDDM_from_curve_displist(ob, dispbase); + dm = CDDM_from_curve_displist(ob, dispbase, NULL); CDDM_calc_normals_mapping(dm); } @@ -1038,7 +1038,7 @@ static DerivedMesh *create_orco_dm(Scene *scene, Object *ob) /* OrcoDM should be created from underformed disp lists */ BKE_displist_make_curveTypes_forOrco(scene, ob, &disp); - dm = CDDM_from_curve_displist(ob, &disp); + dm = CDDM_from_curve_displist(ob, &disp, NULL); BKE_displist_free(&disp); diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 050f921998d..02e5dc02746 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -63,26 +63,34 @@ static ListBase ttfdata = {NULL, NULL}; /* The vfont code */ -void BKE_vfont_free(struct VFont *vf) + +void BKE_vfont_free_data(struct VFont *vfont) { - if (vf == NULL) return; + if (vfont->data) { + while (vfont->data->characters.first) { + VChar *che = vfont->data->characters.first; - if (vf->data) { - while (vf->data->characters.first) { - VChar *che = vf->data->characters.first; - while (che->nurbsbase.first) { Nurb *nu = che->nurbsbase.first; if (nu->bezt) MEM_freeN(nu->bezt); BLI_freelinkN(&che->nurbsbase, nu); } - - BLI_freelinkN(&vf->data->characters, che); + + BLI_freelinkN(&vfont->data->characters, che); } - MEM_freeN(vf->data); - vf->data = NULL; + MEM_freeN(vfont->data); + vfont->data = NULL; } + + BKE_vfont_tmpfont_remove(vfont); +} + +void BKE_vfont_free(struct VFont *vf) +{ + if (vf == NULL) return; + + BKE_vfont_free_data(vf); if (vf->packedfile) { freePackedFile(vf->packedfile); @@ -93,6 +101,11 @@ void BKE_vfont_free(struct VFont *vf) static void *builtin_font_data = NULL; static int builtin_font_size = 0; +int BKE_vfont_is_builtin(struct VFont *vfont) +{ + return (strcmp(vfont->name, FO_BUILTIN_NAME) == 0); +} + void BKE_vfont_builtin_register(void *mem, int size) { builtin_font_data = mem; @@ -115,34 +128,54 @@ static PackedFile *get_builtin_packedfile(void) } } +static void vfont_tmpfont_free(struct TmpFont *tf) +{ + if (tf->pf) { + freePackedFile(tf->pf); /* NULL when the font file can't be found on disk */ + } + MEM_freeN(tf); +} + void BKE_vfont_free_global_ttf(void) { - struct TmpFont *tf; + struct TmpFont *tf, *tf_next; - for (tf = ttfdata.first; tf; tf = tf->next) { - if (tf->pf) freePackedFile(tf->pf); /* NULL when the font file can't be found on disk */ - tf->pf = NULL; - tf->vfont = NULL; + for (tf = ttfdata.first; tf; tf = tf_next) { + tf_next = tf->next; + vfont_tmpfont_free(tf); } - BLI_freelistN(&ttfdata); + ttfdata.first = ttfdata.last = NULL; } -struct TmpFont *BKE_vfont_find_tmpfont(VFont *vfont) +struct TmpFont *BKE_vfont_tmpfont_find(VFont *vfont) { struct TmpFont *tmpfnt = NULL; if (vfont == NULL) return NULL; /* Try finding the font from font list */ - tmpfnt = ttfdata.first; - while (tmpfnt) { - if (tmpfnt->vfont == vfont) + for (tmpfnt = ttfdata.first; tmpfnt; tmpfnt = tmpfnt->next) { + if (tmpfnt->vfont == vfont) { break; - tmpfnt = tmpfnt->next; + } } + return tmpfnt; } +/* assumes a VFont's tmpfont can't be in the database more then once */ +void BKE_vfont_tmpfont_remove(VFont *vfont) +{ + struct TmpFont *tmpfnt; + + tmpfnt = BKE_vfont_tmpfont_find(vfont); + + if (tmpfnt) { + vfont_tmpfont_free(tmpfnt); + BLI_remlink(&ttfdata, tmpfnt); + } +} + static VFontData *vfont_get_data(Main *bmain, VFont *vfont) { struct TmpFont *tmpfnt = NULL; @@ -151,13 +184,13 @@ static VFontData *vfont_get_data(Main *bmain, VFont *vfont) if (vfont == NULL) return NULL; /* Try finding the font from font list */ - tmpfnt = BKE_vfont_find_tmpfont(vfont); + tmpfnt = BKE_vfont_tmpfont_find(vfont); /* And then set the data */ if (!vfont->data) { PackedFile *pf; - if (strcmp(vfont->name, FO_BUILTIN_NAME) == 0) { + if (BKE_vfont_is_builtin(vfont)) { pf = get_builtin_packedfile(); } else { @@ -194,7 +227,11 @@ static VFontData *vfont_get_data(Main *bmain, VFont *vfont) if (!pf) { printf("Font file doesn't exist: %s\n", vfont->name); + /* DON'T DO THIS + * missing file shouldn't modifty path! - campbell */ +#if 0 strcpy(vfont->name, FO_BUILTIN_NAME); +#endif pf = get_builtin_packedfile(); } } @@ -223,7 +260,7 @@ VFont *BKE_vfont_load(Main *bmain, const char *name) BLI_strncpy(filename, name, sizeof(filename)); pf = get_builtin_packedfile(); - is_builtin = 1; + is_builtin = TRUE; } else { char dir[FILE_MAXDIR]; @@ -234,7 +271,7 @@ VFont *BKE_vfont_load(Main *bmain, const char *name) pf = newPackedFile(NULL, name, bmain->name); tpf = newPackedFile(NULL, name, bmain->name); - is_builtin = 0; + is_builtin = FALSE; } if (pf) { @@ -292,11 +329,13 @@ static VFont *which_vfont(Curve *cu, CharInfo *info) VFont *BKE_vfont_builtin_get(void) { - VFont *vf; + VFont *vfont; - for (vf = G.main->vfont.first; vf; vf = vf->id.next) - if (strcmp(vf->name, FO_BUILTIN_NAME) == 0) - return vf; + for (vfont = G.main->vfont.first; vfont; vfont = vfont->id.next) { + if (BKE_vfont_is_builtin(vfont)) { + return vfont; + } + } return BKE_vfont_load(G.main, FO_BUILTIN_NAME); } @@ -359,7 +398,8 @@ static void build_underline(Curve *cu, float x1, float y1, float x2, float y2, i } -static void buildchar(Main *bmain, Curve *cu, unsigned long character, CharInfo *info, float ofsx, float ofsy, float rot, int charidx) +static void buildchar(Main *bmain, Curve *cu, unsigned long character, CharInfo *info, + float ofsx, float ofsy, float rot, int charidx) { BezTriple *bezt1, *bezt2; Nurb *nu1 = NULL, *nu2 = NULL; @@ -385,8 +425,8 @@ static void buildchar(Main *bmain, Curve *cu, unsigned long character, CharInfo /* make a copy at distance ofsx, ofsy with shear*/ fsize = cu->fsize; shear = cu->shear; - si = (float)sin(rot); - co = (float)cos(rot); + si = sinf(rot); + co = cosf(rot); che = find_vfont_char(vfd, character); @@ -520,7 +560,7 @@ static float char_width(Curve *cu, VChar *che, CharInfo *info) } } -struct chartrans *BKE_vfont_to_curve(Main *bmain, Scene *scene, Object *ob, int mode) +struct CharTrans *BKE_vfont_to_curve(Main *bmain, Scene *scene, Object *ob, int mode) { VFont *vfont, *oldvfont; VFontData *vfd = NULL; @@ -528,7 +568,7 @@ struct chartrans *BKE_vfont_to_curve(Main *bmain, Scene *scene, Object *ob, int CharInfo *info = NULL, *custrinfo; TextBox *tb; VChar *che; - struct chartrans *chartransdata = NULL, *ct; + struct CharTrans *chartransdata = NULL, *ct; float *f, xof, yof, xtrax, linedist, *linedata, *linedata2, *linedata3, *linedata4; float twidth, maxlen = 0; int i, slen, j; @@ -538,7 +578,7 @@ struct chartrans *BKE_vfont_to_curve(Main *bmain, Scene *scene, Object *ob, int short cnr = 0, lnr = 0, wsnr = 0; wchar_t *mem, *tmp, ascii; - /* renark: do calculations including the trailing '\0' of a string + /* remark: do calculations including the trailing '\0' of a string * because the cursor can be at that location */ if (ob->type != OB_FONT) return NULL; @@ -583,7 +623,7 @@ struct chartrans *BKE_vfont_to_curve(Main *bmain, Scene *scene, Object *ob, int /* calc offset and rotation of each char */ ct = chartransdata = - (struct chartrans *)MEM_callocN((slen + 1) * sizeof(struct chartrans), "buildtext"); + (struct CharTrans *)MEM_callocN((slen + 1) * sizeof(struct CharTrans), "buildtext"); /* We assume the worst case: 1 character per line (is freed at end anyway) */ @@ -631,10 +671,10 @@ makebreak: /* * The character wasn't in the current curve base so load it - * But if the font is FO_BUILTIN_NAME then do not try loading since + * But if the font is built-in then do not try loading since * whole font is in the memory already */ - if (che == NULL && strcmp(vfont->name, FO_BUILTIN_NAME)) { + if (che == NULL && BKE_vfont_is_builtin(vfont) == FALSE) { BLI_vfontchar_from_freetypefont(vfont, ascii); } @@ -665,7 +705,10 @@ makebreak: twidth = char_width(cu, che, info); /* Calculate positions */ - if ((tb->w != 0.0f) && (ct->dobreak == 0) && ((xof - (tb->x / cu->fsize) + twidth) * cu->fsize) > tb->w + cu->xof * cu->fsize) { + if ((tb->w != 0.0f) && + (ct->dobreak == 0) && + (((xof - (tb->x / cu->fsize) + twidth) * cu->fsize) > tb->w + cu->xof * cu->fsize)) + { // fprintf(stderr, "linewidth exceeded: %c%c%c...\n", mem[i], mem[i+1], mem[i+2]); for (j = i; j && (mem[j] != '\n') && (mem[j] != '\r') && (chartransdata[j].dobreak == 0); j--) { if (mem[j] == ' ' || mem[j] == '-') { @@ -691,6 +734,7 @@ makebreak: } } } + if (ascii == '\n' || ascii == '\r' || ascii == 0 || ct->dobreak) { ct->xof = xof; ct->yof = yof; @@ -760,15 +804,18 @@ makebreak: wsfac = cu->wordspace; wsnr++; } - else wsfac = 1.0f; + else { + wsfac = 1.0f; + } /* Set the width of the character */ twidth = char_width(cu, che, info); xof += (twidth * wsfac * (1.0f + (info->kern / 40.0f)) ) + xtrax; - if (sb) + if (sb) { sb->w = (xof * cu->fsize) - sb->w; + } } ct++; } @@ -812,7 +859,7 @@ makebreak: /* do nothing */ } -// if ((mem[j]!='\r') && (mem[j]!='\n') && (mem[j])) { +// if ((mem[j] != '\r') && (mem[j] != '\n') && (mem[j])) { ct->xof += ct->charnr * linedata[ct->linenr]; // } ct++; @@ -887,11 +934,14 @@ makebreak: else if (cu->spacemode == CU_MIDDLE) { timeofs = (1.0f - distfac) / 2.0f; } - else if (cu->spacemode == CU_FLUSH) distfac = 1.0f; - + else if (cu->spacemode == CU_FLUSH) { + distfac = 1.0f; + } } - else distfac = 1.0; - + else { + distfac = 1.0; + } + distfac /= (maxx - minx); timeofs += distfac * cu->xof; /* not cyclic */ @@ -920,10 +970,10 @@ makebreak: mul_v3_fl(vec, sizefac); - ct->rot = (float)(M_PI - atan2(rotvec[1], rotvec[0])); + ct->rot = (float)M_PI - atan2f(rotvec[1], rotvec[0]); - si = (float)sin(ct->rot); - co = (float)cos(ct->rot); + si = sinf(ct->rot); + co = cosf(ct->rot); yof = ct->yof; @@ -986,21 +1036,21 @@ makebreak: f = cu->editfont->textcurs[0]; f[0] = cu->fsize * (-0.1f * co + ct->xof); - f[1] = cu->fsize * (0.1f * si + ct->yof); + f[1] = cu->fsize * ( 0.1f * si + ct->yof); - f[2] = cu->fsize * (0.1f * co + ct->xof); + f[2] = cu->fsize * ( 0.1f * co + ct->xof); f[3] = cu->fsize * (-0.1f * si + ct->yof); - f[4] = cu->fsize * (0.1f * co + 0.8f * si + ct->xof); + f[4] = cu->fsize * ( 0.1f * co + 0.8f * si + ct->xof); f[5] = cu->fsize * (-0.1f * si + 0.8f * co + ct->yof); f[6] = cu->fsize * (-0.1f * co + 0.8f * si + ct->xof); - f[7] = cu->fsize * (0.1f * si + 0.8f * co + ct->yof); + f[7] = cu->fsize * ( 0.1f * si + 0.8f * co + ct->yof); } MEM_freeN(linedata); - MEM_freeN(linedata2); + MEM_freeN(linedata2); MEM_freeN(linedata3); MEM_freeN(linedata4); @@ -1031,7 +1081,8 @@ makebreak: float ulwidth, uloverlap = 0.0f; if ((i < (slen - 1)) && (mem[i + 1] != '\n') && (mem[i + 1] != '\r') && - ((mem[i + 1] != ' ') || (custrinfo[i + 1].flag & CU_CHINFO_UNDERLINE)) && ((custrinfo[i + 1].flag & CU_CHINFO_WRAP) == 0)) + ((mem[i + 1] != ' ') || (custrinfo[i + 1].flag & CU_CHINFO_UNDERLINE)) && + ((custrinfo[i + 1].flag & CU_CHINFO_WRAP) == 0)) { uloverlap = xtrax + 0.1f; } diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 658be1fb494..21b335aa1e9 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -603,7 +603,7 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char if (floatbuf) { ibuf = IMB_allocImBuf(width, height, depth, IB_rectfloat); - rect_float = (float *)ibuf->rect_float; + rect_float = ibuf->rect_float; ibuf->profile = IB_PROFILE_LINEAR_RGB; } else { @@ -969,7 +969,6 @@ int BKE_imtype_is_movie(const char imtype) switch (imtype) { case R_IMF_IMTYPE_AVIRAW: case R_IMF_IMTYPE_AVIJPEG: - case R_IMF_IMTYPE_AVICODEC: case R_IMF_IMTYPE_QUICKTIME: case R_IMF_IMTYPE_FFMPEG: case R_IMF_IMTYPE_H264: @@ -1084,7 +1083,6 @@ char BKE_imtype_from_arg(const char *imtype_arg) else if (!strcmp(imtype_arg, "AVIRAW")) return R_IMF_IMTYPE_AVIRAW; else if (!strcmp(imtype_arg, "AVIJPEG")) return R_IMF_IMTYPE_AVIJPEG; else if (!strcmp(imtype_arg, "PNG")) return R_IMF_IMTYPE_PNG; - else if (!strcmp(imtype_arg, "AVICODEC")) return R_IMF_IMTYPE_AVICODEC; else if (!strcmp(imtype_arg, "QUICKTIME")) return R_IMF_IMTYPE_QUICKTIME; else if (!strcmp(imtype_arg, "BMP")) return R_IMF_IMTYPE_BMP; #ifdef WITH_HDR @@ -1180,7 +1178,7 @@ int BKE_add_image_extension(char *string, const char imtype) extension = ".jp2"; } #endif - else { // R_IMF_IMTYPE_AVICODEC, R_IMF_IMTYPE_AVIRAW, R_IMF_IMTYPE_AVIJPEG, R_IMF_IMTYPE_JPEG90, R_IMF_IMTYPE_QUICKTIME etc + else { // R_IMF_IMTYPE_AVIRAW, R_IMF_IMTYPE_AVIJPEG, R_IMF_IMTYPE_JPEG90, R_IMF_IMTYPE_QUICKTIME etc if (!(BLI_testextensie(string, ".jpg") || BLI_testextensie(string, ".jpeg"))) extension = ".jpg"; } diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 2fe567cc9bf..8de9640eb35 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -2094,7 +2094,7 @@ void do_versions_ipos_to_animato(Main *main) bAction *new_act; /* add a new action for this, and convert all data into that action */ - new_act = add_empty_action("ConvIPO_Action"); // XXX need a better name... + new_act = add_empty_action(id->name+2); ipo_to_animato(NULL, ipo, NULL, NULL, NULL, NULL, &new_act->curves, &drivers); new_act->idroot = ipo->blocktype; } diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index f3ef01425dd..e073cfdf76d 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -360,6 +360,9 @@ int id_copy(ID *id, ID **newid, int test) return 0; /* can't be copied from here */ case ID_GD: return 0; /* not implemented */ + case ID_MSK: + if (!test) *newid = (ID *)BKE_mask_copy((Mask *)id); + return 1; } return 0; diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 6fe838666c5..f41d8feef0b 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -56,8 +56,6 @@ #include "BKE_movieclip.h" #include "BKE_utildefines.h" -#include "raskter.h" - static MaskSplinePoint *mask_spline_point_next(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point) { if (point == &points_array[spline->tot_point - 1]) { @@ -156,6 +154,7 @@ MaskLayer *BKE_mask_layer_new(Mask *mask, const char *name) mask->masklay_tot++; + masklay->blend = MASK_BLEND_MERGE; masklay->alpha = 1.0f; return masklay; @@ -188,28 +187,48 @@ void BKE_mask_layer_unique_name(Mask *mask, MaskLayer *masklay) BLI_uniquename(&mask->masklayers, masklay, "MaskLayer", '.', offsetof(MaskLayer, name), sizeof(masklay->name)); } -MaskLayer *BKE_mask_layer_copy(MaskLayer *layer) +MaskLayer *BKE_mask_layer_copy(MaskLayer *masklay) { - MaskLayer *layer_new; + MaskLayer *masklay_new; MaskSpline *spline; - layer_new = MEM_callocN(sizeof(MaskLayer), "new mask layer"); + masklay_new = MEM_callocN(sizeof(MaskLayer), "new mask layer"); - BLI_strncpy(layer_new->name, layer->name, sizeof(layer_new->name)); + BLI_strncpy(masklay_new->name, masklay->name, sizeof(masklay_new->name)); - layer_new->alpha = layer->alpha; - layer_new->blend = layer->blend; - layer_new->blend_flag = layer->blend_flag; - layer_new->flag = layer->flag; - layer_new->restrictflag = layer->restrictflag; + masklay_new->alpha = masklay->alpha; + masklay_new->blend = masklay->blend; + masklay_new->blend_flag = masklay->blend_flag; + masklay_new->flag = masklay->flag; + masklay_new->restrictflag = masklay->restrictflag; - for (spline = layer->splines.first; spline; spline = spline->next) { + for (spline = masklay->splines.first; spline; spline = spline->next) { MaskSpline *spline_new = BKE_mask_spline_copy(spline); - BLI_addtail(&layer_new->splines, spline_new); + BLI_addtail(&masklay_new->splines, spline_new); + } + + /* correct animation */ + if (masklay->splines_shapes.first) { + MaskLayerShape *masklay_shape; + MaskLayerShape *masklay_shape_new; + + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + masklay_shape_new = MEM_callocN(sizeof(MaskLayerShape), "new mask layer shape"); + + masklay_shape_new->data = MEM_dupallocN(masklay_shape->data); + masklay_shape_new->tot_vert = masklay_shape->tot_vert; + masklay_shape_new->flag = masklay_shape->flag; + masklay_shape_new->frame = masklay_shape->frame; + + BLI_addtail(&masklay_new->splines_shapes, masklay_shape_new); + } } - return layer_new; + return masklay_new; } void BKE_mask_layer_copy_list(ListBase *masklayers_new, ListBase *masklayers) @@ -246,10 +265,10 @@ MaskSpline *BKE_mask_spline_add(MaskLayer *masklay) return spline; } -int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height) +unsigned int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height) { float max_segment = 0.01f; - int i, resol = 1; + unsigned int i, resol = 1; if (width != 0 && height != 0) { if (width >= height) @@ -262,7 +281,7 @@ int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height) MaskSplinePoint *point = &spline->points[i]; BezTriple *bezt, *bezt_next; float a, b, c, len; - int cur_resol; + unsigned int cur_resol; bezt = &point->bezt; bezt_next = mask_spline_point_next_bezt(spline, spline->points, point); @@ -279,18 +298,27 @@ int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height) cur_resol = len / max_segment; resol = MAX2(resol, cur_resol); + + if (resol >= MASK_RESOL_MAX) { + break; + } } - return resol; + return CLAMPIS(resol, 1, MASK_RESOL_MAX); } -int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height) +unsigned int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height) { const float max_segment = 0.005; - int resol = BKE_mask_spline_resolution(spline, width, height); + unsigned int resol = BKE_mask_spline_resolution(spline, width, height); float max_jump = 0.0f; int i; + /* avoid checking the featrher if we already hit the maximum value */ + if (resol >= MASK_RESOL_MAX) { + return MASK_RESOL_MAX; + } + for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; float prev_u, prev_w; @@ -300,9 +328,16 @@ int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height prev_w = point->bezt.weight; for (j = 0; j < point->tot_uw; j++) { - float jump = fabsf((point->uw[j].w - prev_w) / (point->uw[j].u - prev_u)); + const float w_diff = (point->uw[j].w - prev_w); + const float u_diff = (point->uw[j].u - prev_u); - max_jump = MAX2(max_jump, jump); + /* avoid divide by zero and very high values, + * though these get clamped eventually */ + if (u_diff > FLT_EPSILON) { + float jump = fabsf(w_diff / u_diff); + + max_jump = MAX2(max_jump, jump); + } prev_u = point->uw[j].u; prev_w = point->uw[j].w; @@ -311,29 +346,22 @@ int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height resol += max_jump / max_segment; - return resol; + return CLAMPIS(resol, 1, MASK_RESOL_MAX); } -int BKE_mask_spline_differentiate_calc_total(const MaskSpline *spline, const int resol) +int BKE_mask_spline_differentiate_calc_total(const MaskSpline *spline, const unsigned int resol) { - int len; - - /* count */ - len = (spline->tot_point - 1) * resol; - if (spline->flag & MASK_SPLINE_CYCLIC) { - len += resol; + return spline->tot_point * resol; } else { - len++; + return ((spline->tot_point - 1) * resol) + 1; } - - return len; } float (*BKE_mask_spline_differentiate_with_resolution_ex(MaskSpline *spline, int *tot_diff_point, - const int resol + const unsigned int resol ))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); @@ -394,7 +422,7 @@ float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline, int wi int *tot_diff_point ))[2] { - int resol = BKE_mask_spline_resolution(spline, width, height); + int unsigned resol = BKE_mask_spline_resolution(spline, width, height); return BKE_mask_spline_differentiate_with_resolution_ex(spline, tot_diff_point, resol); } @@ -674,7 +702,7 @@ static void spline_feather_collapse_inner_loops(MaskSpline *spline, float (*feat */ float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpline *spline, int *tot_feather_point, - const int resol, + const unsigned int resol, const int do_collapse ))[2] { @@ -748,7 +776,7 @@ float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpl float (*BKE_mask_spline_feather_differentiated_points_with_resolution(MaskSpline *spline, int width, int height, int *tot_feather_point))[2] { - int resol = BKE_mask_spline_feather_resolution(spline, width, height); + unsigned int resol = BKE_mask_spline_feather_resolution(spline, width, height); return BKE_mask_spline_feather_differentiated_points_with_resolution_ex(spline, tot_feather_point, resol, FALSE); } @@ -1025,10 +1053,11 @@ void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], int keep_di float *BKE_mask_point_segment_feather_diff_with_resolution(MaskSpline *spline, MaskSplinePoint *point, int width, int height, - int *tot_feather_point) + unsigned int *tot_feather_point) { float *feather, *fp; - int i, resol = BKE_mask_spline_feather_resolution(spline, width, height); + unsigned int resol = BKE_mask_spline_feather_resolution(spline, width, height); + unsigned int i; feather = fp = MEM_callocN(2 * resol * sizeof(float), "mask point spline feather diff points"); @@ -1049,13 +1078,13 @@ float *BKE_mask_point_segment_feather_diff_with_resolution(MaskSpline *spline, M return feather; } -float *BKE_mask_point_segment_feather_diff(MaskSpline *spline, MaskSplinePoint *point, int *tot_feather_point) +float *BKE_mask_point_segment_feather_diff(MaskSpline *spline, MaskSplinePoint *point, unsigned int *tot_feather_point) { return BKE_mask_point_segment_feather_diff_with_resolution(spline, point, 0, 0, tot_feather_point); } float *BKE_mask_point_segment_diff_with_resolution(MaskSpline *spline, MaskSplinePoint *point, - int width, int height, int *tot_diff_point) + int width, int height, unsigned int *tot_diff_point) { MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point); @@ -1084,7 +1113,7 @@ float *BKE_mask_point_segment_diff_with_resolution(MaskSpline *spline, MaskSplin return diff_points; } -float *BKE_mask_point_segment_diff(MaskSpline *spline, MaskSplinePoint *point, int *tot_diff_point) +float *BKE_mask_point_segment_diff(MaskSpline *spline, MaskSplinePoint *point, unsigned int *tot_diff_point) { return BKE_mask_point_segment_diff_with_resolution(spline, point, 0, 0, tot_diff_point); } @@ -1258,12 +1287,13 @@ MaskSplinePointUW *BKE_mask_point_sort_uw(MaskSplinePoint *point, MaskSplinePoin void BKE_mask_point_add_uw(MaskSplinePoint *point, float u, float w) { if (!point->uw) - point->uw = MEM_callocN(sizeof(*point->uw), "mask point uw"); + point->uw = MEM_mallocN(sizeof(*point->uw), "mask point uw"); else point->uw = MEM_reallocN(point->uw, (point->tot_uw + 1) * sizeof(*point->uw)); point->uw[point->tot_uw].u = u; point->uw[point->tot_uw].w = w; + point->uw[point->tot_uw].flag = 0; point->tot_uw++; @@ -1308,6 +1338,8 @@ static Mask *mask_alloc(const char *name) mask = BKE_libblock_alloc(&G.main->mask, ID_MSK, name); + mask->id.flag |= LIB_FAKEUSER; + return mask; } @@ -1330,6 +1362,49 @@ Mask *BKE_mask_new(const char *name) return mask; } +Mask *BKE_mask_copy_nolib(Mask *mask) +{ + Mask *mask_new; + + mask_new = MEM_dupallocN(mask); + + /*take care here! - we may want to copy anim data */ + mask_new->adt = NULL; + + mask_new->masklayers.first = NULL; + mask_new->masklayers.last = NULL; + + BKE_mask_layer_copy_list(&mask_new->masklayers, &mask->masklayers); + + /* enable fake user by default */ + if (!(mask_new->id.flag & LIB_FAKEUSER)) { + mask_new->id.flag |= LIB_FAKEUSER; + mask_new->id.us++; + } + + return mask_new; +} + +Mask *BKE_mask_copy(Mask *mask) +{ + Mask *mask_new; + + mask_new = BKE_libblock_copy(&mask->id); + + mask_new->masklayers.first = NULL; + mask_new->masklayers.last = NULL; + + BKE_mask_layer_copy_list(&mask_new->masklayers, &mask->masklayers); + + /* enable fake user by default */ + if (!(mask_new->id.flag & LIB_FAKEUSER)) { + mask_new->id.flag |= LIB_FAKEUSER; + mask_new->id.us++; + } + + return mask_new; +} + void BKE_mask_point_free(MaskSplinePoint *point) { if (point->uw) @@ -1484,8 +1559,8 @@ void BKE_mask_unlink(Main *bmain, Mask *mask) if (sl->spacetype == SPACE_CLIP) { SpaceClip *sc = (SpaceClip *) sl; - if (sc->mask == mask) - sc->mask = NULL; + if (sc->mask_info.mask == mask) + sc->mask_info.mask = NULL; } } } @@ -1494,48 +1569,64 @@ void BKE_mask_unlink(Main *bmain, Mask *mask) mask->id.us = 0; } -void BKE_mask_coord_from_movieclip(MovieClip *clip, MovieClipUser *user, float r_co[2], const float co[2]) +void BKE_mask_coord_from_frame(float r_co[2], const float co[2], const float frame_size[2]) { - int width, height; - - /* scaling for the clip */ - BKE_movieclip_get_size(clip, user, &width, &height); - - if (width == height) { + if (frame_size[0] == frame_size[1]) { r_co[0] = co[0]; r_co[1] = co[1]; } - else if (width < height) { - r_co[0] = ((co[0] - 0.5f) * ((float)width / (float)height)) + 0.5f; + else if (frame_size[0] < frame_size[1]) { + r_co[0] = ((co[0] - 0.5f) * (frame_size[0] / frame_size[1])) + 0.5f; r_co[1] = co[1]; } - else { /* (width > height) */ + else { /* (frame_size[0] > frame_size[1]) */ r_co[0] = co[0]; - r_co[1] = ((co[1] - 0.5f) * ((float)height / (float)width)) + 0.5f; + r_co[1] = ((co[1] - 0.5f) * (frame_size[1] / frame_size[0])) + 0.5f; } } - -/* as above but divide */ -void BKE_mask_coord_to_movieclip(MovieClip *clip, MovieClipUser *user, float r_co[2], const float co[2]) +void BKE_mask_coord_from_movieclip(MovieClip *clip, MovieClipUser *user, float r_co[2], const float co[2]) { int width, height; + float frame_size[2]; /* scaling for the clip */ BKE_movieclip_get_size(clip, user, &width, &height); - if (width == height) { + frame_size[0] = (float)width; + frame_size[1] = (float)height; + + BKE_mask_coord_from_frame(r_co, co, frame_size); +} + +/* as above but divide */ +void BKE_mask_coord_to_frame(float r_co[2], const float co[2], const float frame_size[2]) +{ + if (frame_size[0] == frame_size[1]) { r_co[0] = co[0]; r_co[1] = co[1]; } - else if (width < height) { - r_co[0] = ((co[0] - 0.5f) / ((float)width / (float)height)) + 0.5f; + else if (frame_size[0] < frame_size[1]) { + r_co[0] = ((co[0] - 0.5f) / (frame_size[0] / frame_size[1])) + 0.5f; r_co[1] = co[1]; } - else { /* (width > height) */ + else { /* (frame_size[0] > frame_size[1]) */ r_co[0] = co[0]; - r_co[1] = ((co[1] - 0.5f) / ((float)height / (float)width)) + 0.5f; + r_co[1] = ((co[1] - 0.5f) / (frame_size[1] / frame_size[0])) + 0.5f; } } +void BKE_mask_coord_to_movieclip(MovieClip *clip, MovieClipUser *user, float r_co[2], const float co[2]) +{ + int width, height; + float frame_size[2]; + + /* scaling for the clip */ + BKE_movieclip_get_size(clip, user, &width, &height); + + frame_size[0] = (float)width; + frame_size[1] = (float)height; + + BKE_mask_coord_to_frame(r_co, co, frame_size); +} static int BKE_mask_evaluate_parent(MaskParent *parent, float ctime, float r_co[2]) { @@ -1556,9 +1647,8 @@ static int BKE_mask_evaluate_parent(MaskParent *parent, float ctime, float r_co[ user.framenr = ctime; if (track) { - MovieTrackingMarker *marker = BKE_tracking_marker_get(track, clip_framenr); float marker_pos_ofs[2]; - add_v2_v2v2(marker_pos_ofs, marker->pos, track->offset); + BKE_tracking_marker_get_subframe_position(track, clip_framenr, marker_pos_ofs); BKE_mask_coord_from_movieclip(clip, &user, r_co, marker_pos_ofs); return TRUE; @@ -2444,256 +2534,7 @@ void BKE_mask_layer_shape_changed_remove(MaskLayer *masklay, int index, int coun } } -/* local functions */ -static void invert_vn_vn(float *array, const int size) -{ - float *arr = array + (size - 1); - int i = size; - while (i--) { - *(arr) = 1.0f - *(arr); - arr--; - } -} - -static void m_invert_vn_vn(float *array, const float f, const int size) -{ - float *arr = array + (size - 1); - int i = size; - while (i--) { - *(arr) = 1.0f - (*(arr) * f); - arr--; - } -} - -static void clamp_vn_vn(float *array, const int size) -{ - float *arr = array + (size - 1); - - int i = size; - while (i--) { - if (*arr < 0.0f) *arr = 0.0f; - else if (*arr > 1.0f) *arr = 1.0f; - arr--; - } -} - int BKE_mask_get_duration(Mask *mask) { - return MAX2(1, mask->efra - mask->sfra); -} - -/* rasterization */ -void BKE_mask_rasterize_layers(ListBase *masklayers, int width, int height, float *buffer, - const short do_aspect_correct, const short do_mask_aa, - const short do_feather) -{ - MaskLayer *masklay; - - /* temp blending buffer */ - const int buffer_size = width * height; - float *buffer_tmp = MEM_mallocN(sizeof(float) * buffer_size, __func__); - - for (masklay = masklayers->first; masklay; masklay = masklay->next) { - MaskSpline *spline; - float alpha; - - if (masklay->restrictflag & MASK_RESTRICT_RENDER) { - continue; - } - - memset(buffer_tmp, 0, sizeof(float) * buffer_size); - - for (spline = masklay->splines.first; spline; spline = spline->next) { - float (*diff_points)[2]; - int tot_diff_point; - - float (*diff_feather_points)[2]; - int tot_diff_feather_points; - - diff_points = BKE_mask_spline_differentiate_with_resolution(spline, width, height, - &tot_diff_point); - - if (tot_diff_point) { - if (do_feather) { - diff_feather_points = - BKE_mask_spline_feather_differentiated_points_with_resolution(spline, width, height, - &tot_diff_feather_points); - } - else { - tot_diff_feather_points = 0; - diff_feather_points = NULL; - } - - if (do_aspect_correct) { - if (width != height) { - float *fp; - float *ffp; - int i; - float asp; - - if (width < height) { - fp = &diff_points[0][0]; - ffp = tot_diff_feather_points ? &diff_feather_points[0][0] : NULL; - asp = (float)width / (float)height; - } - else { - fp = &diff_points[0][1]; - ffp = tot_diff_feather_points ? &diff_feather_points[0][1] : NULL; - asp = (float)height / (float)width; - } - - for (i = 0; i < tot_diff_point; i++, fp += 2) { - (*fp) = (((*fp) - 0.5f) / asp) + 0.5f; - } - - if (tot_diff_feather_points) { - for (i = 0; i < tot_diff_feather_points; i++, ffp += 2) { - (*ffp) = (((*ffp) - 0.5f) / asp) + 0.5f; - } - } - } - } - - if (tot_diff_point) { - PLX_raskterize(diff_points, tot_diff_point, - buffer_tmp, width, height,do_mask_aa); - - if (tot_diff_feather_points) { - PLX_raskterize_feather(diff_points, tot_diff_point, - diff_feather_points, tot_diff_feather_points, - buffer_tmp, width, height); - MEM_freeN(diff_feather_points); - } - - MEM_freeN(diff_points); - } - } - } - - /* blend with original */ - if (masklay->blend_flag & MASK_BLENDFLAG_INVERT) { - /* apply alpha multiply before inverting */ - if (masklay->alpha != 1.0f) { - m_invert_vn_vn(buffer_tmp, masklay->alpha, buffer_size); - } - else { - invert_vn_vn(buffer_tmp, buffer_size); - } - - alpha = 1.0f; - } - else { - alpha = masklay->alpha; - } - - switch (masklay->blend) { - case MASK_BLEND_SUBTRACT: - { - if (alpha == 1.0f) { - sub_vn_vn(buffer, buffer_tmp, buffer_size); - } - else { - msub_vn_vn(buffer, buffer_tmp, alpha, buffer_size); - } - break; - } - case MASK_BLEND_ADD: - default: - { - if (alpha == 1.0f) { - add_vn_vn(buffer, buffer_tmp, buffer_size); - } - else { - madd_vn_vn(buffer, buffer_tmp, alpha, buffer_size); - } - break; - } - } - - if (do_mask_aa) { - //PLX_antialias_buffer(buffer,width,height); - } - /* clamp at the end */ - clamp_vn_vn(buffer, buffer_size); - } - MEM_freeN(buffer_tmp); -} - -#ifdef __PLX_RASKTER_MT__ -void BKE_mask_init_layers(Mask *mask, struct layer_init_data *mlayer_data, int width, int height, const short do_aspect_correct) -{ - MaskLayer *masklay; - int numLayers=0; - int currLayer=0; - for (masklay = mask->masklayers->first; masklay; masklay = masklay->next) { - numLayers++; - } - mlayer_data = MEM_mallocN(sizeof(struct layer_init_data) * numLayers, __func__); //size correct? - - - for (masklay = mask->masklayers->first; masklay; masklay = masklay->next) { - MaskSpline *spline; - for (spline = masklay->splines.first; spline; spline = spline->next) { - float (*diff_points)[2]; - int tot_diff_point; - - float (*diff_feather_points)[2]; - int tot_diff_feather_points; - - diff_points = BKE_mask_spline_differentiate_with_resolution(spline, width, height, - &tot_diff_point); - - if (tot_diff_point) { - if (do_feather) { - diff_feather_points = - BKE_mask_spline_feather_differentiated_points_with_resolution(spline, width, height, - &tot_diff_feather_points); - } - else { - tot_diff_feather_points = 0; - diff_feather_points = NULL; - } - - if (do_aspect_correct) { - if (width != height) { - float *fp; - float *ffp; - int i; - float asp; - - if (width < height) { - fp = &diff_points[0][0]; - ffp = tot_diff_feather_points ? &diff_feather_points[0][0] : NULL; - asp = (float)width / (float)height; - } - else { - fp = &diff_points[0][1]; - ffp = tot_diff_feather_points ? &diff_feather_points[0][1] : NULL; - asp = (float)height / (float)width; - } - - for (i = 0; i < tot_diff_point; i++, fp += 2) { - (*fp) = (((*fp) - 0.5f) / asp) + 0.5f; - } - - if (tot_diff_feather_points) { - for (i = 0; i < tot_diff_feather_points; i++, ffp += 2) { - (*ffp) = (((*ffp) - 0.5f) / asp) + 0.5f; - } - } - } - } - PLX_init_base_data(mlayer_data[currLayer], diff_points, tot_diff_points, width, height); - currLayer++; - } - } - } -} -#endif - -void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer, - const short do_aspect_correct, const short do_mask_aa, - const short do_feather) -{ - BKE_mask_rasterize_layers(&mask->masklayers, width, height, buffer, do_aspect_correct, do_mask_aa, do_feather); + return maxi(1, mask->efra - mask->sfra); } diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index b05c1ad4eaa..9e1f4e2cfb2 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -45,8 +45,6 @@ #include "BKE_mask.h" -#ifndef USE_RASKTER - /* this is rather and annoying hack, use define to isolate it. * problem is caused by scanfill removing edges on us. */ #define USE_SCANFILL_EDGE_WORKAROUND @@ -579,9 +577,9 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas float (*diff_feather_points)[2]; int tot_diff_feather_points; - const int resol_a = BKE_mask_spline_resolution(spline, width, height) / 4; - const int resol_b = BKE_mask_spline_feather_resolution(spline, width, height) / 4; - const int resol = CLAMPIS(MAX2(resol_a, resol_b), 4, 512); + const unsigned int resol_a = BKE_mask_spline_resolution(spline, width, height) / 4; + const unsigned int resol_b = BKE_mask_spline_feather_resolution(spline, width, height) / 4; + const unsigned int resol = CLAMPIS(MAX2(resol_a, resol_b), 4, 512); diff_points = BKE_mask_spline_differentiate_with_resolution_ex( spline, &tot_diff_point, resol); @@ -1251,6 +1249,9 @@ float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x } switch (layer->blend) { + case MASK_BLEND_MERGE: + value += value_layer * (1.0f - value); + break; case MASK_BLEND_ADD: value += value_layer; break; @@ -1286,4 +1287,36 @@ float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x return value; } -#endif /* USE_RASKTER */ +/** + * \brief Rasterize a buffer from a single mask + * + * We could get some speedup by inlining #BKE_maskrasterize_handle_sample + * and calculating each layer then blending buffers, but this function is only + * used by the sequencer - so better have the caller thread. + * + * Since #BKE_maskrasterize_handle_sample is used threaded elsewhere, + * we can simply use openmp here for some speedup. + */ +void BKE_maskrasterize_buffer(MaskRasterHandle *mr_handle, + const unsigned int width, const unsigned int height, + float *buffer) +{ +#ifdef _MSC_VER + int y; /* msvc requires signed for some reason */ +#else + unsigned int y; +#endif + +#pragma omp parallel for private(y) + for (y = 0; y < height; y++) { + unsigned int i = y * width; + unsigned int x; + float xy[2]; + xy[1] = (float)y / (float)height; + for (x = 0; x < width; x++, i++) { + xy[0] = (float)x / (float)width; + + buffer[i] = BKE_maskrasterize_handle_sample(mr_handle, xy); + } + } +} diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index c605f33b98f..f97dd2f859d 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -1030,13 +1030,18 @@ static int material_in_nodetree(bNodeTree *ntree, Material *mat) bNode *node; for (node = ntree->nodes.first; node; node = node->next) { - if (node->id && GS(node->id->name) == ID_MA) { - if (node->id == (ID *)mat) - return 1; + if (node->id) { + if (GS(node->id->name) == ID_MA) { + if (node->id == (ID *)mat) { + return 1; + } + } + else if (node->type == NODE_GROUP) { + if (material_in_nodetree((bNodeTree *)node->id, mat)) { + return 1; + } + } } - else if (node->type == NODE_GROUP) - if (material_in_nodetree((bNodeTree *)node->id, mat)) - return 1; } return 0; @@ -1056,28 +1061,24 @@ int material_in_material(Material *parmat, Material *mat) /* ****************** */ /* Update drivers for materials in a nodetree */ -static void material_node_drivers_update(Scene *scene, bNodeTree *ntree, float ctime, Material *rootma) +static void material_node_drivers_update(Scene *scene, bNodeTree *ntree, float ctime) { bNode *node; - Material *ma; /* nodetree itself */ if (ntree->adt && ntree->adt->drivers.first) { BKE_animsys_evaluate_animdata(scene, &ntree->id, ntree->adt, ctime, ADT_RECALC_DRIVERS); } - /* nodes... */ + /* nodes */ for (node = ntree->nodes.first; node; node = node->next) { - if (node->id && GS(node->id->name) == ID_MA) { - /* TODO: prevent infinite recursion here... */ - ma = (Material *)node->id; - if (ma != rootma) { - material_drivers_update(scene, ma, ctime); - } - } - else if (node->type == NODE_GROUP && node->id) { - material_node_drivers_update(scene, (bNodeTree *)node->id, - ctime, rootma); + if (node->id) { + if (GS(node->id->name) == ID_MA) { + material_drivers_update(scene, (Material *)node->id, ctime); + } + else if (node->type == NODE_GROUP) { + material_node_drivers_update(scene, (bNodeTree *)node->id, ctime); + } } } } @@ -1092,6 +1093,15 @@ void material_drivers_update(Scene *scene, Material *ma, float ctime) //if (G.f & G_DEBUG) // printf("material_drivers_update(%s, %s)\n", scene->id.name, ma->id.name); + /* Prevent infinite recursion by checking (and tagging the material) as having been visited already + * (see BKE_scene_update_tagged()). This assumes ma->id.flag & LIB_DOIT isn't set by anything else + * in the meantime... [#32017] + */ + if (ma->id.flag & LIB_DOIT) + return; + else + ma->id.flag |= LIB_DOIT; + /* material itself */ if (ma->adt && ma->adt->drivers.first) { BKE_animsys_evaluate_animdata(scene, &ma->id, ma->adt, ctime, ADT_RECALC_DRIVERS); @@ -1099,7 +1109,7 @@ void material_drivers_update(Scene *scene, Material *ma, float ctime) /* nodes */ if (ma->nodetree) { - material_node_drivers_update(scene, ma->nodetree, ctime, ma); + material_node_drivers_update(scene, ma->nodetree, ctime); } } diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index c5752e193df..77cd127e6ea 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -394,6 +394,7 @@ void BKE_mesh_unlink(Mesh *me) if (me == NULL) return; + if (me->mat) for (a = 0; a < me->totcol; a++) { if (me->mat[a]) me->mat[a]->id.us--; me->mat[a] = NULL; @@ -1234,19 +1235,21 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert, allvert, totvert, alledge, totedge, allloop, allpoly, - totloop, totpoly); + totloop, totpoly, NULL); } /* BMESH: this doesn't calculate all edges from polygons, * only free standing edges are calculated */ /* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */ -/* use specified dispbase */ +/* use specified dispbase */ +/* TODO: orco values for non DL_SURF types */ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, MVert **allvert, int *_totvert, MEdge **alledge, int *_totedge, MLoop **allloop, MPoly **allpoly, - int *_totloop, int *_totpoly) + int *_totloop, int *_totpoly, + int **orco_index_ptr) { DispList *dl; Curve *cu; @@ -1258,6 +1261,7 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, int a, b, ofs, vertcount, startvert, totvert = 0, totedge = 0, totloop = 0, totvlak = 0; int p1, p2, p3, p4, *index; int conv_polys = 0; + int (*orco_index)[4] = NULL; cu = ob->data; @@ -1308,6 +1312,11 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, /* verts and faces */ vertcount = 0; + if (orco_index_ptr) { + *orco_index_ptr = MEM_callocN(sizeof(int) * totvlak * 4, "nurbs_init orco"); + orco_index = (int (*)[4]) *orco_index_ptr; + } + dl = dispbase->first; while (dl) { int smooth = dl->rt & CU_SMOOTH ? 1 : 0; @@ -1385,8 +1394,6 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, mloop += 3; index += 3; } - - } else if (dl->type == DL_SURF) { startvert = vertcount; @@ -1431,6 +1438,15 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, mpoly->totloop = 4; mpoly->mat_nr = dl->col; + if (orco_index) { + const int poly_index = mpoly - *allpoly; + const int p_orco_base = startvert + ((dl->nr + 1) * a) + b; + orco_index[poly_index][0] = p_orco_base + 1; + orco_index[poly_index][1] = p_orco_base + dl->nr + 2; + orco_index[poly_index][2] = p_orco_base + dl->nr + 1; + orco_index[poly_index][3] = p_orco_base; + } + if (smooth) mpoly->flag |= ME_SMOOTH; mpoly++; mloop += 4; @@ -1461,8 +1477,34 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, return 0; } + +MINLINE void copy_uv_orco_v2_v2(float r[2], const float a[2]) +{ + r[0] = 0.5f + a[0] * 0.5f; + r[1] = 0.5f + a[1] * 0.5f; +} + +/** + * orco is normally from #BKE_curve_make_orco + */ +void BKE_mesh_nurbs_to_mdata_orco(MPoly *mpoly, int totpoly, + MLoop *mloops, MLoopUV *mloopuvs, + float (*orco)[3], int (*orco_index)[4]) +{ + MPoly *mp; + + int i, j; + for (i = 0, mp = mpoly; i < totpoly; i++, mp++) { + MLoop *ml = mloops + mp->loopstart; + MLoopUV *mluv = mloopuvs + mp->loopstart; + for (j = 0; j < mp->totloop; j++, ml++, mluv++) { + copy_uv_orco_v2_v2(mluv->uv, orco[orco_index[i][j]]); + } + } +} + /* this may fail replacing ob->data, be sure to check ob->type */ -void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase) +void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr) { Main *bmain = G.main; Object *ob1; @@ -1480,7 +1522,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase) if (dm == NULL) { if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge, &totedge, &allloop, - &allpoly, &totloop, &totpoly) != 0) + &allpoly, &totloop, &totpoly, orco_index_ptr) != 0) { /* Error initializing */ return; @@ -1536,7 +1578,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase) void BKE_mesh_from_nurbs(Object *ob) { - return BKE_mesh_from_nurbs_displist(ob, &ob->disp); + BKE_mesh_from_nurbs_displist(ob, &ob->disp, NULL); } typedef struct EdgeLink { diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index de367b6b4d0..4c23a370a5d 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -504,7 +504,9 @@ static void movieclip_load_get_szie(MovieClip *clip) if (width && height) { clip->tracking.camera.principal[0] = ((float)width) / 2.0f; clip->tracking.camera.principal[1] = ((float)height) / 2.0f; - + } + else { + clip->lastsize[0] = clip->lastsize[1] = IMG_SIZE_FALLBACK; } } diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 866194eea0e..1c06d95a70b 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -1311,7 +1311,7 @@ void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to) memcpy(subGridData[i], gridData[i], key.elem_size * gridSize * gridSize); } - /*numGrids = ccgdm->dm->getNumGrids((DerivedMesh*)ccgdm);*/ /*UNUSED*/ + /* numGrids = ccgdm->dm->getNumGrids((DerivedMesh *)ccgdm); */ /*UNUSED*/ gridSize = ccgdm->getGridSize((DerivedMesh *)ccgdm); gridData = ccgdm->getGridData((DerivedMesh *)ccgdm); gridOffset = ccgdm->getGridOffset((DerivedMesh *)ccgdm); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 56b1c0a17e8..ed33a52e29a 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -91,8 +91,8 @@ bNodeTreeType *ntreeGetType(int type) static bNodeType *node_get_type(bNodeTree *ntree, int type) { bNodeType *ntype = ntreeGetType(ntree->type)->node_types.first; - for (; ntype; ntype= ntype->next) - if (ntype->type==type) + for (; ntype; ntype = ntype->next) + if (ntype->type == type) return ntype; return NULL; @@ -105,12 +105,12 @@ bNodeType *ntreeGetNodeType(bNodeTree *ntree) bNodeSocketType *ntreeGetSocketType(int type) { - static bNodeSocketType *types[NUM_SOCKET_TYPES]= {NULL}; + static bNodeSocketType *types[NUM_SOCKET_TYPES] = {NULL}; static int types_init = 1; if (types_init) { node_socket_type_init(types); - types_init= 0; + types_init = 0; } if (type < NUM_SOCKET_TYPES) { @@ -125,8 +125,8 @@ void ntreeInitTypes(bNodeTree *ntree) { bNode *node, *next; - for (node= ntree->nodes.first; node; node= next) { - next= node->next; + for (node = ntree->nodes.first; node; node = next) { + next = node->next; node->typeinfo = node_get_type(ntree, node->type); @@ -143,11 +143,11 @@ static bNodeSocket *make_socket(bNodeTree *UNUSED(ntree), int in_out, const char { bNodeSocket *sock; - sock= MEM_callocN(sizeof(bNodeSocket), "sock"); + sock = MEM_callocN(sizeof(bNodeSocket), "sock"); BLI_strncpy(sock->name, name, NODE_MAXSTR); - sock->limit = (in_out==SOCK_IN ? 1 : 0xFFF); - sock->type= type; + sock->limit = (in_out == SOCK_IN ? 1 : 0xFFF); + sock->type = type; sock->storage = NULL; sock->default_value = node_socket_make_default_value(type); @@ -159,9 +159,9 @@ static bNodeSocket *make_socket(bNodeTree *UNUSED(ntree), int in_out, const char bNodeSocket *nodeAddSocket(bNodeTree *ntree, bNode *node, int in_out, const char *name, int type) { bNodeSocket *sock = make_socket(ntree, in_out, name, type); - if (in_out==SOCK_IN) + if (in_out == SOCK_IN) BLI_addtail(&node->inputs, sock); - else if (in_out==SOCK_OUT) + else if (in_out == SOCK_OUT) BLI_addtail(&node->outputs, sock); node->update |= NODE_UPDATE; @@ -172,9 +172,9 @@ bNodeSocket *nodeAddSocket(bNodeTree *ntree, bNode *node, int in_out, const char bNodeSocket *nodeInsertSocket(bNodeTree *ntree, bNode *node, int in_out, bNodeSocket *next_sock, const char *name, int type) { bNodeSocket *sock = make_socket(ntree, in_out, name, type); - if (in_out==SOCK_IN) + if (in_out == SOCK_IN) BLI_insertlinkbefore(&node->inputs, next_sock, sock); - else if (in_out==SOCK_OUT) + else if (in_out == SOCK_OUT) BLI_insertlinkbefore(&node->outputs, next_sock, sock); node->update |= NODE_UPDATE; @@ -186,9 +186,9 @@ void nodeRemoveSocket(bNodeTree *ntree, bNode *node, bNodeSocket *sock) { bNodeLink *link, *next; - for (link= ntree->links.first; link; link= next) { - next= link->next; - if (link->fromsock==sock || link->tosock==sock) { + for (link = ntree->links.first; link; link = next) { + next = link->next; + if (link->fromsock == sock || link->tosock == sock) { nodeRemLink(ntree, link); } } @@ -208,17 +208,17 @@ void nodeRemoveAllSockets(bNodeTree *ntree, bNode *node) bNodeSocket *sock; bNodeLink *link, *next; - for (link= ntree->links.first; link; link= next) { - next= link->next; - if (link->fromnode==node || link->tonode==node) { + for (link = ntree->links.first; link; link = next) { + next = link->next; + if (link->fromnode == node || link->tonode == node) { nodeRemLink(ntree, link); } } - for (sock=node->inputs.first; sock; sock=sock->next) + for (sock = node->inputs.first; sock; sock = sock->next) node_socket_free_default_value(sock->type, sock->default_value); BLI_freelistN(&node->inputs); - for (sock=node->outputs.first; sock; sock=sock->next) + for (sock = node->outputs.first; sock; sock = sock->next) node_socket_free_default_value(sock->type, sock->default_value); BLI_freelistN(&node->outputs); @@ -236,20 +236,20 @@ int nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockin { bNode *node; bNodeSocket *tsock; - int index= 0; + int index = 0; - for (node= ntree->nodes.first; node; node= node->next) { - for (index=0, tsock= node->inputs.first; tsock; tsock= tsock->next, index++) { - if (tsock==sock) { - if (in_out) *in_out= SOCK_IN; + for (node = ntree->nodes.first; node; node = node->next) { + for (index = 0, tsock = node->inputs.first; tsock; tsock = tsock->next, index++) { + if (tsock == sock) { + if (in_out) *in_out = SOCK_IN; break; } } if (tsock) break; - for (index=0, tsock= node->outputs.first; tsock; tsock= tsock->next, index++) { - if (tsock==sock) { - if (in_out) *in_out= SOCK_OUT; + for (index = 0, tsock = node->outputs.first; tsock; tsock = tsock->next, index++) { + if (tsock == sock) { + if (in_out) *in_out = SOCK_OUT; break; } } @@ -258,12 +258,12 @@ int nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockin } if (node) { - *nodep= node; - if (sockindex) *sockindex= index; + *nodep = node; + if (sockindex) *sockindex = index; return 1; } - *nodep= NULL; + *nodep = NULL; return 0; } @@ -274,7 +274,7 @@ static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType /* bNodeSocket *sock; */ /* UNUSED */ if (ntype->inputs) { - sockdef= ntype->inputs; + sockdef = ntype->inputs; while (sockdef->type != -1) { /* sock = */ node_add_input_from_template(ntree, node, sockdef); @@ -282,7 +282,7 @@ static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType } } if (ntype->outputs) { - sockdef= ntype->outputs; + sockdef = ntype->outputs; while (sockdef->type != -1) { /* sock = */ node_add_output_from_template(ntree, node, sockdef); @@ -302,7 +302,7 @@ bNode *nodeAddNode(bNodeTree *ntree, struct bNodeTemplate *ntemp) bNode *node; bNodeType *ntype; - ntype= node_get_type(ntree, ntemp->type); + ntype = node_get_type(ntree, ntemp->type); if (ntype == NULL) { printf("nodeAddNodeType() error: '%d' type invalid\n", ntemp->type); return NULL; @@ -311,20 +311,20 @@ bNode *nodeAddNode(bNodeTree *ntree, struct bNodeTemplate *ntemp) if (!nodeValid(ntree, ntemp)) return NULL; - node= MEM_callocN(sizeof(bNode), "new node"); - node->type= ntype->type; - node->typeinfo= ntype; - node->flag= NODE_SELECT|ntype->flag; - node->width= ntype->width; - node->miniwidth= 42.0f; - node->height= ntype->height; - node->color[0] = node->color[1] = node->color[2] = 0.608; /* default theme color */ + node = MEM_callocN(sizeof(bNode), "new node"); + node->type = ntype->type; + node->typeinfo = ntype; + node->flag = NODE_SELECT | ntype->flag; + node->width = ntype->width; + node->miniwidth = 42.0f; + node->height = ntype->height; + node->color[0] = node->color[1] = node->color[2] = 0.608; /* default theme color */ node_add_sockets_from_type(ntree, node, ntype); BLI_addtail(&ntree->nodes, node); - if (ntype->initfunc!=NULL) + if (ntype->initfunc != NULL) ntype->initfunc(ntree, node, ntemp); /* initialize the node name with the node label. @@ -343,19 +343,22 @@ bNode *nodeAddNode(bNodeTree *ntree, struct bNodeTemplate *ntemp) /* ntree is the target tree */ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) { - bNode *nnode= MEM_callocN(sizeof(bNode), "dupli node"); + bNode *nnode = MEM_callocN(sizeof(bNode), "dupli node"); bNodeSocket *sock, *oldsock; - *nnode= *node; - nodeUniqueName(ntree, nnode); - - BLI_addtail(&ntree->nodes, nnode); + *nnode = *node; + /* can be called for nodes outside a node tree (e.g. clipboard) */ + if (ntree) { + nodeUniqueName(ntree, nnode); + + BLI_addtail(&ntree->nodes, nnode); + } BLI_duplicatelist(&nnode->inputs, &node->inputs); - oldsock= node->inputs.first; - for (sock= nnode->inputs.first; sock; sock= sock->next, oldsock= oldsock->next) { - oldsock->new_sock= sock; - sock->stack_index= 0; + oldsock = node->inputs.first; + for (sock = nnode->inputs.first; sock; sock = sock->next, oldsock = oldsock->next) { + oldsock->new_sock = sock; + sock->stack_index = 0; sock->default_value = node_socket_make_default_value(oldsock->type); node_socket_copy_default_value(oldsock->type, sock->default_value, oldsock->default_value); @@ -367,10 +370,10 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) } BLI_duplicatelist(&nnode->outputs, &node->outputs); - oldsock= node->outputs.first; - for (sock= nnode->outputs.first; sock; sock= sock->next, oldsock= oldsock->next) { - oldsock->new_sock= sock; - sock->stack_index= 0; + oldsock = node->outputs.first; + for (sock = nnode->outputs.first; sock; sock = sock->next, oldsock = oldsock->next) { + oldsock->new_sock = sock; + sock->stack_index = 0; sock->default_value = node_socket_make_default_value(oldsock->type); node_socket_copy_default_value(oldsock->type, sock->default_value, oldsock->default_value); @@ -386,11 +389,12 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) if (node->typeinfo->copystoragefunc) node->typeinfo->copystoragefunc(node, nnode); - node->new_node= nnode; - nnode->new_node= NULL; - nnode->preview= NULL; + node->new_node = nnode; + nnode->new_node = NULL; + nnode->preview = NULL; - ntree->update |= NTREE_UPDATE_NODES; + if (ntree) + ntree->update |= NTREE_UPDATE_NODES; return nnode; } @@ -399,108 +403,115 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock) { bNodeSocket *sock; - bNodeLink *link= NULL; - int from= 0, to= 0; + bNodeLink *link = NULL; + int from = 0, to = 0; if (fromnode) { /* test valid input */ - for (sock= fromnode->outputs.first; sock; sock= sock->next) - if (sock==fromsock) + for (sock = fromnode->outputs.first; sock; sock = sock->next) + if (sock == fromsock) break; if (sock) - from= 1; /* OK */ + from = 1; /* OK */ else { - for (sock= fromnode->inputs.first; sock; sock= sock->next) - if (sock==fromsock) + for (sock = fromnode->inputs.first; sock; sock = sock->next) + if (sock == fromsock) break; if (sock) - from= -1; /* OK but flip */ + from = -1; /* OK but flip */ } } - else { + else if (ntree) { /* check tree sockets */ - for (sock= ntree->inputs.first; sock; sock= sock->next) - if (sock==fromsock) + for (sock = ntree->inputs.first; sock; sock = sock->next) + if (sock == fromsock) break; if (sock) - from= 1; /* OK */ + from = 1; /* OK */ else { - for (sock= ntree->outputs.first; sock; sock= sock->next) - if (sock==fromsock) + for (sock = ntree->outputs.first; sock; sock = sock->next) + if (sock == fromsock) break; if (sock) - from= -1; /* OK but flip */ + from = -1; /* OK but flip */ } } if (tonode) { - for (sock= tonode->inputs.first; sock; sock= sock->next) - if (sock==tosock) + for (sock = tonode->inputs.first; sock; sock = sock->next) + if (sock == tosock) break; if (sock) - to= 1; /* OK */ + to = 1; /* OK */ else { - for (sock= tonode->outputs.first; sock; sock= sock->next) - if (sock==tosock) + for (sock = tonode->outputs.first; sock; sock = sock->next) + if (sock == tosock) break; if (sock) - to= -1; /* OK but flip */ + to = -1; /* OK but flip */ } } - else { + else if (ntree) { /* check tree sockets */ - for (sock= ntree->outputs.first; sock; sock= sock->next) - if (sock==tosock) + for (sock = ntree->outputs.first; sock; sock = sock->next) + if (sock == tosock) break; if (sock) - to= 1; /* OK */ + to = 1; /* OK */ else { - for (sock= ntree->inputs.first; sock; sock= sock->next) - if (sock==tosock) + for (sock = ntree->inputs.first; sock; sock = sock->next) + if (sock == tosock) break; if (sock) - to= -1; /* OK but flip */ + to = -1; /* OK but flip */ } } if (from >= 0 && to >= 0) { - link= MEM_callocN(sizeof(bNodeLink), "link"); - BLI_addtail(&ntree->links, link); - link->fromnode= fromnode; - link->fromsock= fromsock; - link->tonode= tonode; - link->tosock= tosock; + link = MEM_callocN(sizeof(bNodeLink), "link"); + if (ntree) + BLI_addtail(&ntree->links, link); + link->fromnode = fromnode; + link->fromsock = fromsock; + link->tonode = tonode; + link->tosock = tosock; } else if (from <= 0 && to <= 0) { - link= MEM_callocN(sizeof(bNodeLink), "link"); - BLI_addtail(&ntree->links, link); - link->fromnode= tonode; - link->fromsock= tosock; - link->tonode= fromnode; - link->tosock= fromsock; + link = MEM_callocN(sizeof(bNodeLink), "link"); + if (ntree) + BLI_addtail(&ntree->links, link); + link->fromnode = tonode; + link->fromsock = tosock; + link->tonode = fromnode; + link->tosock = fromsock; } - ntree->update |= NTREE_UPDATE_LINKS; + if (ntree) + ntree->update |= NTREE_UPDATE_LINKS; return link; } void nodeRemLink(bNodeTree *ntree, bNodeLink *link) { - BLI_remlink(&ntree->links, link); + /* can be called for links outside a node tree (e.g. clipboard) */ + if (ntree) + BLI_remlink(&ntree->links, link); + if (link->tosock) - link->tosock->link= NULL; + link->tosock->link = NULL; MEM_freeN(link); - ntree->update |= NTREE_UPDATE_LINKS; + if (ntree) + ntree->update |= NTREE_UPDATE_LINKS; } void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock) { bNodeLink *link, *next; - for (link= ntree->links.first; link; link= next) { - next= link->next; - if (link->fromsock==sock || link->tosock==sock) { + for (link = ntree->links.first; link; link = next) { + next = link->next; + if (link->fromsock == sock || link->tosock == sock) { nodeRemLink(ntree, link); } } @@ -519,15 +530,15 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node) intlinks = node->typeinfo->internal_connect(ntree, node); /* store link pointers in output sockets, for efficient lookup */ - for (link=intlinks.first; link; link=link->next) + for (link = intlinks.first; link; link = link->next) link->tosock->link = link; /* redirect downstream links */ - for (link=ntree->links.first; link; link=link_next) { + for (link = ntree->links.first; link; link = link_next) { link_next = link->next; /* do we have internal link? */ - if (link->fromnode==node) { + if (link->fromnode == node) { if (link->fromsock->link) { /* get the upstream input link */ bNodeLink *fromlink = link->fromsock->link->fromsock->link; @@ -547,10 +558,10 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node) } /* remove remaining upstream links */ - for (link=ntree->links.first; link; link=link_next) { + for (link = ntree->links.first; link; link = link_next) { link_next = link->next; - if (link->tonode==node) + if (link->tonode == node) nodeRemLink(ntree, link); } @@ -581,9 +592,25 @@ void nodeFromView(bNode *node, float x, float y, float *rx, float *ry) } } +int nodeAttachNodeCheck(bNode *node, bNode *parent) +{ + bNode *parent_recurse; + for (parent_recurse = node; parent_recurse; parent_recurse = parent_recurse->parent) { + if (parent_recurse == parent) { + return TRUE; + } + } + + return FALSE; +} + void nodeAttachNode(bNode *node, bNode *parent) { float locx, locy; + + BLI_assert(parent->type == NODE_FRAME); + BLI_assert(nodeAttachNodeCheck(parent, node) == FALSE); + nodeToView(node, 0.0f, 0.0f, &locx, &locy); node->parent = parent; @@ -596,6 +623,9 @@ void nodeDetachNode(struct bNode *node) float locx, locy; if (node->parent) { + + BLI_assert(node->parent->type == NODE_FRAME); + /* transform to view space */ nodeToView(node, 0.0f, 0.0f, &locx, &locy); node->locx = locx; @@ -612,15 +642,15 @@ bNodeTree *ntreeAddTree(const char *name, int type, int nodetype) /* trees are created as local trees if they of compositor, material or texture type, * node groups and other tree types are created as library data. */ - if (ELEM3(type, NTREE_COMPOSIT, NTREE_SHADER, NTREE_TEXTURE) && nodetype==0) { - ntree= MEM_callocN(sizeof(bNodeTree), "new node tree"); - *( (short *)ntree->id.name )= ID_NT; /* not "type", as that is ntree->type */ - BLI_strncpy(ntree->id.name+2, name, sizeof(ntree->id.name)); + if (ELEM3(type, NTREE_COMPOSIT, NTREE_SHADER, NTREE_TEXTURE) && nodetype == 0) { + ntree = MEM_callocN(sizeof(bNodeTree), "new node tree"); + *( (short *)ntree->id.name) = ID_NT; /* not "type", as that is ntree->type */ + BLI_strncpy(ntree->id.name + 2, name, sizeof(ntree->id.name)); } else - ntree= BKE_libblock_alloc(&G.main->nodetree, ID_NT, name); + ntree = BKE_libblock_alloc(&G.main->nodetree, ID_NT, name); - ntree->type= type; + ntree->type = type; ntree->nodetype = nodetype; ntreeInitTypes(ntree); @@ -648,53 +678,53 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_make_e bNodeLink *link; bNodeSocket *gsock, *oldgsock; - if (ntree==NULL) return NULL; + if (ntree == NULL) return NULL; /* is ntree part of library? */ - for (newtree=G.main->nodetree.first; newtree; newtree= newtree->id.next) - if (newtree==ntree) break; + for (newtree = G.main->nodetree.first; newtree; newtree = newtree->id.next) + if (newtree == ntree) break; if (newtree) { - newtree= BKE_libblock_copy(&ntree->id); + newtree = BKE_libblock_copy(&ntree->id); } else { - newtree= MEM_dupallocN(ntree); + newtree = MEM_dupallocN(ntree); BKE_libblock_copy_data(&newtree->id, &ntree->id, TRUE); /* copy animdata and ID props */ } id_us_plus((ID *)newtree->gpd); /* in case a running nodetree is copied */ - newtree->execdata= NULL; + newtree->execdata = NULL; - newtree->nodes.first= newtree->nodes.last= NULL; - newtree->links.first= newtree->links.last= NULL; + newtree->nodes.first = newtree->nodes.last = NULL; + newtree->links.first = newtree->links.last = NULL; last = ntree->nodes.last; - for (node= ntree->nodes.first; node; node= node->next) { + for (node = ntree->nodes.first; node; node = node->next) { if (do_make_extern) { id_lib_extern(node->id); } - node->new_node= NULL; - /* nnode= */ nodeCopyNode(newtree, node); /* sets node->new */ + node->new_node = NULL; + /* nnode= */ nodeCopyNode(newtree, node); /* sets node->new */ /* make sure we don't copy new nodes again! */ - if (node==last) + if (node == last) break; } /* socket definition for group usage */ BLI_duplicatelist(&newtree->inputs, &ntree->inputs); - for (gsock= newtree->inputs.first, oldgsock= ntree->inputs.first; gsock; gsock=gsock->next, oldgsock=oldgsock->next) { - oldgsock->new_sock= gsock; + for (gsock = newtree->inputs.first, oldgsock = ntree->inputs.first; gsock; gsock = gsock->next, oldgsock = oldgsock->next) { + oldgsock->new_sock = gsock; gsock->groupsock = (oldgsock->groupsock ? oldgsock->groupsock->new_sock : NULL); gsock->default_value = node_socket_make_default_value(oldgsock->type); node_socket_copy_default_value(oldgsock->type, gsock->default_value, oldgsock->default_value); } BLI_duplicatelist(&newtree->outputs, &ntree->outputs); - for (gsock= newtree->outputs.first, oldgsock= ntree->outputs.first; gsock; gsock=gsock->next, oldgsock=oldgsock->next) { - oldgsock->new_sock= gsock; + for (gsock = newtree->outputs.first, oldgsock = ntree->outputs.first; gsock; gsock = gsock->next, oldgsock = oldgsock->next) { + oldgsock->new_sock = gsock; gsock->groupsock = (oldgsock->groupsock ? oldgsock->groupsock->new_sock : NULL); gsock->default_value = node_socket_make_default_value(oldgsock->type); node_socket_copy_default_value(oldgsock->type, gsock->default_value, oldgsock->default_value); @@ -702,7 +732,7 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_make_e /* copy links */ BLI_duplicatelist(&newtree->links, &ntree->links); - for (link= newtree->links.first; link; link= link->next) { + for (link = newtree->links.first; link; link = link->next) { link->fromnode = (link->fromnode ? link->fromnode->new_node : NULL); link->fromsock = (link->fromsock ? link->fromsock->new_sock : NULL); link->tonode = (link->tonode ? link->tonode->new_node : NULL); @@ -713,7 +743,7 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_make_e } /* update node->parent pointers */ - for (node=newtree->nodes.first; node; node=node->next) { + for (node = newtree->nodes.first; node; node = node->next) { if (node->parent) node->parent = node->parent->new_node; } @@ -731,9 +761,9 @@ void ntreeSwitchID(bNodeTree *ntree, ID *id_from, ID *id_to) { bNode *node; /* for scene duplication only */ - for (node= ntree->nodes.first; node; node= node->next) { - if (node->id==id_from) { - node->id= id_to; + for (node = ntree->nodes.first; node; node = node->next) { + if (node->id == id_from) { + node->id = id_to; } } } @@ -747,34 +777,34 @@ void nodeFreePreview(bNode *node) if (node->preview->rect) MEM_freeN(node->preview->rect); MEM_freeN(node->preview); - node->preview= NULL; + node->preview = NULL; } } static void node_init_preview(bNode *node, int xsize, int ysize) { - if (node->preview==NULL) { - node->preview= MEM_callocN(sizeof(bNodePreview), "node preview"); + if (node->preview == NULL) { + node->preview = MEM_callocN(sizeof(bNodePreview), "node preview"); // printf("added preview %s\n", node->name); } /* node previews can get added with variable size this way */ - if (xsize==0 || ysize==0) + if (xsize == 0 || ysize == 0) return; /* sanity checks & initialize */ if (node->preview->rect) { - if (node->preview->xsize!=xsize && node->preview->ysize!=ysize) { + if (node->preview->xsize != xsize && node->preview->ysize != ysize) { MEM_freeN(node->preview->rect); - node->preview->rect= NULL; + node->preview->rect = NULL; } } - if (node->preview->rect==NULL) { - node->preview->rect= MEM_callocN(4*xsize + xsize*ysize*sizeof(char)*4, "node preview rect"); - node->preview->xsize= xsize; - node->preview->ysize= ysize; + if (node->preview->rect == NULL) { + node->preview->rect = MEM_callocN(4 * xsize + xsize * ysize * sizeof(char) * 4, "node preview rect"); + node->preview->xsize = xsize; + node->preview->ysize = ysize; } /* no clear, makes nicer previews */ } @@ -783,13 +813,13 @@ void ntreeInitPreview(bNodeTree *ntree, int xsize, int ysize) { bNode *node; - if (ntree==NULL) + if (ntree == NULL) return; - for (node= ntree->nodes.first; node; node= node->next) { - if (node->typeinfo->flag & NODE_PREVIEW) /* hrms, check for closed nodes? */ + for (node = ntree->nodes.first; node; node = node->next) { + if (node->typeinfo->flag & NODE_PREVIEW) /* hrms, check for closed nodes? */ node_init_preview(node, xsize, ysize); - if (node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT)) + if (node->type == NODE_GROUP && (node->flag & NODE_GROUP_EDIT)) ntreeInitPreview((bNodeTree *)node->id, xsize, ysize); } } @@ -805,13 +835,13 @@ void ntreeClearPreview(bNodeTree *ntree) { bNode *node; - if (ntree==NULL) + if (ntree == NULL) return; - for (node= ntree->nodes.first; node; node= node->next) { + for (node = ntree->nodes.first; node; node = node->next) { if (node->typeinfo->flag & NODE_PREVIEW) nodeClearPreview(node); - if (node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT)) + if (node->type == NODE_GROUP && (node->flag & NODE_GROUP_EDIT)) ntreeClearPreview((bNodeTree *)node->id); } } @@ -821,11 +851,11 @@ void ntreeClearPreview(bNodeTree *ntree) * add the color once. Preview gets cleared before it starts render though */ void nodeAddToPreview(bNode *node, float col[4], int x, int y, int do_manage) { - bNodePreview *preview= node->preview; + bNodePreview *preview = node->preview; if (preview) { - if (x>=0 && y>=0) { - if (x<preview->xsize && y<preview->ysize) { - unsigned char *tar= preview->rect+ 4*((preview->xsize*y) + x); + if (x >= 0 && y >= 0) { + if (x < preview->xsize && y < preview->ysize) { + unsigned char *tar = preview->rect + 4 * ((preview->xsize * y) + x); if (do_manage) { linearrgb_to_srgb_uchar4(tar, col); @@ -849,22 +879,22 @@ void nodeUnlinkNode(bNodeTree *ntree, bNode *node) bNodeSocket *sock; ListBase *lb; - for (link= ntree->links.first; link; link= next) { - next= link->next; + for (link = ntree->links.first; link; link = next) { + next = link->next; - if (link->fromnode==node) { - lb= &node->outputs; + if (link->fromnode == node) { + lb = &node->outputs; if (link->tonode) link->tonode->update |= NODE_UPDATE; } - else if (link->tonode==node) - lb= &node->inputs; + else if (link->tonode == node) + lb = &node->inputs; else - lb= NULL; + lb = NULL; if (lb) { - for (sock= lb->first; sock; sock= sock->next) { - if (link->fromsock==sock || link->tosock==sock) + for (sock = lb->first; sock; sock = sock->next) { + if (link->fromsock == sock || link->tosock == sock) break; } if (sock) { @@ -877,7 +907,7 @@ void nodeUnlinkNode(bNodeTree *ntree, bNode *node) static void node_unlink_attached(bNodeTree *ntree, bNode *parent) { bNode *node; - for (node=ntree->nodes.first; node; node=node->next) { + for (node = ntree->nodes.first; node; node = node->next) { if (node->parent == parent) nodeDetachNode(node); } @@ -885,29 +915,33 @@ static void node_unlink_attached(bNodeTree *ntree, bNode *parent) void nodeFreeNode(bNodeTree *ntree, bNode *node) { - bNodeTreeType *treetype= ntreeGetType(ntree->type); bNodeSocket *sock, *nextsock; - /* remove all references to this node */ - nodeUnlinkNode(ntree, node); - node_unlink_attached(ntree, node); - - BLI_remlink(&ntree->nodes, node); + /* can be called for nodes outside a node tree (e.g. clipboard) */ + if (ntree) { + bNodeTreeType *treetype = ntreeGetType(ntree->type); + + /* remove all references to this node */ + nodeUnlinkNode(ntree, node); + node_unlink_attached(ntree, node); + + BLI_remlink(&ntree->nodes, node); + + if (treetype->free_node_cache) + treetype->free_node_cache(ntree, node); + } /* since it is called while free database, node->id is undefined */ - if (treetype->free_node_cache) - treetype->free_node_cache(ntree, node); - if (node->typeinfo && node->typeinfo->freestoragefunc) node->typeinfo->freestoragefunc(node); - for (sock=node->inputs.first; sock; sock = nextsock) { + for (sock = node->inputs.first; sock; sock = nextsock) { nextsock = sock->next; node_socket_free_default_value(sock->type, sock->default_value); MEM_freeN(sock); } - for (sock=node->outputs.first; sock; sock = nextsock) { + for (sock = node->outputs.first; sock; sock = nextsock) { nextsock = sock->next; node_socket_free_default_value(sock->type, sock->default_value); MEM_freeN(sock); @@ -917,7 +951,8 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node) MEM_freeN(node); - ntree->update |= NTREE_UPDATE_NODES; + if (ntree) + ntree->update |= NTREE_UPDATE_NODES; } /* do not free ntree itself here, BKE_libblock_free calls this function too */ @@ -926,7 +961,7 @@ void ntreeFreeTree(bNodeTree *ntree) bNode *node, *next; bNodeSocket *sock; - if (ntree==NULL) return; + if (ntree == NULL) return; /* XXX hack! node trees should not store execution graphs at all. * This should be removed when old tree types no longer require it. @@ -935,15 +970,15 @@ void ntreeFreeTree(bNodeTree *ntree) */ if (ntree->execdata) { switch (ntree->type) { - case NTREE_COMPOSIT: - ntreeCompositEndExecTree(ntree->execdata, 1); - break; - case NTREE_SHADER: - ntreeShaderEndExecTree(ntree->execdata, 1); - break; - case NTREE_TEXTURE: - ntreeTexEndExecTree(ntree->execdata, 1); - break; + case NTREE_COMPOSIT: + ntreeCompositEndExecTree(ntree->execdata, 1); + break; + case NTREE_SHADER: + ntreeShaderEndExecTree(ntree->execdata, 1); + break; + case NTREE_TEXTURE: + ntreeTexEndExecTree(ntree->execdata, 1); + break; } } @@ -951,17 +986,17 @@ void ntreeFreeTree(bNodeTree *ntree) id_us_min((ID *)ntree->gpd); - BLI_freelistN(&ntree->links); /* do first, then unlink_node goes fast */ + BLI_freelistN(&ntree->links); /* do first, then unlink_node goes fast */ - for (node= ntree->nodes.first; node; node= next) { - next= node->next; + for (node = ntree->nodes.first; node; node = next) { + next = node->next; nodeFreeNode(ntree, node); } - for (sock=ntree->inputs.first; sock; sock=sock->next) + for (sock = ntree->inputs.first; sock; sock = sock->next) node_socket_free_default_value(sock->type, sock->default_value); BLI_freelistN(&ntree->inputs); - for (sock=ntree->outputs.first; sock; sock=sock->next) + for (sock = ntree->outputs.first; sock; sock = sock->next) node_socket_free_default_value(sock->type, sock->default_value); BLI_freelistN(&ntree->outputs); } @@ -970,9 +1005,9 @@ void ntreeFreeCache(bNodeTree *ntree) { bNodeTreeType *treetype; - if (ntree==NULL) return; + if (ntree == NULL) return; - treetype= ntreeGetType(ntree->type); + treetype = ntreeGetType(ntree->type); if (treetype->free_cache) treetype->free_cache(ntree); } @@ -982,45 +1017,46 @@ void ntreeSetOutput(bNodeTree *ntree) bNode *node; /* find the active outputs, might become tree type dependent handler */ - for (node= ntree->nodes.first; node; node= node->next) { - if (node->typeinfo->nclass==NODE_CLASS_OUTPUT) { + for (node = ntree->nodes.first; node; node = node->next) { + if (node->typeinfo->nclass == NODE_CLASS_OUTPUT) { bNode *tnode; - int output= 0; + int output = 0; /* we need a check for which output node should be tagged like this, below an exception */ - if (node->type==CMP_NODE_OUTPUT_FILE) + if (node->type == CMP_NODE_OUTPUT_FILE) continue; /* there is more types having output class, each one is checked */ - for (tnode= ntree->nodes.first; tnode; tnode= tnode->next) { - if (tnode->typeinfo->nclass==NODE_CLASS_OUTPUT) { + for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) { + if (tnode->typeinfo->nclass == NODE_CLASS_OUTPUT) { - if (ntree->type==NTREE_COMPOSIT) { + if (ntree->type == NTREE_COMPOSIT) { /* same type, exception for viewer */ - if (tnode->type==node->type || - (ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) && - ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))) { + if (tnode->type == node->type || + (ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) && + ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))) + { if (tnode->flag & NODE_DO_OUTPUT) { output++; - if (output>1) + if (output > 1) tnode->flag &= ~NODE_DO_OUTPUT; } } } else { /* same type */ - if (tnode->type==node->type) { + if (tnode->type == node->type) { if (tnode->flag & NODE_DO_OUTPUT) { output++; - if (output>1) + if (output > 1) tnode->flag &= ~NODE_DO_OUTPUT; } } } } } - if (output==0) + if (output == 0) node->flag |= NODE_DO_OUTPUT; } } @@ -1037,28 +1073,32 @@ typedef struct MakeLocalCallData { static void ntreeMakeLocal_CheckLocal(void *calldata, ID *owner_id, bNodeTree *ntree) { - MakeLocalCallData *cd= (MakeLocalCallData*)calldata; + MakeLocalCallData *cd = (MakeLocalCallData *)calldata; bNode *node; /* find if group is in tree */ - for (node= ntree->nodes.first; node; node= node->next) { + for (node = ntree->nodes.first; node; node = node->next) { if (node->id == cd->group_id) { - if (owner_id->lib) cd->lib= 1; - else cd->local= 1; + if (owner_id->lib) { + cd->lib = TRUE; + } + else { + cd->local = TRUE; + } } } } static void ntreeMakeLocal_LinkNew(void *calldata, ID *owner_id, bNodeTree *ntree) { - MakeLocalCallData *cd= (MakeLocalCallData*)calldata; + MakeLocalCallData *cd = (MakeLocalCallData *)calldata; bNode *node; /* find if group is in tree */ - for (node= ntree->nodes.first; node; node= node->next) { + for (node = ntree->nodes.first; node; node = node->next) { if (node->id == cd->group_id) { - if (owner_id->lib==NULL) { - node->id= cd->new_id; + if (owner_id->lib == NULL) { + node->id = cd->new_id; cd->new_id->us++; cd->group_id->us--; } @@ -1068,8 +1108,8 @@ static void ntreeMakeLocal_LinkNew(void *calldata, ID *owner_id, bNodeTree *ntre void ntreeMakeLocal(bNodeTree *ntree) { - Main *bmain= G.main; - bNodeTreeType *treetype= ntreeGetType(ntree->type); + Main *bmain = G.main; + bNodeTreeType *treetype = ntreeGetType(ntree->type); MakeLocalCallData cd; /* - only lib users: do nothing @@ -1077,8 +1117,8 @@ void ntreeMakeLocal(bNodeTree *ntree) * - mixed: make copy */ - if (ntree->id.lib==NULL) return; - if (ntree->id.us==1) { + if (ntree->id.lib == NULL) return; + if (ntree->id.us == 1) { id_clear_lib_data(bmain, (ID *)ntree); return; } @@ -1092,14 +1132,14 @@ void ntreeMakeLocal(bNodeTree *ntree) treetype->foreach_nodetree(G.main, &cd, &ntreeMakeLocal_CheckLocal); /* if all users are local, we simply make tree local */ - if (cd.local && cd.lib==0) { + if (cd.local && cd.lib == 0) { id_clear_lib_data(bmain, (ID *)ntree); } else if (cd.local && cd.lib) { /* this is the mixed case, we copy the tree and assign it to local users */ - bNodeTree *newtree= ntreeCopyTree(ntree); + bNodeTree *newtree = ntreeCopyTree(ntree); - newtree->id.us= 0; + newtree->id.us = 0; cd.new_id = &newtree->id; @@ -1109,18 +1149,18 @@ void ntreeMakeLocal(bNodeTree *ntree) int ntreeNodeExists(bNodeTree *ntree, bNode *testnode) { - bNode *node= ntree->nodes.first; - for (; node; node= node->next) - if (node==testnode) + bNode *node = ntree->nodes.first; + for (; node; node = node->next) + if (node == testnode) return 1; return 0; } int ntreeOutputExists(bNode *node, bNodeSocket *testsock) { - bNodeSocket *sock= node->outputs.first; - for (; sock; sock= sock->next) - if (sock==testsock) + bNodeSocket *sock = node->outputs.first; + for (; sock; sock = sock->next) + if (sock == testsock) return 1; return 0; } @@ -1128,33 +1168,33 @@ int ntreeOutputExists(bNode *node, bNodeSocket *testsock) /* returns localized tree for execution in threads */ bNodeTree *ntreeLocalize(bNodeTree *ntree) { - bNodeTreeType *ntreetype= ntreeGetType(ntree->type); + bNodeTreeType *ntreetype = ntreeGetType(ntree->type); bNodeTree *ltree; bNode *node; - bAction *action_backup= NULL, *tmpact_backup= NULL; + bAction *action_backup = NULL, *tmpact_backup = NULL; /* Workaround for copying an action on each render! * set action to NULL so animdata actions don't get copied */ - AnimData *adt= BKE_animdata_from_id(&ntree->id); + AnimData *adt = BKE_animdata_from_id(&ntree->id); if (adt) { - action_backup= adt->action; - tmpact_backup= adt->tmpact; + action_backup = adt->action; + tmpact_backup = adt->tmpact; - adt->action= NULL; - adt->tmpact= NULL; + adt->action = NULL; + adt->tmpact = NULL; } /* node copy func */ ltree = ntreeCopyTree_internal(ntree, FALSE); if (adt) { - AnimData *ladt= BKE_animdata_from_id(<ree->id); + AnimData *ladt = BKE_animdata_from_id(<ree->id); - adt->action= ladt->action= action_backup; - adt->tmpact= ladt->tmpact= tmpact_backup; + adt->action = ladt->action = action_backup; + adt->tmpact = ladt->tmpact = tmpact_backup; if (action_backup) action_backup->id.us++; if (tmpact_backup) tmpact_backup->id.us++; @@ -1165,9 +1205,9 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree) /* ensures only a single output node is enabled */ ntreeSetOutput(ntree); - for (node= ntree->nodes.first; node; node= node->next) { + for (node = ntree->nodes.first; node; node = node->next) { /* store new_node pointer to original */ - node->new_node->new_node= node; + node->new_node->new_node = node; } if (ntreetype->localize) @@ -1181,7 +1221,7 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree) /* is called by jobs manager, outside threads, so it doesnt happen during draw */ void ntreeLocalSync(bNodeTree *localtree, bNodeTree *ntree) { - bNodeTreeType *ntreetype= ntreeGetType(ntree->type); + bNodeTreeType *ntreetype = ntreeGetType(ntree->type); if (ntreetype->local_sync) ntreetype->local_sync(localtree, ntree); @@ -1191,16 +1231,16 @@ void ntreeLocalSync(bNodeTree *localtree, bNodeTree *ntree) /* we have to assume the editor already changed completely */ void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree) { - bNodeTreeType *ntreetype= ntreeGetType(ntree->type); + bNodeTreeType *ntreetype = ntreeGetType(ntree->type); bNode *lnode; /* move over the compbufs and previews */ - for (lnode= localtree->nodes.first; lnode; lnode= lnode->next) { + for (lnode = localtree->nodes.first; lnode; lnode = lnode->next) { if (ntreeNodeExists(ntree, lnode->new_node)) { if (lnode->preview && lnode->preview->rect) { nodeFreePreview(lnode->new_node); - lnode->new_node->preview= lnode->preview; - lnode->preview= NULL; + lnode->new_node->preview = lnode->preview; + lnode->preview = NULL; } } } @@ -1219,7 +1259,7 @@ int ntreeHasType(bNodeTree *ntree, int type) bNode *node; if (ntree) - for (node= ntree->nodes.first; node; node= node->next) + for (node = ntree->nodes.first; node; node = node->next) if (node->type == type) return 1; return 0; @@ -1229,10 +1269,10 @@ bNodeLink *nodeFindLink(bNodeTree *ntree, bNodeSocket *from, bNodeSocket *to) { bNodeLink *link; - for (link= ntree->links.first; link; link= link->next) { - if (link->fromsock==from && link->tosock==to) + for (link = ntree->links.first; link; link = link->next) { + if (link->fromsock == from && link->tosock == to) return link; - if (link->fromsock==to && link->tosock==from) /* hrms? */ + if (link->fromsock == to && link->tosock == from) /* hrms? */ return link; } return NULL; @@ -1241,10 +1281,10 @@ bNodeLink *nodeFindLink(bNodeTree *ntree, bNodeSocket *from, bNodeSocket *to) int nodeCountSocketLinks(bNodeTree *ntree, bNodeSocket *sock) { bNodeLink *link; - int tot= 0; + int tot = 0; - for (link= ntree->links.first; link; link= link->next) { - if (link->fromsock==sock || link->tosock==sock) + for (link = ntree->links.first; link; link = link->next) { + if (link->fromsock == sock || link->tosock == sock) tot++; } return tot; @@ -1254,9 +1294,9 @@ bNode *nodeGetActive(bNodeTree *ntree) { bNode *node; - if (ntree==NULL) return NULL; + if (ntree == NULL) return NULL; - for (node= ntree->nodes.first; node; node= node->next) + for (node = ntree->nodes.first; node; node = node->next) if (node->flag & NODE_ACTIVE) break; return node; @@ -1267,19 +1307,19 @@ bNode *nodeGetActiveID(bNodeTree *ntree, short idtype) { bNode *node; - if (ntree==NULL) return NULL; + if (ntree == NULL) return NULL; /* check for group edit */ - for (node= ntree->nodes.first; node; node= node->next) + for (node = ntree->nodes.first; node; node = node->next) if (node->flag & NODE_GROUP_EDIT) break; if (node) - ntree= (bNodeTree*)node->id; + ntree = (bNodeTree *)node->id; /* now find active node with this id */ - for (node= ntree->nodes.first; node; node= node->next) - if (node->id && GS(node->id->name)==idtype) + for (node = ntree->nodes.first; node; node = node->next) + if (node->id && GS(node->id->name) == idtype) if (node->flag & NODE_ACTIVE_ID) break; @@ -1289,24 +1329,24 @@ bNode *nodeGetActiveID(bNodeTree *ntree, short idtype) int nodeSetActiveID(bNodeTree *ntree, short idtype, ID *id) { bNode *node; - int ok= FALSE; + int ok = FALSE; - if (ntree==NULL) return ok; + if (ntree == NULL) return ok; /* check for group edit */ - for (node= ntree->nodes.first; node; node= node->next) + for (node = ntree->nodes.first; node; node = node->next) if (node->flag & NODE_GROUP_EDIT) break; if (node) - ntree= (bNodeTree*)node->id; + ntree = (bNodeTree *)node->id; /* now find active node with this id */ - for (node= ntree->nodes.first; node; node= node->next) { - if (node->id && GS(node->id->name)==idtype) { - if (id && ok==FALSE && node->id==id) { + for (node = ntree->nodes.first; node; node = node->next) { + if (node->id && GS(node->id->name) == idtype) { + if (id && ok == FALSE && node->id == id) { node->flag |= NODE_ACTIVE_ID; - ok= TRUE; + ok = TRUE; } else { node->flag &= ~NODE_ACTIVE_ID; @@ -1323,10 +1363,10 @@ void nodeClearActiveID(bNodeTree *ntree, short idtype) { bNode *node; - if (ntree==NULL) return; + if (ntree == NULL) return; - for (node= ntree->nodes.first; node; node= node->next) - if (node->id && GS(node->id->name)==idtype) + for (node = ntree->nodes.first; node; node = node->next) + if (node->id && GS(node->id->name) == idtype) node->flag &= ~NODE_ACTIVE_ID; } @@ -1334,9 +1374,9 @@ void nodeClearActive(bNodeTree *ntree) { bNode *node; - if (ntree==NULL) return; + if (ntree == NULL) return; - for (node= ntree->nodes.first; node; node= node->next) + for (node = ntree->nodes.first; node; node = node->next) node->flag &= ~(NODE_ACTIVE | NODE_ACTIVE_ID); } @@ -1347,7 +1387,7 @@ void nodeSetActive(bNodeTree *ntree, bNode *node) bNode *tnode; /* make sure only one node is active, and only one per ID type */ - for (tnode= ntree->nodes.first; tnode; tnode= tnode->next) { + for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) { tnode->flag &= ~NODE_ACTIVE; if (node->id && tnode->id) { @@ -1383,6 +1423,64 @@ void nodeSocketSetType(bNodeSocket *sock, int type) node_socket_free_default_value(old_type, old_default_value); } +/* ************** Node Clipboard *********** */ + +typedef struct bNodeClipboard { + ListBase nodes; + ListBase links; + int type; +} bNodeClipboard; + +bNodeClipboard node_clipboard; + +void BKE_node_clipboard_init(struct bNodeTree *ntree) +{ + node_clipboard.type = ntree->type; +} + +void BKE_node_clipboard_clear(void) +{ + bNode *node, *node_next; + bNodeLink *link, *link_next; + + for (link = node_clipboard.links.first; link; link=link_next) { + link_next = link->next; + nodeRemLink(NULL, link); + } + node_clipboard.links.first = node_clipboard.links.last = NULL; + + for (node = node_clipboard.nodes.first; node; node=node_next) { + node_next = node->next; + nodeFreeNode(NULL, node); + } + node_clipboard.nodes.first = node_clipboard.nodes.last = NULL; +} + +void BKE_node_clipboard_add_node(bNode *node) +{ + BLI_addtail(&node_clipboard.nodes, node); +} + +void BKE_node_clipboard_add_link(bNodeLink *link) +{ + BLI_addtail(&node_clipboard.links, link); +} + +const ListBase *BKE_node_clipboard_get_nodes(void) +{ + return &node_clipboard.nodes; +} + +const ListBase *BKE_node_clipboard_get_links(void) +{ + return &node_clipboard.links; +} + +int BKE_node_clipboard_get_type(void) +{ + return node_clipboard.type; +} + /* ************** dependency stuff *********** */ /* node is guaranteed to be not checked before */ @@ -1395,12 +1493,12 @@ static int node_get_deplist_recurs(bNode *node, bNode ***nsort) node->done = TRUE; /* check linked nodes */ - for (sock= node->inputs.first; sock; sock= sock->next) { + for (sock = node->inputs.first; sock; sock = sock->next) { if (sock->link) { - fromnode= sock->link->fromnode; + fromnode = sock->link->fromnode; if (fromnode) { - if (fromnode->done==0) - fromnode->level= node_get_deplist_recurs(fromnode, nsort); + if (fromnode->done == 0) + fromnode->level = node_get_deplist_recurs(fromnode, nsort); if (fromnode->level <= level) level = fromnode->level - 1; } @@ -1409,14 +1507,14 @@ static int node_get_deplist_recurs(bNode *node, bNode ***nsort) /* check parent node */ if (node->parent) { - if (node->parent->done==0) - node->parent->level= node_get_deplist_recurs(node->parent, nsort); + if (node->parent->done == 0) + node->parent->level = node_get_deplist_recurs(node->parent, nsort); if (node->parent->level <= level) level = node->parent->level - 1; } if (nsort) { - **nsort= node; + **nsort = node; (*nsort)++; } @@ -1427,24 +1525,24 @@ void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***deplist, in { bNode *node, **nsort; - *totnodes=0; + *totnodes = 0; /* first clear data */ - for (node= ntree->nodes.first; node; node= node->next) { + for (node = ntree->nodes.first; node; node = node->next) { node->done = FALSE; (*totnodes)++; } - if (*totnodes==0) { + if (*totnodes == 0) { *deplist = NULL; return; } - nsort= *deplist= MEM_callocN((*totnodes)*sizeof(bNode*), "sorted node array"); + nsort = *deplist = MEM_callocN((*totnodes) * sizeof(bNode *), "sorted node array"); /* recursive check */ - for (node= ntree->nodes.first; node; node= node->next) { - if (node->done==0) { - node->level= node_get_deplist_recurs(node, &nsort); + for (node = ntree->nodes.first; node; node = node->next) { + if (node->done == 0) { + node->level = node_get_deplist_recurs(node, &nsort); } } } @@ -1455,14 +1553,14 @@ static void ntree_update_node_level(bNodeTree *ntree) bNode *node; /* first clear tag */ - for (node= ntree->nodes.first; node; node= node->next) { + for (node = ntree->nodes.first; node; node = node->next) { node->done = FALSE; } /* recursive check */ - for (node= ntree->nodes.first; node; node= node->next) { - if (node->done==0) { - node->level= node_get_deplist_recurs(node, NULL); + for (node = ntree->nodes.first; node; node = node->next) { + if (node->done == 0) { + node->level = node_get_deplist_recurs(node, NULL); } } } @@ -1474,25 +1572,25 @@ static void ntree_update_link_pointers(bNodeTree *ntree) bNodeLink *link; /* first clear data */ - for (node= ntree->nodes.first; node; node= node->next) { - for (sock= node->inputs.first; sock; sock= sock->next) { - sock->link= NULL; + for (node = ntree->nodes.first; node; node = node->next) { + for (sock = node->inputs.first; sock; sock = sock->next) { + sock->link = NULL; sock->flag &= ~SOCK_IN_USE; } - for (sock= node->outputs.first; sock; sock= sock->next) { + for (sock = node->outputs.first; sock; sock = sock->next) { sock->flag &= ~SOCK_IN_USE; } } - for (sock= ntree->inputs.first; sock; sock= sock->next) { + for (sock = ntree->inputs.first; sock; sock = sock->next) { sock->flag &= ~SOCK_IN_USE; } - for (sock= ntree->outputs.first; sock; sock= sock->next) { - sock->link= NULL; + for (sock = ntree->outputs.first; sock; sock = sock->next) { + sock->link = NULL; sock->flag &= ~SOCK_IN_USE; } - for (link= ntree->links.first; link; link= link->next) { - link->tosock->link= link; + for (link = ntree->links.first; link; link = link->next) { + link->tosock->link = link; link->fromsock->flag |= SOCK_IN_USE; link->tosock->flag |= SOCK_IN_USE; @@ -1517,10 +1615,10 @@ static void ntree_validate_links(bNodeTree *ntree) static void ntree_verify_nodes_cb(void *calldata, struct ID *UNUSED(owner_id), struct bNodeTree *ntree) { - ID *id= (ID*)calldata; + ID *id = (ID *)calldata; bNode *node; - for (node=ntree->nodes.first; node; node=node->next) + for (node = ntree->nodes.first; node; node = node->next) if (node->typeinfo->verifyfunc) node->typeinfo->verifyfunc(ntree, node, id); } @@ -1531,21 +1629,21 @@ void ntreeVerifyNodes(struct Main *main, struct ID *id) bNodeTree *ntree; int n; - for (n=0; n < NUM_NTREE_TYPES; ++n) { - ntreetype= ntreeGetType(n); + for (n = 0; n < NUM_NTREE_TYPES; ++n) { + ntreetype = ntreeGetType(n); if (ntreetype && ntreetype->foreach_nodetree) ntreetype->foreach_nodetree(main, id, ntree_verify_nodes_cb); } - for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) + for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) ntree_verify_nodes_cb(id, NULL, ntree); } void ntreeUpdateTree(bNodeTree *ntree) { - bNodeTreeType *ntreetype= ntreeGetType(ntree->type); + bNodeTreeType *ntreetype = ntreeGetType(ntree->type); bNode *node; - if (ntree->update & (NTREE_UPDATE_LINKS|NTREE_UPDATE_NODES)) { + if (ntree->update & (NTREE_UPDATE_LINKS | NTREE_UPDATE_NODES)) { /* set the bNodeSocket->link pointers */ ntree_update_link_pointers(ntree); @@ -1554,7 +1652,7 @@ void ntreeUpdateTree(bNodeTree *ntree) } /* update individual nodes */ - for (node=ntree->nodes.first; node; node=node->next) { + for (node = ntree->nodes.first; node; node = node->next) { /* node tree update tags override individual node update flags */ if ((node->update & NODE_UPDATE) || (ntree->update & NTREE_UPDATE)) { if (ntreetype->update_node) @@ -1567,7 +1665,7 @@ void ntreeUpdateTree(bNodeTree *ntree) } /* check link validity */ - if (ntree->update & (NTREE_UPDATE_LINKS|NTREE_UPDATE_NODES)) + if (ntree->update & (NTREE_UPDATE_LINKS | NTREE_UPDATE_NODES)) ntree_validate_links(ntree); /* generic tree update callback */ @@ -1577,7 +1675,7 @@ void ntreeUpdateTree(bNodeTree *ntree) /* Trees can be associated with a specific node type (i.e. group nodes), * in that case a tree update function may be defined by that node type. */ - bNodeType *ntype= node_get_type(ntree, ntree->nodetype); + bNodeType *ntype = node_get_type(ntree, ntree->nodetype); if (ntype && ntype->updatetreefunc) ntype->updatetreefunc(ntree); } @@ -1591,7 +1689,7 @@ void ntreeUpdateTree(bNodeTree *ntree) void nodeUpdate(bNodeTree *ntree, bNode *node) { - bNodeTreeType *ntreetype= ntreeGetType(ntree->type); + bNodeTreeType *ntreetype = ntreeGetType(ntree->type); if (ntreetype->update_node) ntreetype->update_node(ntree, node); @@ -1613,8 +1711,8 @@ int nodeUpdateID(bNodeTree *ntree, ID *id) ntreetype = ntreeGetType(ntree->type); if (ntreetype->update_node) { - for (node= ntree->nodes.first; node; node= node->next) { - if (node->id==id) { + for (node = ntree->nodes.first; node; node = node->next) { + if (node->id == id) { change = TRUE; node->update |= NODE_UPDATE_ID; ntreetype->update_node(ntree, node); @@ -1624,8 +1722,8 @@ int nodeUpdateID(bNodeTree *ntree, ID *id) } } else { - for (node= ntree->nodes.first; node; node= node->next) { - if (node->id==id) { + for (node = ntree->nodes.first; node; node = node->next) { + if (node->id == id) { change = TRUE; node->update |= NODE_UPDATE_ID; if (node->typeinfo->updatefunc) @@ -1644,7 +1742,7 @@ int nodeUpdateID(bNodeTree *ntree, ID *id) int nodeValid(bNodeTree *ntree, bNodeTemplate *ntemp) { - bNodeType *ntype= node_get_type(ntree, ntemp->type); + bNodeType *ntype = node_get_type(ntree, ntemp->type); if (ntype) { if (ntype->validfunc) return ntype->validfunc(ntree, ntemp); @@ -1655,9 +1753,9 @@ int nodeValid(bNodeTree *ntree, bNodeTemplate *ntemp) return 0; } -const char* nodeLabel(bNode *node) +const char *nodeLabel(bNode *node) { - if (node->label[0]!='\0') + if (node->label[0] != '\0') return node->label; else if (node->typeinfo->labelfunc) return node->typeinfo->labelfunc(node); @@ -1769,8 +1867,8 @@ void node_type_template(struct bNodeType *ntype, struct bNodeTemplate (*template } 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)) + void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node), + void (*verifyfunc)(struct bNodeTree *ntree, struct bNode *node, struct ID *id)) { ntype->updatefunc = updatefunc; ntype->verifyfunc = verifyfunc; @@ -1783,9 +1881,9 @@ void node_type_tree(struct bNodeType *ntype, void (*inittreefunc)(struct bNodeTr } void node_type_group_edit(struct bNodeType *ntype, - struct bNodeTree *(*group_edit_get)(struct bNode *node), - struct bNodeTree *(*group_edit_set)(struct bNode *node, int edit), - void (*group_edit_clear)(struct bNode *node)) + struct bNodeTree *(*group_edit_get)(struct bNode *node), + struct bNodeTree *(*group_edit_set)(struct bNode *node, int edit), + void (*group_edit_clear)(struct bNode *node)) { ntype->group_edit_get = group_edit_get; ntype->group_edit_set = group_edit_set; @@ -1798,9 +1896,9 @@ void node_type_exec(struct bNodeType *ntype, void (*execfunc)(void *data, struct } void node_type_exec_new(struct bNodeType *ntype, - void *(*initexecfunc)(struct bNode *node), - void (*freeexecfunc)(struct bNode *node, void *nodedata), - void (*newexecfunc)(void *data, int thread, struct bNode *, void *nodedata, struct bNodeStack **, struct bNodeStack **)) + void *(*initexecfunc)(struct bNode *node), + void (*freeexecfunc)(struct bNode *node, void *nodedata), + void (*newexecfunc)(void *data, int thread, struct bNode *, void *nodedata, struct bNodeStack **, struct bNodeStack **)) { ntype->initexecfunc = initexecfunc; ntype->freeexecfunc = freeexecfunc; @@ -1829,10 +1927,10 @@ void node_type_compatibility(struct bNodeType *ntype, short compatibility) static bNodeType *is_nodetype_registered(ListBase *typelist, int type) { - bNodeType *ntype= typelist->first; + bNodeType *ntype = typelist->first; - for (;ntype; ntype= ntype->next ) - if (ntype->type==type) + for (; ntype; ntype = ntype->next) + if (ntype->type == type) return ntype; return NULL; @@ -1841,9 +1939,9 @@ static bNodeType *is_nodetype_registered(ListBase *typelist, int type) void nodeRegisterType(bNodeTreeType *ttype, bNodeType *ntype) { ListBase *typelist = &(ttype->node_types); - bNodeType *found= is_nodetype_registered(typelist, ntype->type); + bNodeType *found = is_nodetype_registered(typelist, ntype->type); - if (found==NULL) + if (found == NULL) BLI_addtail(typelist, ntype); } @@ -2070,7 +2168,7 @@ static void registerTextureNodes(bNodeTreeType *ttype) static void free_typeinfos(ListBase *list) { bNodeType *ntype, *next; - for (ntype=list->first; ntype; ntype=next) { + for (ntype = list->first; ntype; ntype = next) { next = ntype->next; if (ntype->needs_free) @@ -2080,6 +2178,10 @@ static void free_typeinfos(ListBase *list) void init_nodesystem(void) { + /* init clipboard */ + node_clipboard.nodes.first = node_clipboard.nodes.last = NULL; + node_clipboard.links.first = node_clipboard.links.last = NULL; + registerCompositNodes(ntreeGetType(NTREE_COMPOSIT)); registerShaderNodes(ntreeGetType(NTREE_SHADER)); registerTextureNodes(ntreeGetType(NTREE_TEXTURE)); @@ -2102,14 +2204,14 @@ void clear_scene_in_nodes(Main *bmain, Scene *sce) Scene *sce1; bNode *node; - for (sce1= bmain->scene.first; sce1; sce1=sce1->id.next) { - if (sce1!=sce) { + for (sce1 = bmain->scene.first; sce1; sce1 = sce1->id.next) { + if (sce1 != sce) { if (sce1->nodetree) { - for (node= sce1->nodetree->nodes.first; node; node= node->next) { - if (node->type==CMP_NODE_R_LAYERS) { - Scene *nodesce= (Scene *)node->id; + for (node = sce1->nodetree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_R_LAYERS) { + Scene *nodesce = (Scene *)node->id; - if (nodesce==sce) node->id = NULL; + if (nodesce == sce) node->id = NULL; } } } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 048560f3a83..baf216b95e9 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -210,7 +210,14 @@ void BKE_object_link_modifiers(struct Object *ob, struct Object *from) for (md = from->modifiers.first; md; md = md->next) { ModifierData *nmd = NULL; - if (ELEM4(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_ParticleInstance, eModifierType_Collision)) continue; + if (ELEM4(md->type, + eModifierType_Hook, + eModifierType_Softbody, + eModifierType_ParticleInstance, + eModifierType_Collision)) + { + continue; + } if (!BKE_object_support_modifier_type_check(ob, md->type)) continue; @@ -1318,7 +1325,8 @@ void BKE_object_copy_proxy_drivers(Object *ob, Object *target) if ((Object *)dtar->id == target) dtar->id = (ID *)ob; else { - /* only on local objects because this causes indirect links a -> b -> c, blend to point directly to a.blend + /* only on local objects because this causes indirect links + * 'a -> b -> c', blend to point directly to a.blend * when a.blend has a proxy thats linked into c.blend */ if (ob->id.lib == NULL) id_lib_extern((ID *)dtar->id); @@ -1688,16 +1696,16 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4]) if (cu->flag & CU_FOLLOW) { #if 0 - float x1, q[4]; + float si, q[4]; vec_to_quat(quat, dir, ob->trackflag, ob->upflag); /* the tilt */ normalize_v3(dir); q[0] = (float)cos(0.5 * vec[3]); - x1 = (float)sin(0.5 * vec[3]); - q[1] = -x1 * dir[0]; - q[2] = -x1 * dir[1]; - q[3] = -x1 * dir[2]; + si = (float)sin(0.5 * vec[3]); + q[1] = -si * dir[0]; + q[2] = -si * dir[1]; + q[3] = -si * dir[2]; mul_qt_qtqt(quat, q, quat); #else quat_apply_track(quat, ob->trackflag, ob->upflag); @@ -1803,7 +1811,11 @@ static void give_parvert(Object *par, int nr, float vec[3]) dm->getVertCo(dm, 0, vec); } } - else fprintf(stderr, "%s: DerivedMesh is needed to solve parenting, object position can be wrong now\n", __func__); + else { + fprintf(stderr, + "%s: DerivedMesh is needed to solve parenting, " + "object position can be wrong now\n", __func__); + } } else if (ELEM(par->type, OB_CURVE, OB_SURF)) { Nurb *nu; diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c index 13ea70d652d..66b0cff691e 100644 --- a/source/blender/blenkernel/intern/ocean.c +++ b/source/blender/blenkernel/intern/ocean.c @@ -834,7 +834,7 @@ void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V, o->_fft_in_nz = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_nz"); o->_N_x = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_x"); - /*o->_N_y = (float*) fftwf_malloc(o->_M * o->_N * sizeof(float)); (MEM01)*/ + /* o->_N_y = (float *) fftwf_malloc(o->_M * o->_N * sizeof(float)); (MEM01) */ o->_N_z = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_z"); o->_N_x_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_nx, o->_N_x, FFTW_ESTIMATE); diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index 52acbeb94e5..f115a41d419 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -50,13 +50,14 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" -#include "BKE_utildefines.h" +#include "BKE_font.h" #include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_sound.h" #include "BKE_image.h" +#include "BKE_main.h" #include "BKE_packedFile.h" #include "BKE_report.h" +#include "BKE_sound.h" +#include "BKE_utildefines.h" #ifdef _WIN32 #define open _open @@ -219,7 +220,7 @@ PackedFile *newPackedFile(ReportList *reports, const char *filename, const char void packAll(Main *bmain, ReportList *reports) { Image *ima; - VFont *vf; + VFont *vfont; bSound *sound; for (ima = bmain->image.first; ima; ima = ima->id.next) { @@ -233,9 +234,9 @@ void packAll(Main *bmain, ReportList *reports) } } - for (vf = bmain->vfont.first; vf; vf = vf->id.next) - if (vf->packedfile == NULL && vf->id.lib == NULL && strcmp(vf->name, FO_BUILTIN_NAME) != 0) - vf->packedfile = newPackedFile(reports, vf->name, bmain->name); + for (vfont = bmain->vfont.first; vfont; vfont = vfont->id.next) + if (vfont->packedfile == NULL && vfont->id.lib == NULL && BKE_vfont_is_builtin(vfont) == FALSE) + vfont->packedfile = newPackedFile(reports, vfont->name, bmain->name); for (sound = bmain->sound.first; sound; sound = sound->id.next) if (sound->packedfile == NULL && sound->id.lib == NULL) diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index ef3fd5c93d0..3267253e744 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -168,7 +168,7 @@ int paint_vertsel_test(Object *ob) ); } -void paint_init(Paint *p, const char col[3]) +void BKE_paint_init(Paint *p, const char col[3]) { Brush *brush; @@ -184,7 +184,7 @@ void paint_init(Paint *p, const char col[3]) p->flags |= PAINT_SHOW_BRUSH; } -void free_paint(Paint *paint) +void BKE_paint_free(Paint *paint) { id_us_min((ID *)paint->brush); } @@ -193,7 +193,7 @@ void free_paint(Paint *paint) * still do a id_us_plus(), rather then if we were copying betweem 2 existing * scenes where a matching value should decrease the existing user count as * with paint_brush_set() */ -void copy_paint(Paint *src, Paint *tar) +void BKE_paint_copy(Paint *src, Paint *tar) { tar->brush = src->brush; id_us_plus((ID *)tar->brush); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index d9afd1eefb4..edc82b56d23 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -178,21 +178,21 @@ Scene *BKE_scene_copy(Scene *sce, int type) ts->vpaint->paintcursor = NULL; ts->vpaint->vpaint_prev = NULL; ts->vpaint->wpaint_prev = NULL; - copy_paint(&ts->vpaint->paint, &ts->vpaint->paint); + BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint); } if (ts->wpaint) { ts->wpaint = MEM_dupallocN(ts->wpaint); ts->wpaint->paintcursor = NULL; ts->wpaint->vpaint_prev = NULL; ts->wpaint->wpaint_prev = NULL; - copy_paint(&ts->wpaint->paint, &ts->wpaint->paint); + BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint); } if (ts->sculpt) { ts->sculpt = MEM_dupallocN(ts->sculpt); - copy_paint(&ts->sculpt->paint, &ts->sculpt->paint); + BKE_paint_copy(&ts->sculpt->paint, &ts->sculpt->paint); } - copy_paint(&ts->imapaint.paint, &ts->imapaint.paint); + BKE_paint_copy(&ts->imapaint.paint, &ts->imapaint.paint); ts->imapaint.paintcursor = NULL; ts->particle.paintcursor = NULL; } @@ -294,22 +294,22 @@ void BKE_scene_free(Scene *sce) if (sce->toolsettings) { if (sce->toolsettings->vpaint) { - free_paint(&sce->toolsettings->vpaint->paint); + BKE_paint_free(&sce->toolsettings->vpaint->paint); MEM_freeN(sce->toolsettings->vpaint); } if (sce->toolsettings->wpaint) { - free_paint(&sce->toolsettings->wpaint->paint); + BKE_paint_free(&sce->toolsettings->wpaint->paint); MEM_freeN(sce->toolsettings->wpaint); } if (sce->toolsettings->sculpt) { - free_paint(&sce->toolsettings->sculpt->paint); + BKE_paint_free(&sce->toolsettings->sculpt->paint); MEM_freeN(sce->toolsettings->sculpt); } if (sce->toolsettings->uvsculpt) { - free_paint(&sce->toolsettings->uvsculpt->paint); + BKE_paint_free(&sce->toolsettings->uvsculpt->paint); MEM_freeN(sce->toolsettings->uvsculpt); } - free_paint(&sce->toolsettings->imapaint.paint); + BKE_paint_free(&sce->toolsettings->imapaint.paint); MEM_freeN(sce->toolsettings); sce->toolsettings = NULL; @@ -1018,6 +1018,11 @@ void BKE_scene_update_tagged(Main *bmain, Scene *scene) DAG_ids_flush_tagged(bmain); scene->physics_settings.quick_cache_step = 0; + + /* clear "LIB_DOIT" flag from all materials, to prevent infinite recursion problems later + * when trying to find materials with drivers that need evaluating [#32017] + */ + tag_main_idcode(bmain, ID_MA, FALSE); /* update all objects: drivers, matrices, displists, etc. flags set * by depgraph or manual, no layer check here, gets correct flushed diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 4dfa9f7e12e..56fddfdaa2b 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -356,7 +356,7 @@ ARegion *BKE_area_find_region_type(ScrArea *sa, int type) /* note, using this function is generally a last resort, you really want to be * using the context when you can - campbell * -1 for any type */ -struct ScrArea *BKE_screen_find_big_area(struct bScreen *sc, const int spacetype, const short min) +ScrArea *BKE_screen_find_big_area(bScreen *sc, const int spacetype, const short min) { ScrArea *sa, *big = NULL; int size, maxsize = 0; diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index b7f72ff86e2..674e848937f 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -545,7 +545,9 @@ static void seq_update_sound_bounds_recursive_rec(Scene *scene, Sequence *metase * since sound is played outside of evaluating the imbufs, */ for (seq = metaseq->seqbase.first; seq; seq = seq->next) { if (seq->type == SEQ_TYPE_META) { - seq_update_sound_bounds_recursive_rec(scene, seq, MAX2(start, metaseq_start(seq)), MIN2(end, metaseq_end(seq))); + seq_update_sound_bounds_recursive_rec(scene, seq, + maxi(start, metaseq_start(seq)), + mini(end, metaseq_end(seq))); } else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) { if (seq->scene_sound) { @@ -2070,10 +2072,30 @@ static ImBuf *seq_render_mask_strip( if (!seq->mask) { return NULL; } + else { + Mask *mask_temp; + MaskRasterHandle *mr_handle; + + mask_temp = BKE_mask_copy_nolib(seq->mask); + + BKE_mask_evaluate(mask_temp, seq->mask->sfra + nr, TRUE); + + maskbuf = MEM_mallocN(sizeof(float) * context.rectx * context.recty, __func__); + + mr_handle = BKE_maskrasterize_handle_new(); - BKE_mask_evaluate(seq->mask, seq->mask->sfra + nr, TRUE); + BKE_maskrasterize_handle_init(mr_handle, mask_temp, + context.rectx, context.recty, + TRUE, TRUE, TRUE); + + BKE_mask_free(mask_temp); + MEM_freeN(mask_temp); + + BKE_maskrasterize_buffer(mr_handle, context.rectx, context.recty, maskbuf); + + BKE_maskrasterize_handle_free(mr_handle); + } - maskbuf = MEM_callocN(sizeof(float) * context.rectx * context.recty, __func__); if (seq->flag & SEQ_MAKE_FLOAT) { /* pixels */ @@ -2082,14 +2104,6 @@ static ImBuf *seq_render_mask_strip( ibuf = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rectfloat); - BKE_mask_rasterize(seq->mask, - context.rectx, context.recty, - maskbuf, - TRUE, - FALSE, /*XXX- TODO: make on/off for anti-aliasing */ - TRUE /*XXX- TODO: make on/off for feather */ - ); - fp_src = maskbuf; fp_dst = ibuf->rect_float; i = context.rectx * context.recty; @@ -2108,14 +2122,6 @@ static ImBuf *seq_render_mask_strip( ibuf = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rect); - BKE_mask_rasterize(seq->mask, - context.rectx, context.recty, - maskbuf, - TRUE, - FALSE, /*XXX- TODO: make on/off for anti-aliasing */ - TRUE /*XXX- TODO: make on/off for feather */ - ); - fp_src = maskbuf; ub_dst = (unsigned char *)ibuf->rect; i = context.rectx * context.recty; @@ -2221,7 +2227,7 @@ static ImBuf *seq_render_scene_strip( /* for old scened this can be uninitialized, * should probably be added to do_versions at some point if the functionality stays */ if (context.scene->r.seq_prev_type == 0) - context.scene->r.seq_prev_type = 3 /* ==OB_SOLID */; + context.scene->r.seq_prev_type = 3 /* == OB_SOLID */; /* opengl offscreen render */ BKE_scene_update_for_newframe(context.bmain, scene, scene->lay); @@ -3140,7 +3146,7 @@ int seq_tx_get_final_left(Sequence *seq, int metaclip) { if (metaclip && seq->tmp) { /* return the range clipped by the parents range */ - return MAX2(seq_tx_get_final_left(seq, 0), seq_tx_get_final_left((Sequence *)seq->tmp, 1) ); + return maxi(seq_tx_get_final_left(seq, 0), seq_tx_get_final_left((Sequence *)seq->tmp, TRUE)); } else { return (seq->start - seq->startstill) + seq->startofs; @@ -3151,7 +3157,7 @@ int seq_tx_get_final_right(Sequence *seq, int metaclip) { if (metaclip && seq->tmp) { /* return the range clipped by the parents range */ - return MIN2(seq_tx_get_final_right(seq, 0), seq_tx_get_final_right((Sequence *)seq->tmp, 1) ); + return mini(seq_tx_get_final_right(seq, 0), seq_tx_get_final_right((Sequence *)seq->tmp, TRUE)); } else { return ((seq->start + seq->len) + seq->endstill) - seq->endofs; @@ -3810,6 +3816,18 @@ int BKE_sequencer_active_get_pair(Scene *scene, Sequence **seq_act, Sequence **s } } +Mask *BKE_sequencer_mask_get(Scene *scene) +{ + Sequence *seq_act = BKE_sequencer_active_get(scene); + + if (seq_act && seq_act->type == SEQ_TYPE_MASK) { + return seq_act->mask; + } + else { + return NULL; + } +} + /* api like funcs for adding */ void seq_load_apply(Scene *scene, Sequence *seq, SeqLoadInfo *seq_load) @@ -3900,7 +3918,7 @@ Sequence *sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo AUD_SoundInfo info; - sound = sound_new_file(CTX_data_main(C), seq_load->path); /* handles relative paths */ + sound = sound_new_file(bmain, seq_load->path); /* handles relative paths */ if (sound == NULL || sound->playback_handle == NULL) { //if (op) diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 2c105e4940d..26ca3805c28 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -3309,7 +3309,7 @@ static void mesh_to_softbody(Scene *scene, Object *ob) if (ob->softflag & OB_SB_GOAL) {bp->goal = sb->defgoal;} } - /* to proove the concept + /* to proof the concept * this enables per vertex *mass painting* */ @@ -3798,7 +3798,7 @@ static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCo /* vertexCos came from local world, go global */ mul_m4_v3(ob->obmat, bp->origE); /* just to be save give bp->origT a defined value - * will be calulated in interpolate_exciter()*/ + * will be calculated in interpolate_exciter() */ copy_v3_v3(bp->origT, bp->origE); } } diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 4342eb20d55..693f6fc1057 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -853,7 +853,7 @@ static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height fp[1] = (stroke_points[i].y - marker->search_min[1]) * frame_height / mask_height; } - /* TODO: add an option to control wether AA is enabled or not */ + /* TODO: add an option to control whether AA is enabled or not */ PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, mask_width, mask_height, FALSE); MEM_freeN(mask_points); @@ -916,7 +916,7 @@ void BKE_tracking_track_deselect(MovieTrackingTrack *track, int area) BKE_tracking_track_flag_clear(track, area, SELECT); } -/*********************** Marker *************************/ +/*********************** Marker *************************/ MovieTrackingMarker *BKE_tracking_marker_insert(MovieTrackingTrack *track, MovieTrackingMarker *marker) { @@ -995,8 +995,8 @@ void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event) if (event == CLAMP_PAT_DIM) { for (a = 0; a < 2; a++) { /* search shouldn't be resized smaller than pattern */ - marker->search_min[a] = MIN2(pat_min[a], marker->search_min[a]); - marker->search_max[a] = MAX2(pat_max[a], marker->search_max[a]); + marker->search_min[a] = minf(pat_min[a], marker->search_min[a]); + marker->search_max[a] = maxf(pat_max[a], marker->search_max[a]); } } else if (event == CLAMP_PAT_POS) { @@ -1020,8 +1020,8 @@ void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event) else if (event == CLAMP_SEARCH_DIM) { for (a = 0; a < 2; a++) { /* search shouldn't be resized smaller than pattern */ - marker->search_min[a] = MIN2(pat_min[a], marker->search_min[a]); - marker->search_max[a] = MAX2(pat_max[a], marker->search_max[a]); + marker->search_min[a] = minf(pat_min[a], marker->search_min[a]); + marker->search_max[a] = maxf(pat_max[a], marker->search_max[a]); } } else if (event == CLAMP_SEARCH_POS) { @@ -1133,6 +1133,36 @@ void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker, float DO_MINMAX2(marker->pattern_corners[3], min, max); } +void BKE_tracking_marker_get_subframe_position(MovieTrackingTrack *track, float framenr, float pos[2]) +{ + MovieTrackingMarker *marker = BKE_tracking_marker_get(track, (int) framenr); + MovieTrackingMarker *marker_last = track->markers + (track->markersnr - 1); + + if (marker != marker_last) { + MovieTrackingMarker *marker_next = marker + 1; + + if (marker_next->framenr == marker->framenr + 1) { + /* currently only do subframing inside tracked ranges, do not extrapolate tracked segments + * could be changed when / if mask parent would be interpolating position in-between + * tracked segments + */ + + float fac = (framenr - (int) framenr) / (marker_next->framenr - marker->framenr); + + interp_v2_v2v2(pos, marker->pos, marker_next->pos, fac); + } + else { + copy_v2_v2(pos, marker->pos); + } + } + else { + copy_v2_v2(pos, marker->pos); + } + + /* currently track offset is always wanted to be applied here, could be made an option later */ + add_v2_v2(pos, track->offset); +} + /*********************** Object *************************/ MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char *name) @@ -1505,7 +1535,7 @@ void BKE_tracking_distortion_free(MovieDistortion *distortion) MEM_freeN(distortion); } -void BKE_tracking_distort_v2(MovieTracking *tracking, float co[2], float nco[2]) +void BKE_tracking_distort_v2(MovieTracking *tracking, const float co[2], float r_co[2]) { MovieTrackingCamera *camera = &tracking->camera; @@ -1521,16 +1551,16 @@ void BKE_tracking_distort_v2(MovieTracking *tracking, float co[2], float nco[2]) camera->k1, camera->k2, camera->k3, x, y, &x, &y); /* result is in image coords already */ - nco[0] = x; - nco[1] = y; + r_co[0] = x; + r_co[1] = y; #else (void) camera; (void) co; - (void) nco; + zero_v2(r_co); #endif } -void BKE_tracking_undistort_v2(MovieTracking *tracking, float co[2], float nco[2]) +void BKE_tracking_undistort_v2(MovieTracking *tracking, const float co[2], float r_co[2]) { MovieTrackingCamera *camera = &tracking->camera; @@ -1541,12 +1571,12 @@ void BKE_tracking_undistort_v2(MovieTracking *tracking, float co[2], float nco[2 libmv_InvertIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy, camera->k1, camera->k2, camera->k3, x, y, &x, &y); - nco[0] = x * camera->focal + camera->principal[0]; - nco[1] = y * camera->focal + camera->principal[1] * aspy; + r_co[0] = x * camera->focal + camera->principal[0]; + r_co[1] = y * camera->focal + camera->principal[1] * aspy; #else (void) camera; (void) co; - (void) nco; + zero_v2(r_co); #endif } @@ -3242,7 +3272,7 @@ static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, i S = (-w * I - h * J) / (dx * I + dy * J + K); - scale = MAX2(scale, S); + scale = maxf(scale, S); } } } @@ -3251,7 +3281,7 @@ static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, i stab->scale = scale; if (stab->maxscale > 0.0f) - stab->scale = MIN2(stab->scale, stab->maxscale); + stab->scale = minf(stab->scale, stab->maxscale); } else { stab->scale = 1.0f; diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c index cd19f8a987c..dab44b5463c 100644 --- a/source/blender/blenkernel/intern/writeavi.c +++ b/source/blender/blenkernel/intern/writeavi.c @@ -80,13 +80,6 @@ bMovieHandle *BKE_movie_handle_get(const char imtype) mh.get_movie_path = filepath_avi; /* do the platform specific handles */ -#if defined(_WIN32) && !defined(FREE_WINDOWS) - if (imtype == R_IMF_IMTYPE_AVICODEC) { - //XXX mh.start_movie= start_avi_codec; - //XXX mh.append_movie= append_avi_codec; - //XXX mh.end_movie= end_avi_codec; - } -#endif #ifdef WITH_QUICKTIME if (imtype == R_IMF_IMTYPE_QUICKTIME) { mh.start_movie = start_qt; diff --git a/source/blender/blenkernel/intern/writeframeserver.c b/source/blender/blenkernel/intern/writeframeserver.c index a2028ff5fa1..a0f367961d2 100644 --- a/source/blender/blenkernel/intern/writeframeserver.c +++ b/source/blender/blenkernel/intern/writeframeserver.c @@ -128,7 +128,7 @@ int BKE_frameserver_start(struct Scene *scene, RenderData *UNUSED(rd), int rectx return 0; } - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &arg, sizeof(arg)); + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &arg, sizeof(arg)); addr.sin_family = AF_INET; addr.sin_port = htons(U.frameserverport); @@ -177,7 +177,7 @@ static char good_bye[] = "<body><pre>\n" "Render stopped. Goodbye</pre></body></html>"; -static int safe_write(char * s, int tosend) +static int safe_write(char *s, int tosend) { int total = tosend; do { @@ -192,15 +192,15 @@ static int safe_write(char * s, int tosend) return total; } -static int safe_puts(char * s) +static int safe_puts(char *s) { return safe_write(s, strlen(s)); } -static int handle_request(RenderData *rd, char * req) +static int handle_request(RenderData *rd, char *req) { - char * p; - char * path; + char *p; + char *path; int pathlen; if (memcmp(req, "GET ", 4) != 0) { @@ -230,22 +230,22 @@ static int handle_request(RenderData *rd, char * req) char buf[4096]; sprintf(buf, - "HTTP/1.1 200 OK\r\n" - "Content-Type: text/html\r\n" - "\r\n" - "start %d\n" - "end %d\n" - "width %d\n" - "height %d\n" - "rate %d\n" - "ratescale %d\n", - rd->sfra, - rd->efra, - render_width, - render_height, - rd->frs_sec, - 1 - ); + "HTTP/1.1 200 OK\r\n" + "Content-Type: text/html\r\n" + "\r\n" + "start %d\n" + "end %d\n" + "width %d\n" + "height %d\n" + "rate %d\n" + "ratescale %d\n", + rd->sfra, + rd->efra, + render_width, + render_height, + rd->frs_sec, + 1 + ); safe_puts(buf); return -1; @@ -262,7 +262,7 @@ int BKE_frameserver_loop(RenderData *rd, ReportList *UNUSED(reports)) { fd_set readfds; struct timeval tv; - struct sockaddr_in addr; + struct sockaddr_in addr; int len, rval; #ifdef FREE_WINDOWS int socklen; @@ -305,7 +305,7 @@ int BKE_frameserver_loop(RenderData *rd, ReportList *UNUSED(reports)) tv.tv_sec = 10; tv.tv_usec = 0; - rval = select(connsock + 1, &readfds, NULL, NULL, &tv); + rval = select(connsock + 1, &readfds, NULL, NULL, &tv); if (rval > 0) { break; } @@ -332,30 +332,30 @@ int BKE_frameserver_loop(RenderData *rd, ReportList *UNUSED(reports)) static void serve_ppm(int *pixels, int rectx, int recty) { - unsigned char* rendered_frame; - unsigned char* row = (unsigned char*) malloc(render_width * 3); + unsigned char *rendered_frame; + unsigned char *row = (unsigned char *) malloc(render_width * 3); int y; char header[1024]; sprintf(header, - "HTTP/1.1 200 OK\r\n" - "Content-Type: image/ppm\r\n" - "Connection: close\r\n" - "\r\n" - "P6\n" - "# Creator: blender frameserver v0.0.1\n" - "%d %d\n" - "255\n", - rectx, recty); + "HTTP/1.1 200 OK\r\n" + "Content-Type: image/ppm\r\n" + "Connection: close\r\n" + "\r\n" + "P6\n" + "# Creator: blender frameserver v0.0.1\n" + "%d %d\n" + "255\n", + rectx, recty); safe_puts(header); rendered_frame = (unsigned char *)pixels; for (y = recty - 1; y >= 0; y--) { - unsigned char* target = row; - unsigned char* src = rendered_frame + rectx * 4 * y; - unsigned char* end = src + rectx * 4; + unsigned char *target = row; + unsigned char *src = rendered_frame + rectx * 4 * y; + unsigned char *end = src + rectx * 4; while (src != end) { target[2] = src[2]; target[1] = src[1]; @@ -364,7 +364,7 @@ static void serve_ppm(int *pixels, int rectx, int recty) target += 3; src += 4; } - safe_write((char*)row, 3 * rectx); + safe_write((char *)row, 3 * rectx); } free(row); closesocket(connsock); @@ -372,7 +372,7 @@ static void serve_ppm(int *pixels, int rectx, int recty) } int BKE_frameserver_append(RenderData *UNUSED(rd), int UNUSED(start_frame), int frame, int *pixels, - int rectx, int recty, ReportList *UNUSED(reports)) + int rectx, int recty, ReportList *UNUSED(reports)) { fprintf(stderr, "Serving frame: %d\n", frame); if (write_ppm) { diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h index 912534e0aca..a40d4ca8463 100644 --- a/source/blender/blenlib/BLI_math_rotation.h +++ b/source/blender/blenlib/BLI_math_rotation.h @@ -92,7 +92,7 @@ void print_qt(const char *str, const float q[4]); /******************************** Axis Angle *********************************/ /* conversion */ -void axis_angle_to_quat(float r[4], const float axis[3], float angle); +void axis_angle_to_quat(float r[4], const float axis[3], const float angle); void axis_angle_to_mat3(float R[3][3], const float axis[3], const float angle); void axis_angle_to_mat4(float R[4][4], const float axis[3], const float angle); @@ -107,9 +107,7 @@ void single_axis_angle_to_mat3(float R[3][3], const char axis, const float angle /* TODO: the following calls should probably be depreceated sometime */ /* conversion */ -void vec_rot_to_quat(float quat[4], const float vec[3], const float phi); void vec_rot_to_mat3(float mat[3][3], const float vec[3], const float phi); -void vec_rot_to_mat4(float mat[4][4], const float vec[3], const float phi); /******************************** XYZ Eulers *********************************/ diff --git a/source/blender/blenlib/BLI_memarena.h b/source/blender/blenlib/BLI_memarena.h index 2a2dd31b26f..092bb639b91 100644 --- a/source/blender/blenlib/BLI_memarena.h +++ b/source/blender/blenlib/BLI_memarena.h @@ -47,41 +47,44 @@ extern "C" { */ #define BLI_MEMARENA_STD_BUFSIZE (1 << 14) +/* some GNU attributes are only available from GCC 4.3 */ +#define MEM_GNU_ATTRIBUTES (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 403)) + struct MemArena; typedef struct MemArena MemArena; struct MemArena *BLI_memarena_new(const int bufsize, const char *name) -#ifdef __GNUC__ +#if MEM_GNU_ATTRIBUTES __attribute__((warn_unused_result)) __attribute__((nonnull(2))) #endif ; void BLI_memarena_free(struct MemArena *ma) -#ifdef __GNUC__ +#if MEM_GNU_ATTRIBUTES __attribute__((nonnull(1))) #endif ; void BLI_memarena_use_malloc(struct MemArena *ma) -#ifdef __GNUC__ +#if MEM_GNU_ATTRIBUTES __attribute__((nonnull(1))) #endif ; void BLI_memarena_use_calloc(struct MemArena *ma) -#ifdef __GNUC__ +#if MEM_GNU_ATTRIBUTES __attribute__((nonnull(1))) #endif ; void BLI_memarena_use_align(struct MemArena *ma, const int align) -#ifdef __GNUC__ +#if MEM_GNU_ATTRIBUTES __attribute__((nonnull(1))) #endif ; void *BLI_memarena_alloc(struct MemArena *ma, int size) -#ifdef __GNUC__ +#if MEM_GNU_ATTRIBUTES __attribute__((warn_unused_result)) __attribute__((nonnull(1))) __attribute__((alloc_size(2))) diff --git a/source/blender/blenlib/BLI_stack.h b/source/blender/blenlib/BLI_stack.h new file mode 100644 index 00000000000..9151e6ab93f --- /dev/null +++ b/source/blender/blenlib/BLI_stack.h @@ -0,0 +1,54 @@ +/* + * ***** 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): Nicholas Bishop + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +#ifndef __BLI_STACK_H__ +#define __BLI_STACK_H__ + +/** \file BLI_stack.h + * \ingroup bli + */ + +typedef struct BLI_Stack BLI_Stack; + +/* Create a new homogeneous stack with elements of 'elem_size' bytes */ +BLI_Stack *BLI_stack_new(int elem_size, const char *description); + +/* Free the stack's data and the stack itself */ +void BLI_stack_free(BLI_Stack *stack); + +/* Copies the source value onto the stack (note that it copies + * elem_size bytes from 'src', the pointer itself is not stored) */ +void BLI_stack_push(BLI_Stack *stack, void *src); + +/* Retrieves and removes the top element from the stack. The value is + * copies to 'dst', which must be at least elem_size bytes. + * + * Does not reduce amount of allocated memory. + * + * If stack is empty, 'dst' will not be modified. */ +void BLI_stack_pop(BLI_Stack *stack, void *dst); + +/* Returns TRUE if the stack is empty, FALSE otherwise */ +int BLI_stack_empty(const BLI_Stack *stack); + +#endif diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index ac7681e3be7..0175076fab8 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -81,6 +81,7 @@ set(SRC intern/rct.c intern/scanfill.c intern/smallhash.c + intern/stack.c intern/storage.c intern/string.c intern/string_cursor_utf8.c @@ -135,6 +136,7 @@ set(SRC BLI_rect.h BLI_scanfill.h BLI_smallhash.h + BLI_stack.h BLI_string.h BLI_string_cursor_utf8.h BLI_string_utf8.h diff --git a/source/blender/blenlib/intern/BLI_args.c b/source/blender/blenlib/intern/BLI_args.c index 22b93948512..6a5952465fe 100644 --- a/source/blender/blenlib/intern/BLI_args.c +++ b/source/blender/blenlib/intern/BLI_args.c @@ -88,7 +88,7 @@ static unsigned int case_strhash(const void *ptr) static unsigned int keyhash(const void *ptr) { const bAKey *k = ptr; - return case_strhash(k->arg); // ^ BLI_ghashutil_inthash((void*)k->pass); + return case_strhash(k->arg); /* ^ BLI_ghashutil_inthash((void *)k->pass); */ } static int keycmp(const void *a, const void *b) diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 9a2b94b2c7e..2b3c314131b 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -648,7 +648,7 @@ static int implicit_leafs_index(BVHBuildHelper *data, int depth, int child_index // This functions returns the number of branches needed to have the requested number of leafs. static int implicit_needed_branches(int tree_type, int leafs) { - return MAX2(1, (leafs + tree_type - 3) / (tree_type - 1) ); + return maxi(1, (leafs + tree_type - 3) / (tree_type - 1) ); } /* diff --git a/source/blender/blenlib/intern/DLRB_tree.c b/source/blender/blenlib/intern/DLRB_tree.c index 53ae086782b..930ab4fc400 100644 --- a/source/blender/blenlib/intern/DLRB_tree.c +++ b/source/blender/blenlib/intern/DLRB_tree.c @@ -330,7 +330,7 @@ static void rotate_left(DLRBT_Tree *tree, DLRBT_Node *root) root_slot = &root->parent->right; } else - root_slot = ((DLRBT_Node **)&tree->root); //&((DLRBT_Node*)tree->root); + root_slot = ((DLRBT_Node **)&tree->root); /* &((DLRBT_Node *)tree->root); */ /* - pivot's left child becomes root's right child * - root now becomes pivot's left child @@ -364,7 +364,7 @@ static void rotate_right(DLRBT_Tree *tree, DLRBT_Node *root) root_slot = &root->parent->right; } else - root_slot = ((DLRBT_Node **)&tree->root); //&((DLRBT_Node*)tree->root); + root_slot = ((DLRBT_Node **)&tree->root); /* &((DLRBT_Node*)tree->root); */ /* - pivot's right child becomes root's left child * - root now becomes pivot's right child diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c index f458c158fb2..6d95b078340 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenlib/intern/bpath.c @@ -73,6 +73,7 @@ #include "BLI_bpath.h" #include "BLI_utildefines.h" +#include "BKE_font.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_report.h" @@ -191,12 +192,14 @@ void BLI_bpath_absolute_convert(Main *bmain, const char *basedir, ReportList *re data.count_tot, data.count_changed, data.count_failed); } -/* find this file recursively, use the biggest file so thumbnails don't get used by mistake - * - dir: subdir to search - * - filename: set this filename - * - filesize: filesize for the file +/** + * find this file recursively, use the biggest file so thumbnails don't get used by mistake + * \param filename_new: the path will be copied here, caller must initialize as empyu string. + * \param dirname: subdir to search + * \param filename: set this filename + * \param filesize: filesize for the file * - * return found: 1/0. + * \returns found: 1/0. */ #define MAX_RECUR 16 static int findFileRecursive(char *filename_new, @@ -213,8 +216,6 @@ static int findFileRecursive(char *filename_new, int size; int found = FALSE; - filename_new[0] = '\0'; - dir = opendir(dirname); if (dir == NULL) @@ -271,6 +272,8 @@ static int findMissingFiles_visit_cb(void *userdata, char *path_dst, const char int recur_depth = 0; int found; + filename_new[0] = '\0'; + found = findFileRecursive(filename_new, data->searchdir, BLI_path_basename((char *)path_src), &filesize, &recur_depth); @@ -482,9 +485,9 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int break; case ID_VF: { - VFont *vf = (VFont *)id; - if (vf->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) { - if (strcmp(vf->name, FO_BUILTIN_NAME) != 0) { + VFont *vfont = (VFont *)id; + if (vfont->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) { + if (BKE_vfont_is_builtin(vfont) == FALSE) { rewrite_path_fixed(((VFont *)id)->name, visit_cb, absbase, bpath_user_data); } } diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index 6ce8b9ecf91..60999e76c47 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -296,7 +296,7 @@ static int objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode) struct TmpFont *tf; /* Find the correct FreeType font */ - tf = BKE_vfont_find_tmpfont(vfont); + tf = BKE_vfont_tmpfont_find(vfont); /* What, no font found. Something strange here */ if (!tf) return FALSE; @@ -556,7 +556,7 @@ typedef struct FT_Outline_ * Type1 format. * * Each arc is described through a series of start, end and control points. Each point of the outline - * has a specific tag which indicates wether it is used to describe a line segment or an arc. + * has a specific tag which indicates whether it is used to describe a line segment or an arc. * * * The following rules are applied to decompose the contour's points into segments and arcs : diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c index b2d5392c596..97fc431d8fa 100644 --- a/source/blender/blenlib/intern/math_base_inline.c +++ b/source/blender/blenlib/intern/math_base_inline.c @@ -143,12 +143,20 @@ MINLINE float minf(float a, float b) { return (a < b) ? a : b; } - MINLINE float maxf(float a, float b) { return (a > b) ? a : b; } +MINLINE int mini(int a, int b) +{ + return (a < b) ? a : b; +} +MINLINE int maxi(int a, int b) +{ + return (b < a) ? a : b; +} + MINLINE float signf(float f) { return (f < 0.f) ? -1.f : 1.f; diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index de665686ea6..5d3a658b206 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -430,7 +430,7 @@ int isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], co { #define CCW(A, B, C) ((C[1] - A[1]) * (B[0] - A[0]) > (B[1]-A[1]) * (C[0]-A[0])) - return CCW(v1, v3, v4) != CCW(v2, v3, v4) && CCW(v1, v2, v3) != CCW(v1, v2, v4); + return CCW(v1, v3, v4) != CCW(v2, v3, v4) && CCW(v1, v2, v3) != CCW(v1, v2, v4); #undef CCW } @@ -1991,8 +1991,13 @@ void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3 void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const float v3[2], const float v4[2], const float co[2], float w[4]) { -#define MEAN_VALUE_HALF_TAN_V2(_area, i1, i2) ((_area = cross_v2v2(dirs[i1], dirs[i2])) != 0.0f ? \ - (((lens[i1] * lens[i2]) - dot_v2v2(dirs[i1], dirs[i2])) / _area) : 0.0f) + /* note: fabsf() here is not needed for convex quads (and not used in interp_weights_poly_v2). + * but in the case of concave/bowtie quads for the mask rasterizer it gives unreliable results + * without adding absf(). If this becomes an issue for more general useage we could have + * this optional or use a different function - Campbell */ +#define MEAN_VALUE_HALF_TAN_V2(_area, i1, i2) \ + ((_area = cross_v2v2(dirs[i1], dirs[i2])) != 0.0f ? \ + fabsf(((lens[i1] * lens[i2]) - dot_v2v2(dirs[i1], dirs[i2])) / _area) : 0.0f) float wtot, area; @@ -2367,7 +2372,8 @@ void resolve_quad_uv(float r_uv[2], const float st[2], const float st0[2], const /***************************** View & Projection *****************************/ -void orthographic_m4(float matrix[][4], const float left, const float right, const float bottom, const float top, const float nearClip, const float farClip) +void orthographic_m4(float matrix[][4], const float left, const float right, const float bottom, const float top, + const float nearClip, const float farClip) { float Xdelta, Ydelta, Zdelta; @@ -2386,7 +2392,8 @@ void orthographic_m4(float matrix[][4], const float left, const float right, con matrix[3][2] = -(farClip + nearClip) / Zdelta; } -void perspective_m4(float mat[4][4], const float left, const float right, const float bottom, const float top, const float nearClip, const float farClip) +void perspective_m4(float mat[4][4], const float left, const float right, const float bottom, const float top, + const float nearClip, const float farClip) { float Xdelta, Ydelta, Zdelta; diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index 78f0badc3b1..69f837c7652 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -166,10 +166,9 @@ void sub_qt_qtqt(float q[4], const float q1[4], const float q2[4]) /* angular mult factor */ void mul_fac_qt_fl(float q[4], const float fac) { - float angle = fac * saacos(q[0]); /* quat[0] = cos(0.5 * angle), but now the 0.5 and 2.0 rule out */ - - float co = (float)cos(angle); - float si = (float)sin(angle); + const float angle = fac * saacos(q[0]); /* quat[0] = cos(0.5 * angle), but now the 0.5 and 2.0 rule out */ + const float co = cosf(angle); + const float si = sinf(angle); q[0] = co; normalize_v3(q + 1); mul_v3_fl(q + 1, si); @@ -342,8 +341,8 @@ void mat3_to_quat_is_ok(float q[4], float wmat[3][3]) co = mat[2][2]; angle = 0.5f * saacos(co); - co = (float)cos(angle); - si = (float)sin(angle); + co = cosf(angle); + si = sinf(angle); q1[0] = co; q1[1] = -nor[0] * si; /* negative here, but why? */ q1[2] = -nor[1] * si; @@ -357,8 +356,8 @@ void mat3_to_quat_is_ok(float q[4], float wmat[3][3]) /* and align x-axes */ angle = (float)(0.5 * atan2(mat[0][1], mat[0][0])); - co = (float)cos(angle); - si = (float)sin(angle); + co = cosf(angle); + si = sinf(angle); q2[0] = co; q2[1] = 0.0f; q2[2] = 0.0f; @@ -483,8 +482,8 @@ void vec_to_quat(float q[4], const float vec[3], short axis, const short upflag) normalize_v3(nor); angle = 0.5f * saacos(co); - si = (float)sin(angle); - q[0] = (float)cos(angle); + si = sinf(angle); + q[0] = cosf(angle); q[1] = nor[0] * si; q[2] = nor[1] * si; q[3] = nor[2] * si; @@ -615,16 +614,18 @@ void tri_to_quat(float quat[4], const float v1[3], const float v2[3], const floa /* move z-axis to face-normal */ normal_tri_v3(vec, v1, v2, v3); - n[0] = vec[1]; + n[0] = vec[1]; n[1] = -vec[0]; - n[2] = 0.0f; + n[2] = 0.0f; normalize_v3(n); - if (n[0] == 0.0f && n[1] == 0.0f) n[0] = 1.0f; + if (n[0] == 0.0f && n[1] == 0.0f) { + n[0] = 1.0f; + } angle = -0.5f * (float)saacos(vec[2]); - co = (float)cos(angle); - si = (float)sin(angle); + co = cosf(angle); + si = sinf(angle); q1[0] = co; q1[1] = n[0] * si; q1[2] = n[1] * si; @@ -641,8 +642,8 @@ void tri_to_quat(float quat[4], const float v1[3], const float v2[3], const floa normalize_v3(vec); angle = (float)(0.5 * atan2(vec[1], vec[0])); - co = (float)cos(angle); - si = (float)sin(angle); + co = cosf(angle); + si = sinf(angle); q2[0] = co; q2[1] = 0.0f; q2[2] = 0.0f; @@ -659,22 +660,22 @@ void print_qt(const char *str, const float q[4]) /******************************** Axis Angle *********************************/ /* Axis angle to Quaternions */ -void axis_angle_to_quat(float q[4], const float axis[3], float angle) +void axis_angle_to_quat(float q[4], const float axis[3], const float angle) { float nor[3]; - float si; - if (normalize_v3_v3(nor, axis) == 0.0f) { + if (LIKELY(normalize_v3_v3(nor, axis) != 0.0f)) { + const float phi = angle / 2.0f; + float si; + si = sinf(phi); + q[0] = cosf(phi); + q[1] = nor[0] * si; + q[2] = nor[1] * si; + q[3] = nor[2] * si; + } + else { unit_qt(q); - return; } - - angle /= 2; - si = (float)sin(angle); - q[0] = (float)cos(angle); - q[1] = nor[0] * si; - q[2] = nor[1] * si; - q[3] = nor[2] * si; } /* Quaternions to Axis Angle */ @@ -689,8 +690,8 @@ void quat_to_axis_angle(float axis[3], float *angle, const float q[4]) #endif /* calculate angle/2, and sin(angle/2) */ - ha = (float)acos(q[0]); - si = (float)sin(ha); + ha = acosf(q[0]); + si = sinf(ha); /* from half-angle to angle */ *angle = ha * 2; @@ -739,8 +740,8 @@ void axis_angle_to_mat3(float mat[3][3], const float axis[3], const float angle) } /* now convert this to a 3x3 matrix */ - co = (float)cos(angle); - si = (float)sin(angle); + co = cosf(angle); + si = sinf(angle); ico = (1.0f - co); nsi[0] = nor[0] * si; @@ -837,7 +838,7 @@ void single_axis_angle_to_mat3(float mat[3][3], const char axis, const float ang /****************************** Vector/Rotation ******************************/ /* TODO: the following calls should probably be depreceated sometime */ -/* ODO, replace use of this function with axis_angle_to_mat3() */ +/* TODO, replace use of this function with axis_angle_to_mat3() */ void vec_rot_to_mat3(float mat[][3], const float vec[3], const float phi) { /* rotation of phi radials around vec */ @@ -849,8 +850,8 @@ void vec_rot_to_mat3(float mat[][3], const float vec[3], const float phi) vx2 = vx * vx; vy2 = vy * vy; vz2 = vz * vz; - co = (float)cos(phi); - si = (float)sin(phi); + co = cosf(phi); + si = sinf(phi); mat[0][0] = vx2 + co * (1.0f - vx2); mat[0][1] = vx * vy * (1.0f - co) + vz * si; @@ -863,38 +864,6 @@ void vec_rot_to_mat3(float mat[][3], const float vec[3], const float phi) mat[2][2] = vz2 + co * (1.0f - vz2); } -/* axis angle to 4x4 matrix */ -void vec_rot_to_mat4(float mat[][4], const float vec[3], const float phi) -{ - float tmat[3][3]; - - vec_rot_to_mat3(tmat, vec, phi); - unit_m4(mat); - copy_m4_m3(mat, tmat); -} - -/* axis angle to quaternion */ -void vec_rot_to_quat(float *quat, const float vec[3], const float phi) -{ - /* rotation of phi radials around vec */ - float si; - - quat[1] = vec[0]; - quat[2] = vec[1]; - quat[3] = vec[2]; - - if (normalize_v3(quat + 1) == 0.0f) { - unit_qt(quat); - } - else { - quat[0] = (float)cos((double)phi / 2.0); - si = (float)sin((double)phi / 2.0); - quat[1] *= si; - quat[2] *= si; - quat[3] *= si; - } -} - /******************************** XYZ Eulers *********************************/ /* XYZ order */ @@ -1691,12 +1660,12 @@ void quat_apply_track(float quat[4], short axis, short upflag) { /* rotations are hard coded to match vec_to_quat */ const float quat_track[][4] = { - {0.70710676908493, 0.0, -0.70710676908493, 0.0}, /* pos-y90 */ + {M_SQRT1_2, 0.0, -M_SQRT1_2, 0.0}, /* pos-y90 */ {0.5, 0.5, 0.5, 0.5}, /* Quaternion((1,0,0), radians(90)) * Quaternion((0,1,0), radians(90)) */ - {0.70710676908493, 0.0, 0.0, 0.70710676908493}, /* pos-z90 */ - {0.70710676908493, 0.0, 0.70710676908493, 0.0}, /* neg-y90 */ + {M_SQRT1_2, 0.0, 0.0, M_SQRT1_2}, /* pos-z90 */ + {M_SQRT1_2, 0.0, M_SQRT1_2, 0.0}, /* neg-y90 */ {0.5, -0.5, -0.5, 0.5}, /* Quaternion((1,0,0), radians(-90)) * Quaternion((0,1,0), radians(-90)) */ - {-3.0908619663705394e-08, 0.70710676908493, 0.70710676908493, 3.0908619663705394e-08} /* no rotation */ + {-3.0908619663705394e-08, M_SQRT1_2, M_SQRT1_2, 3.0908619663705394e-08} /* no rotation */ }; assert(axis >= 0 && axis <= 5); @@ -1711,8 +1680,8 @@ void quat_apply_track(float quat[4], short axis, short upflag) * up axis is used X->Y, Y->X, Z->X, if this first up axis isn used then rotate 90d * the strange bit shift below just find the low axis {X:Y, Y:X, Z:X} */ if (upflag != (2 - axis) >> 1) { - float q[4] = {0.70710676908493, 0.0, 0.0, 0.0}; /* assign 90d rotation axis */ - q[axis + 1] = ((axis == 1)) ? 0.70710676908493 : -0.70710676908493; /* flip non Y axis */ + float q[4] = {M_SQRT1_2, 0.0, 0.0, 0.0}; /* assign 90d rotation axis */ + q[axis + 1] = ((axis == 1)) ? M_SQRT1_2 : -M_SQRT1_2; /* flip non Y axis */ mul_qt_qtqt(quat, quat, q); } } diff --git a/source/blender/blenlib/intern/pbvh.c b/source/blender/blenlib/intern/pbvh.c index 14f9001814c..b4b546d9167 100644 --- a/source/blender/blenlib/intern/pbvh.c +++ b/source/blender/blenlib/intern/pbvh.c @@ -189,8 +189,8 @@ static void BB_expand(BB *bb, float co[3]) { int i; for (i = 0; i < 3; ++i) { - bb->bmin[i] = MIN2(bb->bmin[i], co[i]); - bb->bmax[i] = MAX2(bb->bmax[i], co[i]); + bb->bmin[i] = minf(bb->bmin[i], co[i]); + bb->bmax[i] = maxf(bb->bmax[i], co[i]); } } @@ -199,8 +199,8 @@ static void BB_expand_with_bb(BB *bb, BB *bb2) { int i; for (i = 0; i < 3; ++i) { - bb->bmin[i] = MIN2(bb->bmin[i], bb2->bmin[i]); - bb->bmax[i] = MAX2(bb->bmax[i], bb2->bmax[i]); + bb->bmin[i] = minf(bb->bmin[i], bb2->bmin[i]); + bb->bmax[i] = maxf(bb->bmax[i], bb2->bmax[i]); } } @@ -663,7 +663,7 @@ void BLI_pbvh_build_grids(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj, bvh->totgrid = totgrid; bvh->gridkey = *key; bvh->grid_hidden = grid_hidden; - bvh->leaf_limit = MAX2(LEAF_LIMIT / ((gridsize - 1) * (gridsize - 1)), 1); + bvh->leaf_limit = maxi(LEAF_LIMIT / ((gridsize - 1) * (gridsize - 1)), 1); BB_reset(&cb); diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c index 1f0bd445831..25191370130 100644 --- a/source/blender/blenlib/intern/scanfill.c +++ b/source/blender/blenlib/intern/scanfill.c @@ -658,7 +658,7 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf) if (v1 == v2 || v2 == v3) break; /* printf("test verts %x %x %x\n",v1,v2,v3); */ miny = minf(v1->xy[1], v3->xy[1]); - /* miny= MIN2(v1->xy[1],v3->xy[1]); */ + /* miny= minf(v1->xy[1],v3->xy[1]); */ sc1 = sc + 1; test = 0; diff --git a/source/blender/blenlib/intern/stack.c b/source/blender/blenlib/intern/stack.c new file mode 100644 index 00000000000..1d5bdbfdab6 --- /dev/null +++ b/source/blender/blenlib/intern/stack.c @@ -0,0 +1,110 @@ +/* + * ***** 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): Nicholas Bishop + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/blenlib/intern/stack.c + * \ingroup bli + */ + +#include <string.h> +#include <stdlib.h> /* abort() */ + +#include "BLI_stack.h" /* own include */ + +#include "BLI_utildefines.h" +#include "MEM_guardedalloc.h" + +typedef struct BLI_Stack { + void *data; + + int totelem; + int maxelem; + + int elem_size; +} BLI_Stack; + +BLI_Stack *BLI_stack_new(int elem_size, const char *description) +{ + BLI_Stack *stack = MEM_callocN(sizeof(*stack), description); + + stack->elem_size = elem_size; + + return stack; +} + +void BLI_stack_free(BLI_Stack *stack) +{ + if (stack) { + if (stack->data) + MEM_freeN(stack->data); + MEM_freeN(stack); + } +} + +/* Gets the last element in the stack */ +#define STACK_LAST_ELEM(stack__) \ + (((char *)(stack__)->data) + \ + ((stack__)->elem_size * ((stack__)->totelem - 1))) + +void BLI_stack_push(BLI_Stack *stack, void *src) +{ + /* Ensure stack is large enough */ + if (stack->totelem == stack->maxelem) { + if (stack->maxelem == 0) { + /* Initialize stack with space for a small hardcoded + * number of elements */ + stack->maxelem = 32; + stack->data = MEM_mallocN((stack->elem_size * + stack->maxelem), AT); + } + else { + /* Double stack size */ + int maxelem = stack->maxelem + stack->maxelem; + /* Check for overflow */ + BLI_assert(maxelem > stack->maxelem); + stack->data = MEM_reallocN(stack->data, + (stack->elem_size * + maxelem)); + stack->maxelem = maxelem; + } + } + + BLI_assert(stack->totelem < stack->maxelem); + + /* Copy source to end of stack */ + stack->totelem++; + memcpy(STACK_LAST_ELEM(stack), src, stack->elem_size); +} + +void BLI_stack_pop(BLI_Stack *stack, void *dst) +{ + BLI_assert(stack->totelem > 0); + if (stack->totelem > 0) { + memcpy(dst, STACK_LAST_ELEM(stack), stack->elem_size); + stack->totelem--; + } +} + +int BLI_stack_empty(const BLI_Stack *stack) +{ + return stack->totelem == 0; +} diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c index ff234a971aa..8047de2eeca 100644 --- a/source/blender/blenlib/intern/string_utf8.c +++ b/source/blender/blenlib/intern/string_utf8.c @@ -261,7 +261,9 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *dst_w, const char *src_c, const size { int len=0; - if (dst_w==NULL || src_c==NULL) return(0); + if (dst_w == NULL || src_c == NULL) { + return 0; + } while (*src_c && len < maxcpy) { size_t step= 0; diff --git a/source/blender/blenlib/intern/voronoi.c b/source/blender/blenlib/intern/voronoi.c index dc76fb1493d..f61df9c11f5 100644 --- a/source/blender/blenlib/intern/voronoi.c +++ b/source/blender/blenlib/intern/voronoi.c @@ -259,9 +259,9 @@ static float voronoi_getXOfEdge(VoronoiProcess *process, VoronoiParabola *par, f x2 = (-b - sqrtf(disc)) / (2 * a); if (p[1] < r[1]) - ry = MAX2(x1, x2); + ry = maxf(x1, x2); else - ry = MIN2(x1, x2); + ry = minf(x1, x2); return ry; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index da6fc6b1a0b..5b2c608bc41 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -761,7 +761,7 @@ BHead *blo_firstbhead(FileData *fd) BHead *blo_prevbhead(FileData *UNUSED(fd), BHead *thisblock) { - BHeadN *bheadn = (BHeadN *) (((char *) thisblock) - GET_INT_FROM_POINTER( &((BHeadN*)0)->bhead) ); + BHeadN *bheadn = (BHeadN *) (((char *) thisblock) - offsetof(BHeadN, bhead)); BHeadN *prev = bheadn->prev; return (prev) ? &prev->bhead : NULL; @@ -773,11 +773,11 @@ BHead *blo_nextbhead(FileData *fd, BHead *thisblock) BHead *bhead = NULL; if (thisblock) { - // bhead is actually a sub part of BHeadN - // We calculate the BHeadN pointer from the BHead pointer below - new_bhead = (BHeadN *) (((char *) thisblock) - GET_INT_FROM_POINTER( &((BHeadN*)0)->bhead) ); + /* bhead is actually a sub part of BHeadN + * We calculate the BHeadN pointer from the BHead pointer below */ + new_bhead = (BHeadN *) (((char *) thisblock) - offsetof(BHeadN, bhead)); - // get the next BHeadN. If it doesn't exist we read in the next one + /* get the next BHeadN. If it doesn't exist we read in the next one */ new_bhead = new_bhead->next; if (new_bhead == NULL) { new_bhead = get_bhead(fd); @@ -785,8 +785,8 @@ BHead *blo_nextbhead(FileData *fd, BHead *thisblock) } if (new_bhead) { - // here we do the reverse: - // go from the BHeadN pointer to the BHead pointer + /* here we do the reverse: + * go from the BHeadN pointer to the BHead pointer */ bhead = &new_bhead->bhead; } @@ -1667,8 +1667,8 @@ static void lib_link_brush(FileData *fd, Main *main) /* only link ID pointers */ for (brush = main->brush.first; brush; brush = brush->id.next) { - if (brush->id.flag & LIB_NEEDLINK) { - brush->id.flag -= LIB_NEEDLINK; + if (brush->id.flag & LIB_NEED_LINK) { + brush->id.flag -= LIB_NEED_LINK; brush->mtex.tex = newlibadr_us(fd, brush->id.lib, brush->mtex.tex); brush->clone.image = newlibadr_us(fd, brush->id.lib, brush->clone.image); @@ -1739,13 +1739,13 @@ static void lib_link_ipo(FileData *fd, Main *main) Ipo *ipo; for (ipo = main->ipo.first; ipo; ipo = ipo->id.next) { - if (ipo->id.flag & LIB_NEEDLINK) { + if (ipo->id.flag & LIB_NEED_LINK) { IpoCurve *icu; for (icu = ipo->curve.first; icu; icu = icu->next) { if (icu->driver) icu->driver->ob = newlibadr(fd, ipo->id.lib, icu->driver->ob); } - ipo->id.flag -= LIB_NEEDLINK; + ipo->id.flag -= LIB_NEED_LINK; } } } @@ -1913,14 +1913,25 @@ static void direct_link_fcurves(FileData *fd, ListBase *list) /* group */ fcu->grp = newdataadr(fd, fcu->grp); + /* clear disabled flag - allows disabled drivers to be tried again ([#32155]), + * but also means that another method for "reviving disabled F-Curves" exists + */ + fcu->flag &= ~FCURVE_DISABLED; + /* driver */ fcu->driver= newdataadr(fd, fcu->driver); if (fcu->driver) { ChannelDriver *driver= fcu->driver; DriverVar *dvar; + /* compiled expression data will need to be regenerated (old pointer may still be set here) */ driver->expr_comp = NULL; + /* give the driver a fresh chance - the operating environment may be different now + * (addons, etc. may be different) so the driver namespace may be sane now [#32155] + */ + driver->flag &= ~DRIVER_FLAG_INVALID; + /* relink variables, targets and their paths */ link_list(fd, &driver->variables); for (dvar= driver->variables.first; dvar; dvar= dvar->next) { @@ -1949,8 +1960,8 @@ static void lib_link_action(FileData *fd, Main *main) bActionChannel *chan; for (act = main->action.first; act; act = act->id.next) { - if (act->id.flag & LIB_NEEDLINK) { - act->id.flag -= LIB_NEEDLINK; + if (act->id.flag & LIB_NEED_LINK) { + act->id.flag -= LIB_NEED_LINK; // XXX depreceated - old animation system <<< for (chan=act->chanbase.first; chan; chan=chan->next) { @@ -2176,8 +2187,8 @@ static void lib_link_nodetree(FileData *fd, Main *main) /* only link ID pointers */ for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) { - if (ntree->id.flag & LIB_NEEDLINK) { - ntree->id.flag -= LIB_NEEDLINK; + if (ntree->id.flag & LIB_NEED_LINK) { + ntree->id.flag -= LIB_NEED_LINK; lib_link_ntree(fd, &ntree->id, ntree); } } @@ -2599,9 +2610,9 @@ static void lib_link_armature(FileData *fd, Main *main) bArmature *arm; for (arm = main->armature.first; arm; arm = arm->id.next) { - if (arm->id.flag & LIB_NEEDLINK) { + if (arm->id.flag & LIB_NEED_LINK) { if (arm->adt) lib_link_animdata(fd, &arm->id, arm->adt); - arm->id.flag -= LIB_NEEDLINK; + arm->id.flag -= LIB_NEED_LINK; } } } @@ -2649,14 +2660,14 @@ static void lib_link_camera(FileData *fd, Main *main) Camera *ca; for (ca = main->camera.first; ca; ca = ca->id.next) { - if (ca->id.flag & LIB_NEEDLINK) { + if (ca->id.flag & LIB_NEED_LINK) { if (ca->adt) lib_link_animdata(fd, &ca->id, ca->adt); ca->ipo = newlibadr_us(fd, ca->id.lib, ca->ipo); // XXX depreceated - old animation system ca->dof_ob = newlibadr_us(fd, ca->id.lib, ca->dof_ob); - ca->id.flag -= LIB_NEEDLINK; + ca->id.flag -= LIB_NEED_LINK; } } } @@ -2677,7 +2688,7 @@ static void lib_link_lamp(FileData *fd, Main *main) int a; for (la = main->lamp.first; la; la = la->id.next) { - if (la->id.flag & LIB_NEEDLINK) { + if (la->id.flag & LIB_NEED_LINK) { if (la->adt) lib_link_animdata(fd, &la->id, la->adt); for (a = 0; a < MAX_MTEX; a++) { @@ -2693,7 +2704,7 @@ static void lib_link_lamp(FileData *fd, Main *main) if (la->nodetree) lib_link_ntree(fd, &la->id, la->nodetree); - la->id.flag -= LIB_NEEDLINK; + la->id.flag -= LIB_NEED_LINK; } } } @@ -2737,13 +2748,13 @@ static void lib_link_key(FileData *fd, Main *main) } } - if (key->id.flag & LIB_NEEDLINK) { + if (key->id.flag & LIB_NEED_LINK) { if (key->adt) lib_link_animdata(fd, &key->id, key->adt); key->ipo = newlibadr_us(fd, key->id.lib, key->ipo); // XXX depreceated - old animation system key->from = newlibadr(fd, key->id.lib, key->from); - key->id.flag -= LIB_NEEDLINK; + key->id.flag -= LIB_NEED_LINK; } } } @@ -2807,7 +2818,7 @@ static void lib_link_mball(FileData *fd, Main *main) int a; for (mb = main->mball.first; mb; mb = mb->id.next) { - if (mb->id.flag & LIB_NEEDLINK) { + if (mb->id.flag & LIB_NEED_LINK) { if (mb->adt) lib_link_animdata(fd, &mb->id, mb->adt); for (a = 0; a < mb->totcol; a++) @@ -2815,7 +2826,7 @@ static void lib_link_mball(FileData *fd, Main *main) mb->ipo = newlibadr_us(fd, mb->id.lib, mb->ipo); // XXX depreceated - old animation system - mb->id.flag -= LIB_NEEDLINK; + mb->id.flag -= LIB_NEED_LINK; } } } @@ -2846,7 +2857,7 @@ static void lib_link_world(FileData *fd, Main *main) int a; for (wrld = main->world.first; wrld; wrld = wrld->id.next) { - if (wrld->id.flag & LIB_NEEDLINK) { + if (wrld->id.flag & LIB_NEED_LINK) { if (wrld->adt) lib_link_animdata(fd, &wrld->id, wrld->adt); wrld->ipo = newlibadr_us(fd, wrld->id.lib, wrld->ipo); // XXX depreceated - old animation system @@ -2862,7 +2873,7 @@ static void lib_link_world(FileData *fd, Main *main) if (wrld->nodetree) lib_link_ntree(fd, &wrld->id, wrld->nodetree); - wrld->id.flag -= LIB_NEEDLINK; + wrld->id.flag -= LIB_NEED_LINK; } } } @@ -2893,8 +2904,8 @@ static void lib_link_vfont(FileData *UNUSED(fd), Main *main) VFont *vf; for (vf = main->vfont.first; vf; vf = vf->id.next) { - if (vf->id.flag & LIB_NEEDLINK) { - vf->id.flag -= LIB_NEEDLINK; + if (vf->id.flag & LIB_NEED_LINK) { + vf->id.flag -= LIB_NEED_LINK; } } } @@ -2912,8 +2923,8 @@ static void lib_link_text(FileData *UNUSED(fd), Main *main) Text *text; for (text = main->text.first; text; text = text->id.next) { - if (text->id.flag & LIB_NEEDLINK) { - text->id.flag -= LIB_NEEDLINK; + if (text->id.flag & LIB_NEED_LINK) { + text->id.flag -= LIB_NEED_LINK; } } } @@ -2965,10 +2976,10 @@ static void lib_link_image(FileData *fd, Main *main) Image *ima; for (ima = main->image.first; ima; ima = ima->id.next) { - if (ima->id.flag & LIB_NEEDLINK) { + if (ima->id.flag & LIB_NEED_LINK) { if (ima->id.properties) IDP_LibLinkProperty(ima->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); - ima->id.flag -= LIB_NEEDLINK; + ima->id.flag -= LIB_NEED_LINK; } } } @@ -3035,7 +3046,7 @@ static void lib_link_curve(FileData *fd, Main *main) int a; for (cu = main->curve.first; cu; cu = cu->id.next) { - if (cu->id.flag & LIB_NEEDLINK) { + if (cu->id.flag & LIB_NEED_LINK) { if (cu->adt) lib_link_animdata(fd, &cu->id, cu->adt); for (a = 0; a < cu->totcol; a++) @@ -3052,7 +3063,7 @@ static void lib_link_curve(FileData *fd, Main *main) cu->ipo = newlibadr_us(fd, cu->id.lib, cu->ipo); // XXX depreceated - old animation system cu->key = newlibadr_us(fd, cu->id.lib, cu->key); - cu->id.flag -= LIB_NEEDLINK; + cu->id.flag -= LIB_NEED_LINK; } } } @@ -3137,7 +3148,7 @@ static void lib_link_texture(FileData *fd, Main *main) Tex *tex; for (tex = main->tex.first; tex; tex = tex->id.next) { - if (tex->id.flag & LIB_NEEDLINK) { + if (tex->id.flag & LIB_NEED_LINK) { if (tex->adt) lib_link_animdata(fd, &tex->id, tex->adt); tex->ima = newlibadr_us(fd, tex->id.lib, tex->ima); @@ -3154,7 +3165,7 @@ static void lib_link_texture(FileData *fd, Main *main) if (tex->nodetree) lib_link_ntree(fd, &tex->id, tex->nodetree); - tex->id.flag -= LIB_NEEDLINK; + tex->id.flag -= LIB_NEED_LINK; } } } @@ -3213,7 +3224,7 @@ static void lib_link_material(FileData *fd, Main *main) int a; for (ma = main->mat.first; ma; ma = ma->id.next) { - if (ma->id.flag & LIB_NEEDLINK) { + if (ma->id.flag & LIB_NEED_LINK) { if (ma->adt) lib_link_animdata(fd, &ma->id, ma->adt); /* Link ID Properties -- and copy this comment EXACTLY for easy finding @@ -3234,7 +3245,7 @@ static void lib_link_material(FileData *fd, Main *main) if (ma->nodetree) lib_link_ntree(fd, &ma->id, ma->nodetree); - ma->id.flag -= LIB_NEEDLINK; + ma->id.flag -= LIB_NEED_LINK; } } } @@ -3356,7 +3367,7 @@ static void lib_link_particlesettings(FileData *fd, Main *main) int a; for (part = main->particle.first; part; part = part->id.next) { - if (part->id.flag & LIB_NEEDLINK) { + if (part->id.flag & LIB_NEED_LINK) { if (part->adt) lib_link_animdata(fd, &part->id, part->adt); part->ipo = newlibadr_us(fd, part->id.lib, part->ipo); // XXX depreceated - old animation system @@ -3438,7 +3449,7 @@ static void lib_link_particlesettings(FileData *fd, Main *main) } } - part->id.flag -= LIB_NEEDLINK; + part->id.flag -= LIB_NEED_LINK; } } } @@ -3651,7 +3662,7 @@ static void lib_link_mesh(FileData *fd, Main *main) Mesh *me; for (me = main->mesh.first; me; me = me->id.next) { - if (me->id.flag & LIB_NEEDLINK) { + if (me->id.flag & LIB_NEED_LINK) { int i; /* Link ID Properties -- and copy this comment EXACTLY for easy finding @@ -3695,7 +3706,7 @@ static void lib_link_mesh(FileData *fd, Main *main) convert_tface_mt(fd, main); for (me = main->mesh.first; me; me = me->id.next) { - if (me->id.flag & LIB_NEEDLINK) { + if (me->id.flag & LIB_NEED_LINK) { /* * Re-tessellate, even if the polys were just created from tessfaces, this * is important because it: @@ -3712,7 +3723,7 @@ static void lib_link_mesh(FileData *fd, Main *main) BKE_mesh_tessface_clear(me); #endif - me->id.flag -= LIB_NEEDLINK; + me->id.flag -= LIB_NEED_LINK; } } } @@ -3954,13 +3965,13 @@ static void lib_link_latt(FileData *fd, Main *main) Lattice *lt; for (lt = main->latt.first; lt; lt = lt->id.next) { - if (lt->id.flag & LIB_NEEDLINK) { + if (lt->id.flag & LIB_NEED_LINK) { if (lt->adt) lib_link_animdata(fd, <->id, lt->adt); lt->ipo = newlibadr_us(fd, lt->id.lib, lt->ipo); // XXX depreceated - old animation system lt->key = newlibadr_us(fd, lt->id.lib, lt->key); - lt->id.flag -= LIB_NEEDLINK; + lt->id.flag -= LIB_NEED_LINK; } } } @@ -4007,7 +4018,7 @@ static void lib_link_object(FileData *fd, Main *main) int warn=0, a; for (ob = main->object.first; ob; ob = ob->id.next) { - if (ob->id.flag & LIB_NEEDLINK) { + if (ob->id.flag & LIB_NEED_LINK) { if (ob->id.properties) IDP_LibLinkProperty(ob->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); if (ob->adt) lib_link_animdata(fd, &ob->id, ob->adt); @@ -4086,7 +4097,7 @@ static void lib_link_object(FileData *fd, Main *main) ob->gpd = newlibadr_us(fd, ob->id.lib, ob->gpd); ob->duplilist = NULL; - ob->id.flag -= LIB_NEEDLINK; + ob->id.flag -= LIB_NEED_LINK; /* if id.us==0 a new base will be created later on */ /* WARNING! Also check expand_object(), should reflect the stuff below. */ @@ -4783,7 +4794,7 @@ static void lib_link_scene(FileData *fd, Main *main) TimeMarker *marker; for (sce = main->scene.first; sce; sce = sce->id.next) { - if (sce->id.flag & LIB_NEEDLINK) { + if (sce->id.flag & LIB_NEED_LINK) { /* Link ID Properties -- and copy this comment EXACTLY for easy finding * of library blocks that implement this.*/ if (sce->id.properties) IDP_LibLinkProperty(sce->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); @@ -4881,7 +4892,7 @@ static void lib_link_scene(FileData *fd, Main *main) /* Motion Tracking */ sce->clip = newlibadr_us(fd, sce->id.lib, sce->clip); - sce->id.flag -= LIB_NEEDLINK; + sce->id.flag -= LIB_NEED_LINK; } } } @@ -5142,11 +5153,11 @@ static void lib_link_windowmanager(FileData *fd, Main *main) wmWindow *win; for (wm = main->wm.first; wm; wm = wm->id.next) { - if (wm->id.flag & LIB_NEEDLINK) { + if (wm->id.flag & LIB_NEED_LINK) { for (win = wm->windows.first; win; win = win->next) win->screen = newlibadr(fd, NULL, win->screen); - wm->id.flag -= LIB_NEEDLINK; + wm->id.flag -= LIB_NEED_LINK; } } } @@ -5214,7 +5225,7 @@ static void lib_link_screen(FileData *fd, Main *main) ScrArea *sa; for (sc = main->screen.first; sc; sc = sc->id.next) { - if (sc->id.flag & LIB_NEEDLINK) { + if (sc->id.flag & LIB_NEED_LINK) { sc->id.us = 1; sc->scene = newlibadr(fd, sc->id.lib, sc->scene); sc->animtimer = NULL; /* saved in rare cases */ @@ -5287,7 +5298,8 @@ static void lib_link_screen(FileData *fd, Main *main) SpaceImage *sima = (SpaceImage *)sl; sima->image = newlibadr_us(fd, sc->id.lib, sima->image); - + sima->mask_info.mask = newlibadr_us(fd, sc->id.lib, sima->mask_info.mask); + /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data * so fingers crossed this works fine! */ @@ -5373,7 +5385,7 @@ static void lib_link_screen(FileData *fd, Main *main) SpaceClip *sclip = (SpaceClip *)sl; sclip->clip = newlibadr_us(fd, sc->id.lib, sclip->clip); - sclip->mask = newlibadr_us(fd, sc->id.lib, sclip->mask); + sclip->mask_info.mask = newlibadr_us(fd, sc->id.lib, sclip->mask_info.mask); sclip->scopes.track_search = NULL; sclip->scopes.track_preview = NULL; @@ -5387,7 +5399,7 @@ static void lib_link_screen(FileData *fd, Main *main) } } } - sc->id.flag -= LIB_NEEDLINK; + sc->id.flag -= LIB_NEED_LINK; } } } @@ -5587,6 +5599,7 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) * so assume that here we're doing for undo only... */ sima->gpd = restore_pointer_by_name(newmain, (ID *)sima->gpd, 1); + sima->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sima->mask_info.mask, 1); } else if (sl->spacetype == SPACE_SEQ) { SpaceSeq *sseq = (SpaceSeq *)sl; @@ -5662,7 +5675,7 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) SpaceClip *sclip = (SpaceClip *)sl; sclip->clip = restore_pointer_by_name(newmain, (ID *)sclip->clip, 1); - sclip->mask = restore_pointer_by_name(newmain, (ID *)sclip->mask, 1); + sclip->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sclip->mask_info.mask, 1); sclip->scopes.ok = 0; } @@ -6072,7 +6085,7 @@ static void lib_link_speaker(FileData *fd, Main *main) Speaker *spk; for (spk = main->speaker.first; spk; spk = spk->id.next) { - if (spk->id.flag & LIB_NEEDLINK) { + if (spk->id.flag & LIB_NEED_LINK) { if (spk->adt) lib_link_animdata(fd, &spk->id, spk->adt); spk->sound= newlibadr(fd, spk->id.lib, spk->sound); @@ -6080,7 +6093,7 @@ static void lib_link_speaker(FileData *fd, Main *main) spk->sound->id.us++; } - spk->id.flag -= LIB_NEEDLINK; + spk->id.flag -= LIB_NEED_LINK; } } } @@ -6119,8 +6132,8 @@ static void lib_link_sound(FileData *fd, Main *main) bSound *sound; for (sound = main->sound.first; sound; sound = sound->id.next) { - if (sound->id.flag & LIB_NEEDLINK) { - sound->id.flag -= LIB_NEEDLINK; + if (sound->id.flag & LIB_NEED_LINK) { + sound->id.flag -= LIB_NEED_LINK; sound->ipo = newlibadr_us(fd, sound->id.lib, sound->ipo); // XXX depreceated - old animation system sound_load(main, sound); @@ -6141,8 +6154,8 @@ static void lib_link_group(FileData *fd, Main *main) int add_us; for (group = main->group.first; group; group = group->id.next) { - if (group->id.flag & LIB_NEEDLINK) { - group->id.flag -= LIB_NEEDLINK; + if (group->id.flag & LIB_NEED_LINK) { + group->id.flag -= LIB_NEED_LINK; add_us = 0; @@ -6231,7 +6244,7 @@ static void lib_link_movieclip(FileData *fd, Main *main) MovieClip *clip; for (clip = main->movieclip.first; clip; clip = clip->id.next) { - if (clip->id.flag & LIB_NEEDLINK) { + if (clip->id.flag & LIB_NEED_LINK) { MovieTracking *tracking = &clip->tracking; MovieTrackingObject *object; @@ -6246,7 +6259,7 @@ static void lib_link_movieclip(FileData *fd, Main *main) lib_link_movieTracks(fd, clip, &object->tracks); } - clip->id.flag -= LIB_NEEDLINK; + clip->id.flag -= LIB_NEED_LINK; } } } @@ -6302,7 +6315,7 @@ static void lib_link_mask(FileData *fd, Main *main) mask = main->mask.first; while (mask) { - if (mask->id.flag & LIB_NEEDLINK) { + if (mask->id.flag & LIB_NEED_LINK) { MaskLayer *masklay; if (mask->adt) @@ -6327,7 +6340,7 @@ static void lib_link_mask(FileData *fd, Main *main) } } - mask->id.flag -= LIB_NEEDLINK; + mask->id.flag -= LIB_NEED_LINK; } mask = mask->id.next; } @@ -6428,7 +6441,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID BLI_addtail(lb, id); /* clear first 8 bits */ - id->flag = (id->flag & 0xFF00) | flag | LIB_NEEDLINK; + id->flag = (id->flag & 0xFF00) | flag | LIB_NEED_LINK; id->lib = main->curlib; if (id->flag & LIB_FAKEUSER) id->us= 1; else id->us = 0; @@ -7016,6 +7029,24 @@ static void do_version_ntree_dilateerode_264(void *UNUSED(data), ID *UNUSED(id), } } +static void do_version_ntree_mask_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) +{ + bNode *node; + + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_MASK) { + if (node->storage == NULL) { + NodeMask *data = MEM_callocN(sizeof(NodeMask), __func__); + /* move settings into own struct */ + data->size_x = node->custom3; + data->size_y = node->custom4; + node->custom3 = 0.5f; /* default shutter */ + node->storage = data; + } + } + } +} + static void do_version_ntree_keying_despill_balance(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) { bNode *node; @@ -7852,6 +7883,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main) ntreetype->foreach_nodetree(main, NULL, do_version_ntree_keying_despill_balance); } + if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 17)) { + bNodeTreeType *ntreetype = ntreeGetType(NTREE_COMPOSIT); + + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, do_version_ntree_mask_264); + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ @@ -8054,14 +8092,14 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) /* ************* APPEND LIBRARY ************** */ -struct bheadsort { +struct BHeadSort { BHead *bhead; void *old; }; static int verg_bheadsort(const void *v1, const void *v2) { - const struct bheadsort *x1=v1, *x2=v2; + const struct BHeadSort *x1=v1, *x2=v2; if (x1->old > x2->old) return 1; else if (x1->old < x2->old) return -1; @@ -8071,7 +8109,7 @@ static int verg_bheadsort(const void *v1, const void *v2) static void sort_bhead_old_map(FileData *fd) { BHead *bhead; - struct bheadsort *bhs; + struct BHeadSort *bhs; int tot = 0; for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) @@ -8080,14 +8118,14 @@ static void sort_bhead_old_map(FileData *fd) fd->tot_bheadmap = tot; if (tot == 0) return; - bhs = fd->bheadmap = MEM_mallocN(tot*sizeof(struct bheadsort), "bheadsort"); + bhs = fd->bheadmap = MEM_mallocN(tot*sizeof(struct BHeadSort), STRINGIFY(BHeadSort)); for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead), bhs++) { bhs->bhead = bhead; bhs->old = bhead->old; } - qsort(fd->bheadmap, tot, sizeof(struct bheadsort), verg_bheadsort); + qsort(fd->bheadmap, tot, sizeof(struct BHeadSort), verg_bheadsort); } static BHead *find_previous_lib(FileData *fd, BHead *bhead) @@ -8109,7 +8147,7 @@ static BHead *find_bhead(FileData *fd, void *old) #if 0 BHead *bhead; #endif - struct bheadsort *bhs, bhs_s; + struct BHeadSort *bhs, bhs_s; if (!old) return NULL; @@ -8118,7 +8156,7 @@ static BHead *find_bhead(FileData *fd, void *old) sort_bhead_old_map(fd); bhs_s.old = old; - bhs = bsearch(&bhs_s, fd->bheadmap, fd->tot_bheadmap, sizeof(struct bheadsort), verg_bheadsort); + bhs = bsearch(&bhs_s, fd->bheadmap, fd->tot_bheadmap, sizeof(struct BHeadSort), verg_bheadsort); if (bhs) return bhs->bhead; @@ -8894,6 +8932,37 @@ static void expand_movieclip(FileData *fd, Main *mainvar, MovieClip *clip) expand_animdata(fd, mainvar, clip->adt); } +static void expand_mask_parent(FileData *fd, Main *mainvar, MaskParent *parent) +{ + if (parent->id) { + expand_doit(fd, mainvar, parent->id); + } +} + +static void expand_mask(FileData *fd, Main *mainvar, Mask *mask) +{ + MaskLayer *mask_layer; + + if (mask->adt) + expand_animdata(fd, mainvar, mask->adt); + + for (mask_layer = mask->masklayers.first; mask_layer; mask_layer = mask_layer->next) { + MaskSpline *spline; + + for (spline = mask_layer->splines.first; spline; spline = spline->next) { + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + expand_mask_parent(fd, mainvar, &point->parent); + } + + expand_mask_parent(fd, mainvar, &spline->parent); + } + } +} + static void expand_main(FileData *fd, Main *mainvar) { ListBase *lbarray[MAX_LIBARRAY]; @@ -8909,7 +8978,7 @@ static void expand_main(FileData *fd, Main *mainvar) while (a--) { id= lbarray[a]->first; while (id) { - if (id->flag & LIB_TEST) { + if (id->flag & LIB_NEED_EXPAND) { switch (GS(id->name)) { case ID_OB: expand_object(fd, mainvar, (Object *)id); @@ -8977,10 +9046,13 @@ static void expand_main(FileData *fd, Main *mainvar) case ID_MC: expand_movieclip(fd, mainvar, (MovieClip *)id); break; + case ID_MSK: + expand_mask(fd, mainvar, (Mask *)id); + break; } do_it = TRUE; - id->flag -= LIB_TEST; + id->flag -= LIB_NEED_EXPAND; } id = id->next; @@ -9195,7 +9267,7 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r) if (strcmp(id->name, bhead_id_name(fd, bhead))==0) { id->flag &= ~LIB_READ; - id->flag |= LIB_TEST; + id->flag |= LIB_NEED_EXPAND; // printf("read lib block %s\n", id->name); read_libblock(fd, mainvar, bhead, id->flag, id_r); diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h index a3aa8e783a0..a979a16220d 100644 --- a/source/blender/blenloader/intern/readfile.h +++ b/source/blender/blenloader/intern/readfile.h @@ -84,7 +84,7 @@ typedef struct FileData { struct OldNewMap *imamap; struct OldNewMap *movieclipmap; - struct bheadsort *bheadmap; + struct BHeadSort *bheadmap; int tot_bheadmap; ListBase *mainlist; diff --git a/source/blender/blenloader/intern/undofile.c b/source/blender/blenloader/intern/undofile.c index 21a9290968b..38fd6e9d32d 100644 --- a/source/blender/blenloader/intern/undofile.c +++ b/source/blender/blenloader/intern/undofile.c @@ -104,7 +104,7 @@ void add_memfilechunk(MemFile *compare, MemFile *current, const char *buf, unsig static MemFileChunk *compchunk = NULL; MemFileChunk *curchunk; - /* this function inits when compare != NULL or when current==NULL */ + /* this function inits when compare != NULL or when current == NULL */ if (compare) { compchunk = compare->chunks.first; return; diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c index 46ef2716ade..c31906cbd80 100644 --- a/source/blender/blenloader/intern/versioning_legacy.c +++ b/source/blender/blenloader/intern/versioning_legacy.c @@ -569,7 +569,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) /* tex->extend and tex->imageflag have changed: */ Tex *tex = main->tex.first; while (tex) { - if (tex->id.flag & LIB_NEEDLINK) { + if (tex->id.flag & LIB_NEED_LINK) { if (tex->extend == 0) { if (tex->xrepeat || tex->yrepeat) { @@ -3107,7 +3107,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) part->id.lib = ob->id.lib; part->id.us--; - part->id.flag |= (ob->id.flag & LIB_NEEDLINK); + part->id.flag |= (ob->id.flag & LIB_NEED_LINK); psys->totpart = 0; psys->flag = PSYS_ENABLED|PSYS_CURRENT; diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index c39096d0800..74d3df01fd0 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -236,7 +236,7 @@ static float quad_coord(float aa[3], float bb[3], float cc[3], float dd[3], int f1 = fabsf(f1); f2 = fabsf(f2); - f1 = MIN2(f1, f2); + f1 = minf(f1, f2); CLAMP(f1, 0.0f, 1.0f + FLT_EPSILON); } else { diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index c80a88d280e..eacee8e12ad 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -104,6 +104,9 @@ static BMOpDefine bmo_smooth_vert_def = { {BMO_OP_SLOT_BOOL, "mirror_clip_y"}, /* set vertices close to the y axis before the operation to 0 */ {BMO_OP_SLOT_BOOL, "mirror_clip_z"}, /* set vertices close to the z axis before the operation to 0 */ {BMO_OP_SLOT_FLT, "clipdist"}, /* clipping threshod for the above three slots */ + {BMO_OP_SLOT_BOOL, "use_axis_x"}, /* smooth vertices along X axis */ + {BMO_OP_SLOT_BOOL, "use_axis_y"}, /* smooth vertices along Y axis */ + {BMO_OP_SLOT_BOOL, "use_axis_z"}, /* smooth vertices along Z axis */ {0} /* null-terminating sentinel */, }, bmo_smooth_vert_exec, diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 03b72aefee6..5d63172dbfa 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -507,8 +507,8 @@ static int linecrossesf(const float v1[2], const float v2[2], const float v3[2], #define GETMIN2_AXIS(a, b, ma, mb, axis) \ { \ - ma[axis] = MIN2(a[axis], b[axis]); \ - mb[axis] = MAX2(a[axis], b[axis]); \ + ma[axis] = minf(a[axis], b[axis]); \ + mb[axis] = maxf(a[axis], b[axis]); \ } (void)0 #define GETMIN2(a, b, ma, mb) \ @@ -538,17 +538,17 @@ static int linecrossesf(const float v1[2], const float v2[2], const float v3[2], /* do an interval test on the x and y axes */ /* first do x axis */ - if (ABS(v1[1] - v2[1]) < EPS && - ABS(v3[1] - v4[1]) < EPS && - ABS(v1[1] - v3[1]) < EPS) + if (fabsf(v1[1] - v2[1]) < EPS && + fabsf(v3[1] - v4[1]) < EPS && + fabsf(v1[1] - v3[1]) < EPS) { return (mv4[0] >= mv1[0] && mv3[0] <= mv2[0]); } /* now do y axis */ - if (ABS(v1[0] - v2[0]) < EPS && - ABS(v3[0] - v4[0]) < EPS && - ABS(v1[0] - v3[0]) < EPS) + if (fabsf(v1[0] - v2[0]) < EPS && + fabsf(v3[0] - v4[0]) < EPS && + fabsf(v1[0] - v3[0]) < EPS) { return (mv4[1] >= mv1[1] && mv3[1] <= mv2[1]); } @@ -994,8 +994,8 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) for (i = 0, l = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l = l->next) { p1 = projverts[i]; - out[0] = MAX2(out[0], p1[0]) + 0.01f; - out[1] = MAX2(out[1], p1[1]) + 0.01f; + out[0] = maxf(out[0], p1[0]) + 0.01f; + out[1] = maxf(out[1], p1[1]) + 0.01f; out[2] = 0.0f; p1[2] = 0.0f; diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c index c17f23eb658..5fec9f259ee 100644 --- a/source/blender/bmesh/operators/bmo_create.c +++ b/source/blender/bmesh/operators/bmo_create.c @@ -1312,7 +1312,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) * */ - /* Here we check for consistancy and create 2 edges */ + /* Here we check for consistency and create 2 edges */ if (totf == 0 && totv >= 4 && totv == tote + 2) { /* find a free standing vertex and 2 endpoint verts */ BMVert *v_free = NULL, *v_a = NULL, *v_b = NULL; diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index 5664c487236..1d73435032d 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -304,7 +304,7 @@ void bmo_recalc_face_normals_exec(BMesh *bm, BMOperator *op) BLI_array_declare(fstack); BMLoop *l, *l2; float maxx, maxx_test, cent[3]; - int i, maxi, flagflip = BMO_slot_bool_get(op, "do_flip"); + int i, i_max, flagflip = BMO_slot_bool_get(op, "do_flip"); startf = NULL; maxx = -1.0e10; @@ -353,7 +353,7 @@ void bmo_recalc_face_normals_exec(BMesh *bm, BMOperator *op) BMO_elem_flag_enable(bm, startf, FACE_VIS); i = 0; - maxi = 1; + i_max = 1; while (i >= 0) { f = fstack[i]; i--; @@ -381,9 +381,9 @@ void bmo_recalc_face_normals_exec(BMesh *bm, BMOperator *op) } } - if (i == maxi) { + if (i == i_max) { BLI_array_grow_one(fstack); - maxi++; + i_max++; } fstack[i] = l2->f; @@ -413,11 +413,16 @@ void bmo_smooth_vert_exec(BMesh *bm, BMOperator *op) float (*cos)[3] = NULL; float *co, *co2, clipdist = BMO_slot_float_get(op, "clipdist"); int i, j, clipx, clipy, clipz; + int xaxis, yaxis, zaxis; clipx = BMO_slot_bool_get(op, "mirror_clip_x"); clipy = BMO_slot_bool_get(op, "mirror_clip_y"); clipz = BMO_slot_bool_get(op, "mirror_clip_z"); + xaxis = BMO_slot_bool_get(op, "use_axis_x"); + yaxis = BMO_slot_bool_get(op, "use_axis_y"); + zaxis = BMO_slot_bool_get(op, "use_axis_z"); + i = 0; BMO_ITER (v, &siter, bm, op, "verts", BM_VERT) { BLI_array_grow_one(cos); @@ -451,7 +456,13 @@ void bmo_smooth_vert_exec(BMesh *bm, BMOperator *op) i = 0; BMO_ITER (v, &siter, bm, op, "verts", BM_VERT) { - copy_v3_v3(v->co, cos[i]); + if (xaxis) + v->co[0] = cos[i][0]; + if (yaxis) + v->co[1] = cos[i][1]; + if (zaxis) + v->co[2] = cos[i][2]; + i++; } diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp index 57829f777c5..0e8ead61437 100644 --- a/source/blender/collada/AnimationExporter.cpp +++ b/source/blender/collada/AnimationExporter.cpp @@ -106,7 +106,8 @@ void AnimationExporter::operator()(Object *ob) if ((!strcmp(transformName, "lens")) || (!strcmp(transformName, "ortho_scale")) || - (!strcmp(transformName, "clip_end")) || (!strcmp(transformName, "clip_start"))) + (!strcmp(transformName, "clip_end")) || + (!strcmp(transformName, "clip_start"))) { dae_animation(ob, fcu, transformName, true); } @@ -203,8 +204,10 @@ void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformNa } //axis names for colors - else if (!strcmp(transformName, "color") || !strcmp(transformName, "specular_color") || !strcmp(transformName, "diffuse_color") || - (!strcmp(transformName, "alpha"))) + else if (!strcmp(transformName, "color") || + !strcmp(transformName, "specular_color") || + !strcmp(transformName, "diffuse_color") || + !strcmp(transformName, "alpha")) { const char *axis_names[] = {"R", "G", "B"}; if (fcu->array_index < 3) @@ -212,8 +215,10 @@ void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformNa } //axis names for transforms - else if ((!strcmp(transformName, "location") || !strcmp(transformName, "scale")) || - (!strcmp(transformName, "rotation_euler")) || (!strcmp(transformName, "rotation_quaternion"))) + else if (!strcmp(transformName, "location") || + !strcmp(transformName, "scale") || + !strcmp(transformName, "rotation_euler") || + !strcmp(transformName, "rotation_quaternion")) { const char *axis_names[] = {"X", "Y", "Z"}; if (fcu->array_index < 3) @@ -260,9 +265,13 @@ void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformNa MEM_freeN(eul); MEM_freeN(eul_axis); } + else if(!strcmp(transformName, "lens") && (ob->type == OB_CAMERA)) { + output_id = create_lens_source_from_fcurve((Camera *) ob->data, COLLADASW::InputSemantic::OUTPUT, fcu, anim_id); + } else { output_id = create_source_from_fcurve(COLLADASW::InputSemantic::OUTPUT, fcu, anim_id, axis_name); } + // create interpolations source std::string interpolation_id = create_interpolation_source(fcu, anim_id, axis_name, &has_tangents); @@ -553,7 +562,7 @@ void AnimationExporter::add_source_parameters(COLLADASW::SourceBase::ParameterNa } } -void AnimationExporter::get_source_values(BezTriple *bezt, COLLADASW::InputSemantic::Semantics semantic, bool rotation, float *values, int *length) +void AnimationExporter::get_source_values(BezTriple *bezt, COLLADASW::InputSemantic::Semantics semantic, bool is_rotation, float *values, int *length) { switch (semantic) { case COLLADASW::InputSemantic::INPUT: @@ -562,7 +571,7 @@ void AnimationExporter::get_source_values(BezTriple *bezt, COLLADASW::InputSeman break; case COLLADASW::InputSemantic::OUTPUT: *length = 1; - if (rotation) { + if (is_rotation) { values[0] = RAD2DEGF(bezt->vec[1][1]); } else { @@ -578,7 +587,7 @@ void AnimationExporter::get_source_values(BezTriple *bezt, COLLADASW::InputSeman values[0] = 0; values[1] = 0; } - else if (rotation) { + else if (is_rotation) { values[1] = RAD2DEGF(bezt->vec[0][1]); } else { @@ -594,7 +603,7 @@ void AnimationExporter::get_source_values(BezTriple *bezt, COLLADASW::InputSeman values[0] = 0; values[1] = 0; } - else if (rotation) { + else if (is_rotation) { values[1] = RAD2DEGF(bezt->vec[2][1]); } else { @@ -654,6 +663,44 @@ std::string AnimationExporter::create_source_from_fcurve(COLLADASW::InputSemanti return source_id; } +/* + * Similar to create_source_from_fcurve, but adds conversion of lens + * animation data from focal length to FOV. + */ +std::string AnimationExporter::create_lens_source_from_fcurve(Camera *cam, COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id) +{ + std::string source_id = anim_id + get_semantic_suffix(semantic); + + COLLADASW::FloatSourceF source(mSW); + source.setId(source_id); + source.setArrayId(source_id + ARRAY_ID_SUFFIX); + source.setAccessorCount(fcu->totvert); + + source.setAccessorStride(1); + + COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); + add_source_parameters(param, semantic, false, "", false); + + source.prepareToAppendValues(); + + for (unsigned int i = 0; i < fcu->totvert; i++) { + float values[3]; // be careful! + int length = 0; + get_source_values(&fcu->bezt[i], semantic, false, values, &length); + for (int j = 0; j < length; j++) + { + float val = RAD2DEGF(focallength_to_fov(values[j], cam->sensor_x)); + source.appendValues(val); + } + } + + source.finish(); + + return source_id; +} + + + //Currently called only to get OUTPUT source values ( if rotation and hence the axis is also specified ) std::string AnimationExporter::create_source_from_array(COLLADASW::InputSemantic::Semantics semantic, float *v, int tot, bool is_rot, const std::string& anim_id, const char *axis_name) { diff --git a/source/blender/collada/AnimationExporter.h b/source/blender/collada/AnimationExporter.h index 1313687db28..0a7832e9d64 100644 --- a/source/blender/collada/AnimationExporter.h +++ b/source/blender/collada/AnimationExporter.h @@ -133,6 +133,8 @@ protected: std::string create_source_from_fcurve(COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id, const char *axis_name); + std::string create_lens_source_from_fcurve(Camera *cam, COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id); + std::string create_source_from_array(COLLADASW::InputSemantic::Semantics semantic, float *v, int tot, bool is_rot, const std::string& anim_id, const char *axis_name); std::string create_source_from_vector(COLLADASW::InputSemantic::Semantics semantic, std::vector<float> &fra, bool is_rot, const std::string& anim_id, const char *axis_name); diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp index 9c11358ce7f..a237222774d 100644 --- a/source/blender/collada/AnimationImporter.cpp +++ b/source/blender/collada/AnimationImporter.cpp @@ -652,6 +652,51 @@ void AnimationImporter:: Assign_float_animations(const COLLADAFW::UniqueId& list } +/* + * Lens animations must be stored in COLLADA by using FOV, + * while blender internally uses focal length. + * The imported animation curves must be converted appropriately. + */ +void AnimationImporter::Assign_lens_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, const double aspect, Camera *cam, const char *anim_type, int fov_type) +{ + char rna_path[100]; + if (animlist_map.find(listid) == animlist_map.end()) { + return; + } + else { + //anim_type has animations + const COLLADAFW::AnimationList *animlist = animlist_map[listid]; + const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings(); + //all the curves belonging to the current binding + std::vector<FCurve *> animcurves; + for (unsigned int j = 0; j < bindings.getCount(); j++) { + animcurves = curve_map[bindings[j].animation]; + + BLI_strncpy(rna_path, anim_type, sizeof(rna_path)); + + modify_fcurve(&animcurves, rna_path, 0); + std::vector<FCurve *>::iterator iter; + //Add the curves of the current animation to the object + for (iter = animcurves.begin(); iter != animcurves.end(); iter++) { + FCurve *fcu = *iter; + + for (unsigned int i = 0; i < fcu->totvert; i++) { + + double input_fov = fcu->bezt[i].vec[1][1]; + double xfov = (fov_type == CAMERA_YFOV) ? aspect * input_fov : input_fov; + + // fov is in degrees, cam->lens is in millimiters + double fov = fov_to_focallength(DEG2RADF(input_fov), cam->sensor_x); + + fcu->bezt[i].vec[1][1] = fov; + } + + BLI_addtail(AnimCurves, fcu); + } + } + } +} + void AnimationImporter::apply_matrix_curves(Object *ob, std::vector<FCurve *>& animcurves, COLLADAFW::Node *root, COLLADAFW::Node *node, COLLADAFW::Transformation *tm) { @@ -796,6 +841,39 @@ void AnimationImporter::apply_matrix_curves(Object *ob, std::vector<FCurve *>& a } +/* + * This function returns the aspet ration from the Collada camera. + * + * Note:COLLADA allows to specify either XFov, or YFov alone. + * In tghat case the aspect ratio can be determined from + * the viewport aspect ratio (which is 1:1 ?) + * XXX: check this: its probably wrong! + * If both values are specified, then the aspect ration is simply xfov/yfov + * and if aspect ratio is efined, then .. well then its that one. + */ +static const double get_aspect_ratio(const COLLADAFW::Camera *camera) +{ + double aspect = camera->getAspectRatio().getValue(); + + if(aspect == 0) + { + const double yfov = camera->getYFov().getValue(); + + if(yfov == 0) + aspect=1; // assume yfov and xfov are equal + else + { + const double xfov = camera->getXFov().getValue(); + if (xfov==0) + aspect = 1; + else + aspect = xfov / yfov; + } + } + return aspect; +} + + void AnimationImporter::translate_Animations(COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, COLLADAFW::Node *>& root_map, std::multimap<COLLADAFW::UniqueId, Object *>& object_map, @@ -804,8 +882,15 @@ void AnimationImporter::translate_Animations(COLLADAFW::Node *node, AnimationImporter::AnimMix *animType = get_animation_type(node, FW_object_map); bool is_joint = node->getType() == COLLADAFW::Node::JOINT; - COLLADAFW::Node *root = root_map.find(node->getUniqueId()) == root_map.end() ? node : root_map[node->getUniqueId()]; - Object *ob = is_joint ? armature_importer->get_armature_for_joint(root) : object_map.find(node->getUniqueId())->second; + COLLADAFW::UniqueId uid = node->getUniqueId(); + COLLADAFW::Node *root = root_map.find(uid) == root_map.end() ? node : root_map[uid]; + + Object *ob; + if(is_joint) + ob = armature_importer->get_armature_for_joint(root); + else + ob = object_map.find(uid) == object_map.end() ? NULL : object_map.find(uid)->second; + if (!ob) { fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str()); return; @@ -917,10 +1002,11 @@ void AnimationImporter::translate_Animations(COLLADAFW::Node *node, } if (animType->camera != 0) { - Camera *camera = (Camera *) ob->data; - - if (!camera->adt || !camera->adt->action) act = verify_adt_action((ID *)&camera->id, 1); - else act = camera->adt->action; + Camera *cam = (Camera *) ob->data; + if (!cam->adt || !cam->adt->action) + act = verify_adt_action((ID *)&cam->id, 1); + else + act = cam->adt->action; ListBase *AnimCurves = &(act->curves); const COLLADAFW::InstanceCameraPointerArray& nodeCameras = node->getInstanceCameras(); @@ -931,7 +1017,15 @@ void AnimationImporter::translate_Animations(COLLADAFW::Node *node, if ((animType->camera & CAMERA_XFOV) != 0) { const COLLADAFW::AnimatableFloat *xfov = &(camera->getXFov()); const COLLADAFW::UniqueId& listid = xfov->getAnimationList(); - Assign_float_animations(listid, AnimCurves, "lens"); + double aspect = get_aspect_ratio(camera); + Assign_lens_animations(listid, AnimCurves, aspect, cam, "lens", CAMERA_XFOV); + } + + else if ((animType->camera & CAMERA_YFOV) != 0) { + const COLLADAFW::AnimatableFloat *yfov = &(camera->getYFov()); + const COLLADAFW::UniqueId& listid = yfov->getAnimationList(); + double aspect = get_aspect_ratio(camera); + Assign_lens_animations(listid, AnimCurves, aspect, cam, "lens", CAMERA_YFOV); } else if ((animType->camera & CAMERA_XMAG) != 0) { @@ -940,6 +1034,12 @@ void AnimationImporter::translate_Animations(COLLADAFW::Node *node, Assign_float_animations(listid, AnimCurves, "ortho_scale"); } + else if ((animType->camera & CAMERA_YMAG) != 0) { + const COLLADAFW::AnimatableFloat *ymag = &(camera->getYMag()); + const COLLADAFW::UniqueId& listid = ymag->getAnimationList(); + Assign_float_animations(listid, AnimCurves, "ortho_scale"); + } + if ((animType->camera & CAMERA_ZFAR) != 0) { const COLLADAFW::AnimatableFloat *zfar = &(camera->getFarClippingPlane()); const COLLADAFW::UniqueId& listid = zfar->getAnimationList(); @@ -1166,14 +1266,27 @@ AnimationImporter::AnimMix *AnimationImporter::get_animation_type(const COLLADAF const COLLADAFW::InstanceCameraPointerArray& nodeCameras = node->getInstanceCameras(); for (unsigned int i = 0; i < nodeCameras.getCount(); i++) { - const COLLADAFW::Camera *camera = (COLLADAFW::Camera *) FW_object_map[nodeCameras[i]->getInstanciatedObjectId()]; + const COLLADAFW::Camera *camera = (COLLADAFW::Camera *) FW_object_map[nodeCameras[i]->getInstanciatedObjectId()]; + if ( camera == NULL ) { + // Can happen if the node refers to an unknown camera. + continue; + } + + const bool is_perspective_type = camera->getCameraType() == COLLADAFW::Camera::PERSPECTIVE; - if (camera->getCameraType() == COLLADAFW::Camera::PERSPECTIVE) { - types->camera = setAnimType(&(camera->getXMag()), (types->camera), CAMERA_XFOV); + int addition; + const COLLADAFW::Animatable *mag; + const COLLADAFW::UniqueId listid = camera->getYMag().getAnimationList(); + if (animlist_map.find(listid) != animlist_map.end()) { + mag = &(camera->getYMag()); + addition = (is_perspective_type) ? CAMERA_YFOV: CAMERA_YMAG; } else { - types->camera = setAnimType(&(camera->getXMag()), (types->camera), CAMERA_XMAG); + mag = &(camera->getXMag()); + addition = (is_perspective_type) ? CAMERA_XFOV: CAMERA_XMAG; } + types->camera = setAnimType(mag, (types->camera), addition); + types->camera = setAnimType(&(camera->getFarClippingPlane()), (types->camera), CAMERA_ZFAR); types->camera = setAnimType(&(camera->getNearClippingPlane()), (types->camera), CAMERA_ZNEAR); @@ -1205,10 +1318,14 @@ AnimationImporter::AnimMix *AnimationImporter::get_animation_type(const COLLADAF int AnimationImporter::setAnimType(const COLLADAFW::Animatable *prop, int types, int addition) { - const COLLADAFW::UniqueId& listid = prop->getAnimationList(); + int anim_type; + const COLLADAFW::UniqueId& listid = prop->getAnimationList(); if (animlist_map.find(listid) != animlist_map.end()) - return types | addition; - else return types; + anim_type = types | addition; + else + anim_type = types; + + return anim_type; } // Is not used anymore. diff --git a/source/blender/collada/AnimationImporter.h b/source/blender/collada/AnimationImporter.h index d6a93a36c6e..db61692484b 100644 --- a/source/blender/collada/AnimationImporter.h +++ b/source/blender/collada/AnimationImporter.h @@ -102,8 +102,10 @@ private: // INANIMATE = 0, CAMERA_XFOV = 2, CAMERA_XMAG = 4, - CAMERA_ZFAR = 8, - CAMERA_ZNEAR = 16 + CAMERA_YFOV = 8, + CAMERA_YMAG = 16, + CAMERA_ZFAR = 32, + CAMERA_ZNEAR = 64 }; enum matAnim @@ -163,6 +165,7 @@ public: void Assign_color_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, const char * anim_type); void Assign_float_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, const char * anim_type); + void Assign_lens_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, const double aspect, Camera *cam, const char *anim_type, int fov_type); int setAnimType ( const COLLADAFW::Animatable * prop, int type, int addition); diff --git a/source/blender/collada/CameraExporter.cpp b/source/blender/collada/CameraExporter.cpp index be424fbbb4d..7d438f7f12f 100644 --- a/source/blender/collada/CameraExporter.cpp +++ b/source/blender/collada/CameraExporter.cpp @@ -84,7 +84,7 @@ void CamerasExporter::operator()(Object *ob, Scene *sce) default: { COLLADASW::OrthographicOptic ortho(mSW); - ortho.setXMag(cam->ortho_scale, "xmag"); + ortho.setXMag(cam->ortho_scale / 2, "xmag"); ortho.setAspectRatio((float)(sce->r.xsch) / (float)(sce->r.ysch), false, "aspect_ratio"); ortho.setZFar(cam->clipend, false, "zfar"); ortho.setZNear(cam->clipsta, false, "znear"); diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index ca07512f439..7cfce9d2526 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -308,7 +308,7 @@ Object *DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera { const COLLADAFW::UniqueId& cam_uid = camera->getInstanciatedObjectId(); if (uid_camera_map.find(cam_uid) == uid_camera_map.end()) { - fprintf(stderr, "Couldn't find camera by UID.\n"); + // fprintf(stderr, "Couldn't find camera by UID.\n"); return NULL; } @@ -443,7 +443,13 @@ void DocumentImporter::write_node(COLLADAFW::Node *node, COLLADAFW::Node *parent } while (camera_done < camera.getCount()) { ob = create_camera_object(camera[camera_done], sce); - objects_done->push_back(ob); + if (ob == NULL) { + std::string id = node->getOriginalId(); + std::string name = node->getName(); + fprintf(stderr, "<node id=\"%s\", name=\"%s\" >...contains a reference to an unknown instance_camera.\n", id.c_str(), name.c_str()); + } + else + objects_done->push_back(ob); ++camera_done; } while (lamp_done < lamp.getCount()) { @@ -846,7 +852,7 @@ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera) switch (cam->type) { case CAM_ORTHO: { - double ymag = camera->getYMag().getValue(); + double ymag = 2 * camera->getYMag().getValue(); double aspect = camera->getAspectRatio().getValue(); double xmag = aspect * ymag; cam->ortho_scale = (float)xmag; @@ -873,7 +879,7 @@ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera) { switch (cam->type) { case CAM_ORTHO: - cam->ortho_scale = (float)camera->getXMag().getValue(); + cam->ortho_scale = (float)camera->getXMag().getValue() * 2; break; case CAM_PERSP: default: diff --git a/source/blender/compositor/COM_compositor.h b/source/blender/compositor/COM_compositor.h index cd1615c9094..4e955ea3df1 100644 --- a/source/blender/compositor/COM_compositor.h +++ b/source/blender/compositor/COM_compositor.h @@ -297,7 +297,7 @@ extern "C" { * - output nodes can have different priorities in the WorkScheduler. * This is implemented in the COM_execute function. */ -void COM_execute(RenderData* rd, bNodeTree *editingtree, int rendering); +void COM_execute(RenderData *rd, bNodeTree *editingtree, int rendering); /** * @brief Return a list of highlighted bnodes pointers. @@ -310,7 +310,7 @@ void COM_startReadHighlights(void); * @param bnode * @return */ -int COM_isHighlightedbNode(bNode* bnode); +int COM_isHighlightedbNode(bNode *bnode); #ifdef __cplusplus } diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h index e890715cafe..a87b40af89d 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.h +++ b/source/blender/compositor/intern/COM_ExecutionGroup.h @@ -316,7 +316,7 @@ public: * @brief get all inputbuffers needed to calculate an chunk * @note all inputbuffers must be executed * @param chunkNumber the chunk to be calculated - * @return MemoryBuffer** the inputbuffers + * @return (MemoryBuffer **) the inputbuffers */ MemoryBuffer **getInputBuffersCPU(); @@ -324,7 +324,7 @@ public: * @brief get all inputbuffers needed to calculate an chunk * @note all inputbuffers must be executed * @param chunkNumber the chunk to be calculated - * @return MemoryBuffer** the inputbuffers + * @return (MemoryBuffer **) the inputbuffers */ MemoryBuffer **getInputBuffersOpenCL(int chunkNumber); diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.h b/source/blender/compositor/intern/COM_ExecutionSystem.h index 4f6780c8d0b..ac849bf4f6c 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.h +++ b/source/blender/compositor/intern/COM_ExecutionSystem.h @@ -153,7 +153,7 @@ public: * @brief Create a new ExecutionSystem and initialize it with the * editingtree. * - * @param editingtree [bNodeTree*] + * @param editingtree [bNodeTree *] * @param rendering [true false] */ ExecutionSystem(RenderData *rd, bNodeTree *editingtree, bool rendering, bool fastcalculation); diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cpp b/source/blender/compositor/intern/COM_MemoryBuffer.cpp index 0aae8853795..3b8fbd6d708 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.cpp +++ b/source/blender/compositor/intern/COM_MemoryBuffer.cpp @@ -87,6 +87,44 @@ float *MemoryBuffer::convertToValueBuffer() return result; } +float MemoryBuffer::getMaximumValue() +{ + float result = this->m_buffer[0]; + const unsigned int size = this->determineBufferSize(); + unsigned int i; + + const float *fp_src = this->m_buffer; + + for (i = 0; i < size; i++, fp_src += COM_NUMBER_OF_CHANNELS) { + float value = *fp_src; + if (value > result) { + result = value; + } + } + + return result; +} + +float MemoryBuffer::getMaximumValue(rcti *rect) +{ + rcti rect_clamp; + + /* first clamp the rect by the bounds or we get un-initialized values */ + BLI_rcti_isect(rect, &this->m_rect, &rect_clamp); + + if (!BLI_rcti_is_empty(&rect_clamp)) { + MemoryBuffer *temp = new MemoryBuffer(NULL, &rect_clamp); + temp->copyContentFrom(this); + float result = temp->getMaximumValue(); + delete temp; + return result; + } + else { + BLI_assert(0); + return 0.0f; + } +} + MemoryBuffer::~MemoryBuffer() { if (this->m_buffer) { @@ -98,6 +136,7 @@ MemoryBuffer::~MemoryBuffer() void MemoryBuffer::copyContentFrom(MemoryBuffer *otherBuffer) { if (!otherBuffer) { + BLI_assert(0); return; } unsigned int otherY; @@ -209,7 +248,7 @@ static void imp2radangle(float A, float B, float C, float F, float *a, float *b, *b = sqrtf(F2 / d); *ecc = *a / *b; } - // incr theta by 0.5*pi (angle of major axis) + /* incr theta by 0.5 * pi (angle of major axis) */ *th = 0.5f * (atan2f(B, AmC) + (float)M_PI); } } diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h index 9abbfb163e2..f64603ed5d9 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.h +++ b/source/blender/compositor/intern/COM_MemoryBuffer.h @@ -202,6 +202,9 @@ public: /** * @brief add the content from otherBuffer to this MemoryBuffer * @param otherBuffer source buffer + * + * @note take care when running this on a new buffer since it wont fill in + * uninitialized values in areas where the buffers don't overlap. */ void copyContentFrom(MemoryBuffer *otherBuffer); @@ -228,6 +231,8 @@ public: MemoryBuffer *duplicate(); float *convertToValueBuffer(); + float getMaximumValue(); + float getMaximumValue(rcti *rect); private: unsigned int determineBufferSize(); diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h index 9b6d574e321..a9cf281b02f 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.h +++ b/source/blender/compositor/intern/COM_NodeOperation.h @@ -148,7 +148,7 @@ public: * @param memoryBuffers all input MemoryBuffer's needed * @param outputBuffer the outputbuffer to write to */ - virtual void executeOpenCLRegion(OpenCLDevice* device, rcti *rect, + virtual void executeOpenCLRegion(OpenCLDevice *device, rcti *rect, unsigned int chunkNumber, MemoryBuffer **memoryBuffers, MemoryBuffer *outputBuffer) {} /** @@ -163,7 +163,7 @@ public: * @param clMemToCleanUp all created cl_mem references must be added to this list. Framework will clean this after execution * @param clKernelsToCleanUp all created cl_kernel references must be added to this list. Framework will clean this after execution */ - virtual void executeOpenCL(OpenCLDevice* device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp) {} + virtual void executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp) {} virtual void deinitExecution(); bool isResolutionSet() { diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.cpp b/source/blender/compositor/intern/COM_OpenCLDevice.cpp index 63f75681779..be5936b495e 100644 --- a/source/blender/compositor/intern/COM_OpenCLDevice.cpp +++ b/source/blender/compositor/intern/COM_OpenCLDevice.cpp @@ -67,7 +67,7 @@ void OpenCLDevice::execute(WorkPackage *work) } cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex, list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers, SocketReader *reader) { - return COM_clAttachMemoryBufferToKernelParameter(kernel, parameterIndex, offsetIndex, cleanup, inputMemoryBuffers, (ReadBufferOperation*)reader); + return COM_clAttachMemoryBufferToKernelParameter(kernel, parameterIndex, offsetIndex, cleanup, inputMemoryBuffers, (ReadBufferOperation *)reader); } cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex, list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers, ReadBufferOperation *reader) @@ -106,7 +106,7 @@ void OpenCLDevice::COM_clAttachMemoryBufferOffsetToKernelParameter(cl_kernel ker } } -void OpenCLDevice::COM_clAttachSizeToKernelParameter(cl_kernel kernel, int offsetIndex, NodeOperation* operation) +void OpenCLDevice::COM_clAttachSizeToKernelParameter(cl_kernel kernel, int offsetIndex, NodeOperation *operation) { if (offsetIndex != -1) { cl_int error; @@ -133,7 +133,7 @@ void OpenCLDevice::COM_clEnqueueRange(cl_kernel kernel, MemoryBuffer *outputMemo if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } } -void OpenCLDevice::COM_clEnqueueRange(cl_kernel kernel, MemoryBuffer *outputMemoryBuffer, int offsetIndex, NodeOperation* operation) +void OpenCLDevice::COM_clEnqueueRange(cl_kernel kernel, MemoryBuffer *outputMemoryBuffer, int offsetIndex, NodeOperation *operation) { cl_int error; const int width = outputMemoryBuffer->getWidth(); diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.h b/source/blender/compositor/intern/COM_OpenCLDevice.h index f1a1e31c930..2021cacabcc 100644 --- a/source/blender/compositor/intern/COM_OpenCLDevice.h +++ b/source/blender/compositor/intern/COM_OpenCLDevice.h @@ -100,9 +100,9 @@ public: cl_mem COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex, list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers, ReadBufferOperation *reader); void COM_clAttachMemoryBufferOffsetToKernelParameter(cl_kernel kernel, int offsetIndex, MemoryBuffer *memoryBuffers); void COM_clAttachOutputMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, cl_mem clOutputMemoryBuffer); - void COM_clAttachSizeToKernelParameter(cl_kernel kernel, int offsetIndex, NodeOperation* operation); + void COM_clAttachSizeToKernelParameter(cl_kernel kernel, int offsetIndex, NodeOperation *operation); void COM_clEnqueueRange(cl_kernel kernel, MemoryBuffer *outputMemoryBuffer); - void COM_clEnqueueRange(cl_kernel kernel, MemoryBuffer *outputMemoryBuffer, int offsetIndex, NodeOperation* operation); + void COM_clEnqueueRange(cl_kernel kernel, MemoryBuffer *outputMemoryBuffer, int offsetIndex, NodeOperation *operation); cl_kernel COM_clCreateKernel(const char *kernelname, list<cl_kernel> *clKernelsToCleanUp); }; diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp index 7d4134aca13..849c4affd9c 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.cpp +++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp @@ -77,20 +77,20 @@ void ** g_highlightedNodesRead; #define HIGHLIGHT(wp) \ { \ - ExecutionGroup* group = wp->getExecutionGroup(); \ + ExecutionGroup *group = wp->getExecutionGroup(); \ if (group->isComplex()) { \ - NodeOperation* operation = group->getOutputNodeOperation(); \ - if (operation->isWriteBufferOperation()) {\ - WriteBufferOperation *writeOperation = (WriteBufferOperation*)operation;\ + NodeOperation *operation = group->getOutputNodeOperation(); \ + if (operation->isWriteBufferOperation()) { \ + WriteBufferOperation *writeOperation = (WriteBufferOperation *)operation; \ NodeOperation *complexOperation = writeOperation->getInput(); \ bNode *node = complexOperation->getbNode(); \ if (node) { \ if (node->original) { \ - node = node->original;\ - }\ - if (g_highlightIndex < MAX_HIGHLIGHT) {\ - g_highlightedNodes[g_highlightIndex++] = node;\ - }\ + node = node->original; \ + } \ + if (g_highlightIndex < MAX_HIGHLIGHT) { \ + g_highlightedNodes[g_highlightIndex++] = node; \ + } \ } \ } \ } \ @@ -103,18 +103,18 @@ void COM_startReadHighlights() } g_highlightedNodesRead = g_highlightedNodes; - g_highlightedNodes = new void*[MAX_HIGHLIGHT]; + g_highlightedNodes = new void *[MAX_HIGHLIGHT]; g_highlightIndex = 0; for (int i = 0 ; i < MAX_HIGHLIGHT; i++) { g_highlightedNodes[i] = 0; } } -int COM_isHighlightedbNode(bNode* bnode) +int COM_isHighlightedbNode(bNode *bnode) { if (!g_highlightedNodesRead) return false; for (int i = 0 ; i < MAX_HIGHLIGHT; i++) { - void* p = g_highlightedNodesRead[i]; + void *p = g_highlightedNodesRead[i]; if (!p) return false; if (p == bnode) return true; } diff --git a/source/blender/compositor/intern/COM_compositor.cpp b/source/blender/compositor/intern/COM_compositor.cpp index ab64f8f7bf1..2402f9a1163 100644 --- a/source/blender/compositor/intern/COM_compositor.cpp +++ b/source/blender/compositor/intern/COM_compositor.cpp @@ -54,7 +54,7 @@ void COM_execute(RenderData *rd, bNodeTree *editingtree, int rendering) } - /* set progress bar to 0% and status to init compositing*/ + /* set progress bar to 0% and status to init compositing */ editingtree->progress(editingtree->prh, 0.0); bool twopass = (editingtree->flag&NTREE_TWO_PASS) > 0 && !rendering; diff --git a/source/blender/compositor/nodes/COM_BilateralBlurNode.cpp b/source/blender/compositor/nodes/COM_BilateralBlurNode.cpp index 683093302c1..399d2adf0be 100644 --- a/source/blender/compositor/nodes/COM_BilateralBlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BilateralBlurNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_BilateralBlurNode.h" -#include "DNA_scene_types.h" #include "DNA_node_types.h" #include "COM_ExecutionSystem.h" #include "COM_BilateralBlurOperation.h" diff --git a/source/blender/compositor/nodes/COM_BlurNode.cpp b/source/blender/compositor/nodes/COM_BlurNode.cpp index 9b945887ec2..059b01e2c05 100644 --- a/source/blender/compositor/nodes/COM_BlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BlurNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_BlurNode.h" -#include "DNA_scene_types.h" #include "DNA_node_types.h" #include "COM_GaussianXBlurOperation.h" #include "COM_GaussianYBlurOperation.h" diff --git a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp index 300193da842..f45572fe4ae 100644 --- a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_BokehBlurNode.h" -#include "DNA_scene_types.h" #include "DNA_camera_types.h" #include "DNA_object_types.h" #include "DNA_node_types.h" diff --git a/source/blender/compositor/nodes/COM_BokehImageNode.cpp b/source/blender/compositor/nodes/COM_BokehImageNode.cpp index 75f5e07d552..f6abbbb9a9a 100644 --- a/source/blender/compositor/nodes/COM_BokehImageNode.cpp +++ b/source/blender/compositor/nodes/COM_BokehImageNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_BokehImageNode.h" -#include "DNA_scene_types.h" #include "COM_BokehImageOperation.h" #include "COM_ExecutionSystem.h" diff --git a/source/blender/compositor/nodes/COM_BoxMaskNode.cpp b/source/blender/compositor/nodes/COM_BoxMaskNode.cpp index 789ff265a5c..0580a32ed8c 100644 --- a/source/blender/compositor/nodes/COM_BoxMaskNode.cpp +++ b/source/blender/compositor/nodes/COM_BoxMaskNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_BoxMaskNode.h" -#include "DNA_scene_types.h" #include "COM_BoxMaskOperation.h" #include "COM_ExecutionSystem.h" diff --git a/source/blender/compositor/nodes/COM_BrightnessNode.cpp b/source/blender/compositor/nodes/COM_BrightnessNode.cpp index 1e1fbdbc301..cd230a23a5c 100644 --- a/source/blender/compositor/nodes/COM_BrightnessNode.cpp +++ b/source/blender/compositor/nodes/COM_BrightnessNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_BrightnessNode.h" -#include "DNA_scene_types.h" #include "COM_BrightnessOperation.h" #include "COM_ExecutionSystem.h" diff --git a/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp b/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp index 69f39639660..eab921863e9 100644 --- a/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp @@ -45,13 +45,13 @@ void ChannelMatteNode::convertToOperations(ExecutionSystem *graph, CompositorCon switch (node->custom1) { case CMP_NODE_CHANNEL_MATTE_CS_RGB: break; - case CMP_NODE_CHANNEL_MATTE_CS_HSV: /*HSV*/ + case CMP_NODE_CHANNEL_MATTE_CS_HSV: /* HSV */ convert = new ConvertRGBToHSVOperation(); break; - case CMP_NODE_CHANNEL_MATTE_CS_YUV: /*YUV*/ + case CMP_NODE_CHANNEL_MATTE_CS_YUV: /* YUV */ convert = new ConvertRGBToYUVOperation(); break; - case CMP_NODE_CHANNEL_MATTE_CS_YCC: /*YCC*/ + case CMP_NODE_CHANNEL_MATTE_CS_YCC: /* YCC */ convert = new ConvertRGBToYCCOperation(); ((ConvertRGBToYCCOperation *)convert)->setMode(0); /* BLI_YCC_ITU_BT601 */ break; diff --git a/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp b/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp index 41b3bebbd7b..a05abaf17d3 100644 --- a/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_ColorCorrectionNode.h" -#include "DNA_scene_types.h" #include "COM_ColorCorrectionOperation.h" #include "COM_ExecutionSystem.h" diff --git a/source/blender/compositor/nodes/COM_ColorCurveNode.cpp b/source/blender/compositor/nodes/COM_ColorCurveNode.cpp index 9ae11c22b6a..93ff304afd8 100644 --- a/source/blender/compositor/nodes/COM_ColorCurveNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorCurveNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_ColorCurveNode.h" -#include "DNA_scene_types.h" #include "COM_ColorCurveOperation.h" #include "COM_ExecutionSystem.h" diff --git a/source/blender/compositor/nodes/COM_ColorNode.cpp b/source/blender/compositor/nodes/COM_ColorNode.cpp index 65480c7aeb2..088f8bbb19d 100644 --- a/source/blender/compositor/nodes/COM_ColorNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_ColorNode.h" -#include "DNA_scene_types.h" #include "COM_SetColorOperation.h" #include "COM_ExecutionSystem.h" diff --git a/source/blender/compositor/nodes/COM_CompositorNode.cpp b/source/blender/compositor/nodes/COM_CompositorNode.cpp index 28e466203c4..d0d66a81c77 100644 --- a/source/blender/compositor/nodes/COM_CompositorNode.cpp +++ b/source/blender/compositor/nodes/COM_CompositorNode.cpp @@ -31,15 +31,19 @@ CompositorNode::CompositorNode(bNode *editorNode) : Node(editorNode) void CompositorNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { + bNode *editorNode = this->getbNode(); + InputSocket *imageSocket = this->getInputSocket(0); InputSocket *alphaSocket = this->getInputSocket(1); - if (imageSocket->isConnected()) { - CompositorOperation *colorAlphaProg = new CompositorOperation(); - colorAlphaProg->setRenderData(context->getRenderData()); - colorAlphaProg->setbNodeTree(context->getbNodeTree()); - imageSocket->relinkConnections(colorAlphaProg->getInputSocket(0)); - alphaSocket->relinkConnections(colorAlphaProg->getInputSocket(1)); - graph->addOperation(colorAlphaProg); - addPreviewOperation(graph, colorAlphaProg->getInputSocket(0)); - } + InputSocket *depthSocket = this->getInputSocket(2); + + CompositorOperation *compositorOperation = new CompositorOperation(); + compositorOperation->setSceneName(editorNode->id->name); + compositorOperation->setRenderData(context->getRenderData()); + compositorOperation->setbNodeTree(context->getbNodeTree()); + imageSocket->relinkConnections(compositorOperation->getInputSocket(0), 0, graph); + alphaSocket->relinkConnections(compositorOperation->getInputSocket(1)); + depthSocket->relinkConnections(compositorOperation->getInputSocket(2)); + graph->addOperation(compositorOperation); + addPreviewOperation(graph, compositorOperation->getInputSocket(0)); } diff --git a/source/blender/compositor/nodes/COM_DefocusNode.cpp b/source/blender/compositor/nodes/COM_DefocusNode.cpp index 65825a60b50..7354c4fcd65 100644 --- a/source/blender/compositor/nodes/COM_DefocusNode.cpp +++ b/source/blender/compositor/nodes/COM_DefocusNode.cpp @@ -105,7 +105,8 @@ void DefocusNode::convertToOperations(ExecutionSystem *graph, CompositorContext VariableSizeBokehBlurOperation *operation = new VariableSizeBokehBlurOperation(); if (data->preview) { operation->setQuality(COM_QUALITY_LOW); - } else { + } + else { operation->setQuality(context->getQuality()); } operation->setMaxBlur(data->maxblur); diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp index 043ae367fbb..cecc3bf6e86 100644 --- a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp +++ b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_DilateErodeNode.h" -#include "DNA_scene_types.h" #include "COM_ExecutionSystem.h" #include "COM_DilateErodeOperation.h" #include "COM_AntiAliasOperation.h" diff --git a/source/blender/compositor/nodes/COM_DirectionalBlurNode.cpp b/source/blender/compositor/nodes/COM_DirectionalBlurNode.cpp index 85fc63ae8cb..eb30f6952ba 100644 --- a/source/blender/compositor/nodes/COM_DirectionalBlurNode.cpp +++ b/source/blender/compositor/nodes/COM_DirectionalBlurNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_DirectionalBlurNode.h" -#include "DNA_scene_types.h" #include "DNA_node_types.h" #include "COM_ExecutionSystem.h" #include "COM_DirectionalBlurOperation.h" diff --git a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp index ab1d83385c7..40a9d1fa275 100644 --- a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp +++ b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp @@ -22,7 +22,6 @@ #include "COM_DoubleEdgeMaskNode.h" #include "COM_DoubleEdgeMaskOperation.h" -#include "DNA_scene_types.h" #include "COM_ExecutionSystem.h" DoubleEdgeMaskNode::DoubleEdgeMaskNode(bNode *editorNode) : Node(editorNode) diff --git a/source/blender/compositor/nodes/COM_EllipseMaskNode.cpp b/source/blender/compositor/nodes/COM_EllipseMaskNode.cpp index 23410c6a115..dc4421abb25 100644 --- a/source/blender/compositor/nodes/COM_EllipseMaskNode.cpp +++ b/source/blender/compositor/nodes/COM_EllipseMaskNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_EllipseMaskNode.h" -#include "DNA_scene_types.h" #include "COM_EllipseMaskOperation.h" #include "COM_ExecutionSystem.h" diff --git a/source/blender/compositor/nodes/COM_GammaNode.cpp b/source/blender/compositor/nodes/COM_GammaNode.cpp index 52699c83bf9..33a5cb282a1 100644 --- a/source/blender/compositor/nodes/COM_GammaNode.cpp +++ b/source/blender/compositor/nodes/COM_GammaNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_GammaNode.h" -#include "DNA_scene_types.h" #include "COM_GammaOperation.h" #include "COM_ExecutionSystem.h" diff --git a/source/blender/compositor/nodes/COM_IDMaskNode.cpp b/source/blender/compositor/nodes/COM_IDMaskNode.cpp index 31d2ccb391e..12a508c75f5 100644 --- a/source/blender/compositor/nodes/COM_IDMaskNode.cpp +++ b/source/blender/compositor/nodes/COM_IDMaskNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_IDMaskNode.h" -#include "DNA_scene_types.h" #include "COM_IDMaskOperation.h" #include "COM_ExecutionSystem.h" #include "COM_AntiAliasOperation.h" diff --git a/source/blender/compositor/nodes/COM_InvertNode.cpp b/source/blender/compositor/nodes/COM_InvertNode.cpp index c468bda1b67..9c4e28a2971 100644 --- a/source/blender/compositor/nodes/COM_InvertNode.cpp +++ b/source/blender/compositor/nodes/COM_InvertNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_InvertNode.h" -#include "DNA_scene_types.h" #include "COM_InvertOperation.h" #include "COM_ExecutionSystem.h" #include "BKE_node.h" diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp index efd50a44a51..6bc9afba32c 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.cpp +++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp @@ -30,6 +30,8 @@ #include "COM_KeyingDespillOperation.h" #include "COM_KeyingClipOperation.h" +#include "COM_MathBaseOperation.h" + #include "COM_SeparateChannelOperation.h" #include "COM_CombineChannelsOperation.h" #include "COM_ConvertRGBToYCCOperation.h" @@ -239,8 +241,6 @@ void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext * keyingOperation->setScreenBalance(keying_data->screen_balance); inputScreen->relinkConnections(keyingOperation->getInputSocket(1), 1, graph); - inputGarbageMatte->relinkConnections(keyingOperation->getInputSocket(2), 2, graph); - inputCoreMatte->relinkConnections(keyingOperation->getInputSocket(3), 3, graph); if (keying_data->blur_pre) { /* chroma preblur operation for input of keying operation */ @@ -256,18 +256,54 @@ void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext * postprocessedMatte = keyingOperation->getOutputSocket(); + /* black / white clipping */ if (keying_data->clip_black > 0.0f || keying_data->clip_white < 1.0f) { postprocessedMatte = setupClip(graph, postprocessedMatte, keying_data->edge_kernel_radius, keying_data->edge_kernel_tolerance, keying_data->clip_black, keying_data->clip_white, false); } + /* output edge matte */ if (outputEdges->isConnected()) { edgesMatte = setupClip(graph, postprocessedMatte, keying_data->edge_kernel_radius, keying_data->edge_kernel_tolerance, keying_data->clip_black, keying_data->clip_white, true); } + /* apply garbage matte */ + if (inputGarbageMatte->isConnected()) { + SetValueOperation *valueOperation = new SetValueOperation(); + MathSubtractOperation *subtractOperation = new MathSubtractOperation(); + MathMinimumOperation *minOperation = new MathMinimumOperation(); + + valueOperation->setValue(1.0f); + + addLink(graph, valueOperation->getOutputSocket(), subtractOperation->getInputSocket(0)); + inputGarbageMatte->relinkConnections(subtractOperation->getInputSocket(1), 0, graph); + + addLink(graph, subtractOperation->getOutputSocket(), minOperation->getInputSocket(0)); + addLink(graph, postprocessedMatte, minOperation->getInputSocket(1)); + + postprocessedMatte = minOperation->getOutputSocket(); + + graph->addOperation(valueOperation); + graph->addOperation(subtractOperation); + graph->addOperation(minOperation); + } + + /* apply core matte */ + if (inputCoreMatte->isConnected()) { + MathMaximumOperation *maxOperation = new MathMaximumOperation(); + + inputCoreMatte->relinkConnections(maxOperation->getInputSocket(0), 0, graph); + + addLink(graph, postprocessedMatte, maxOperation->getInputSocket(1)); + + postprocessedMatte = maxOperation->getOutputSocket(); + + graph->addOperation(maxOperation); + } + /* apply blur on matte if needed */ if (keying_data->blur_post) postprocessedMatte = setupPostBlur(graph, postprocessedMatte, keying_data->blur_post); diff --git a/source/blender/compositor/nodes/COM_LensDistortionNode.cpp b/source/blender/compositor/nodes/COM_LensDistortionNode.cpp index 3913b4ac2b6..94c2fc885fb 100644 --- a/source/blender/compositor/nodes/COM_LensDistortionNode.cpp +++ b/source/blender/compositor/nodes/COM_LensDistortionNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_LensDistortionNode.h" -#include "DNA_scene_types.h" #include "COM_ExecutionSystem.h" #include "COM_ProjectorLensDistortionOperation.h" #include "COM_ScreenLensDistortionOperation.h" diff --git a/source/blender/compositor/nodes/COM_MaskNode.cpp b/source/blender/compositor/nodes/COM_MaskNode.cpp index b6300300f6f..8d549d09362 100644 --- a/source/blender/compositor/nodes/COM_MaskNode.cpp +++ b/source/blender/compositor/nodes/COM_MaskNode.cpp @@ -36,18 +36,30 @@ MaskNode::MaskNode(bNode *editorNode) : Node(editorNode) void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { - const RenderData *data = context->getRenderData(); + const RenderData *rd = context->getRenderData(); OutputSocket *outputMask = this->getOutputSocket(0); bNode *editorNode = this->getbNode(); + NodeMask *data = (NodeMask *)editorNode->storage; Mask *mask = (Mask *)editorNode->id; // always connect the output image MaskOperation *operation = new MaskOperation(); operation->setbNode(editorNode); - operation->setMaskWidth(data->xsch * data->size / 100.0f); - operation->setMaskHeight(data->ysch * data->size / 100.0f); + + if (editorNode->custom1 & CMP_NODEFLAG_MASK_FIXED) { + operation->setMaskWidth(data->size_x); + operation->setMaskHeight(data->size_y); + } + else if (editorNode->custom1 & CMP_NODEFLAG_MASK_FIXED_SCENE) { + operation->setMaskWidth(data->size_x * (rd->size / 100.0f)); + operation->setMaskHeight(data->size_y * (rd->size / 100.0f)); + } + else { + operation->setMaskWidth(rd->xsch * rd->size / 100.0f); + operation->setMaskHeight(rd->ysch * rd->size / 100.0f); + } if (outputMask->isConnected()) { outputMask->relinkConnections(operation->getOutputSocket()); @@ -58,5 +70,13 @@ void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co operation->setSmooth((bool)(editorNode->custom1 & CMP_NODEFLAG_MASK_AA) != 0); operation->setFeather((bool)(editorNode->custom1 & CMP_NODEFLAG_MASK_NO_FEATHER) == 0); + if ((editorNode->custom1 & CMP_NODEFLAG_MASK_MOTION_BLUR) && + (editorNode->custom2 > 1) && + (editorNode->custom3 > FLT_EPSILON)) + { + operation->setMotionBlurSamples(editorNode->custom2); + operation->setMotionBlurShutter(editorNode->custom3); + } + graph->addOperation(operation); } diff --git a/source/blender/compositor/nodes/COM_MuteNode.cpp b/source/blender/compositor/nodes/COM_MuteNode.cpp index f52b7216cca..2c96473a556 100644 --- a/source/blender/compositor/nodes/COM_MuteNode.cpp +++ b/source/blender/compositor/nodes/COM_MuteNode.cpp @@ -20,14 +20,16 @@ * Monique Dewanchand */ -#include <stdio.h> - #include "COM_MuteNode.h" #include "COM_SocketConnection.h" #include "COM_SetValueOperation.h" #include "COM_SetVectorOperation.h" #include "COM_SetColorOperation.h" +extern "C" { + #include "BLI_listbase.h" +} + MuteNode::MuteNode(bNode *editorNode) : Node(editorNode) { /* pass */ @@ -45,7 +47,12 @@ void MuteNode::reconnect(ExecutionSystem *graph, OutputSocket *output) } } } - + + createDefaultOutput(graph, output); +} + +void MuteNode::createDefaultOutput(ExecutionSystem *graph, OutputSocket *output) +{ NodeOperation *operation = NULL; switch (output->getDataType()) { case COM_DT_VALUE: @@ -84,14 +91,59 @@ void MuteNode::reconnect(ExecutionSystem *graph, OutputSocket *output) output->clearConnections(); } +template<class SocketType> void MuteNode::fillSocketMap(vector<SocketType *> &sockets, SocketMap &socketMap) +{ + for (typename vector<SocketType *>::iterator it = sockets.begin(); it != sockets.end(); it++) { + Socket *socket = (Socket *) *it; + + socketMap.insert(std::pair<bNodeSocket *, Socket *>(socket->getbNodeSocket(), socket)); + } +} + void MuteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { + bNode *editorNode = this->getbNode(); vector<OutputSocket *> &outputsockets = this->getOutputSockets(); - for (unsigned int index = 0; index < outputsockets.size(); index++) { - OutputSocket *output = outputsockets[index]; - if (output->isConnected()) { - reconnect(graph, output); + /* mute node is also used for unknown nodes and couple of nodes in fast mode + * can't use generic routines in that case + */ + if ((editorNode->flag & NODE_MUTED) && editorNode->typeinfo->internal_connect) { + vector<InputSocket *> &inputsockets = this->getInputSockets(); + bNodeTree *editorTree = (bNodeTree *) context->getbNodeTree(); + SocketMap socketMap; + ListBase intlinks; + bNodeLink *link; + + intlinks = editorNode->typeinfo->internal_connect(editorTree, editorNode); + + this->fillSocketMap<OutputSocket>(outputsockets, socketMap); + this->fillSocketMap<InputSocket>(inputsockets, socketMap); + + for (link = (bNodeLink *) intlinks.first; link; link = link->next) { + if (link->fromnode == editorNode) { + InputSocket *fromSocket = (InputSocket *) socketMap.find(link->fromsock)->second; + OutputSocket *toSocket = (OutputSocket *) socketMap.find(link->tosock)->second; + + if (toSocket->isConnected()) { + if (fromSocket->isConnected()) { + toSocket->relinkConnections(fromSocket->getConnection()->getFromSocket(), false); + } + else { + createDefaultOutput(graph, toSocket); + } + } + } + } + + BLI_freelistN(&intlinks); + } + else { + for (unsigned int index = 0; index < outputsockets.size(); index++) { + OutputSocket *output = outputsockets[index]; + if (output->isConnected()) { + reconnect(graph, output); + } } } } diff --git a/source/blender/compositor/nodes/COM_MuteNode.h b/source/blender/compositor/nodes/COM_MuteNode.h index aab37e5f888..2e5250e625e 100644 --- a/source/blender/compositor/nodes/COM_MuteNode.h +++ b/source/blender/compositor/nodes/COM_MuteNode.h @@ -23,8 +23,14 @@ #ifndef _COM_MuteNode_h_ #define _COM_MuteNode_h_ +#include <map> + #include "COM_Node.h" +extern "C" { + #include "BKE_node.h" +} + /** * @brief MuteNode * @ingroup Node @@ -34,7 +40,12 @@ public: MuteNode(bNode *editorNode); void convertToOperations(ExecutionSystem *graph, CompositorContext *context); private: + typedef std::map<bNodeSocket *, Socket *> SocketMap; + void reconnect(ExecutionSystem *graph, OutputSocket *output); + void createDefaultOutput(ExecutionSystem *graph, OutputSocket *output); + + template<class SocketType> void fillSocketMap(vector<SocketType *> &sockets, SocketMap &socketMap); }; #endif diff --git a/source/blender/compositor/nodes/COM_ScaleNode.cpp b/source/blender/compositor/nodes/COM_ScaleNode.cpp index 95b048b6cad..c51782b77af 100644 --- a/source/blender/compositor/nodes/COM_ScaleNode.cpp +++ b/source/blender/compositor/nodes/COM_ScaleNode.cpp @@ -64,7 +64,7 @@ void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c break; case CMP_SCALE_RENDERPERCENT: { - const RenderData *data = context->getRenderData(); + const RenderData *rd = context->getRenderData(); ScaleFixedSizeOperation *operation = new ScaleFixedSizeOperation(); /* framing options */ @@ -72,8 +72,8 @@ void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c operation->setIsCrop((bnode->custom2 & CMP_SCALE_RENDERSIZE_FRAME_CROP) != 0); operation->setOffset(bnode->custom3, bnode->custom4); - operation->setNewWidth(data->xsch * data->size / 100.0f); - operation->setNewHeight(data->ysch * data->size / 100.0f); + operation->setNewWidth(rd->xsch * rd->size / 100.0f); + operation->setNewHeight(rd->ysch * rd->size / 100.0f); inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph); outputSocket->relinkConnections(operation->getOutputSocket(0)); operation->getInputSocket(0)->getConnection()->setIgnoreResizeCheck(true); diff --git a/source/blender/compositor/nodes/COM_TimeNode.cpp b/source/blender/compositor/nodes/COM_TimeNode.cpp index 8e155e375e1..84ee4e77b06 100644 --- a/source/blender/compositor/nodes/COM_TimeNode.cpp +++ b/source/blender/compositor/nodes/COM_TimeNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_TimeNode.h" -#include "DNA_scene_types.h" #include "COM_SetValueOperation.h" #include "COM_ExecutionSystem.h" extern "C" { diff --git a/source/blender/compositor/nodes/COM_TonemapNode.cpp b/source/blender/compositor/nodes/COM_TonemapNode.cpp index 68e322e9dcf..440e6b62414 100644 --- a/source/blender/compositor/nodes/COM_TonemapNode.cpp +++ b/source/blender/compositor/nodes/COM_TonemapNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_TonemapNode.h" -#include "DNA_scene_types.h" #include "COM_TonemapOperation.h" #include "COM_ExecutionSystem.h" diff --git a/source/blender/compositor/nodes/COM_TrackPositionNode.cpp b/source/blender/compositor/nodes/COM_TrackPositionNode.cpp index 243f63a0149..f4efcfe27f0 100644 --- a/source/blender/compositor/nodes/COM_TrackPositionNode.cpp +++ b/source/blender/compositor/nodes/COM_TrackPositionNode.cpp @@ -52,17 +52,20 @@ void TrackPositionNode::convertToOperations(ExecutionSystem *graph, CompositorCo operationX->setTrackName(trackpos_data->track_name); operationX->setFramenumber(context->getFramenumber()); operationX->setAxis(0); - operationX->setRelative(editorNode->custom1); + operationX->setPosition(editorNode->custom1); + operationX->setRelativeFrame(editorNode->custom2); operationY->setMovieClip(clip); operationY->setTrackingObject(trackpos_data->tracking_object); operationY->setTrackName(trackpos_data->track_name); operationY->setFramenumber(context->getFramenumber()); operationY->setAxis(1); - operationY->setRelative(editorNode->custom1); + operationY->setPosition(editorNode->custom1); + operationY->setRelativeFrame(editorNode->custom2); outputX->relinkConnections(operationX->getOutputSocket()); outputY->relinkConnections(operationY->getOutputSocket()); graph->addOperation(operationX); + graph->addOperation(operationY); } diff --git a/source/blender/compositor/nodes/COM_ValueNode.cpp b/source/blender/compositor/nodes/COM_ValueNode.cpp index 89b0602f8b0..593d74952ee 100644 --- a/source/blender/compositor/nodes/COM_ValueNode.cpp +++ b/source/blender/compositor/nodes/COM_ValueNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_ValueNode.h" -#include "DNA_scene_types.h" #include "COM_SetValueOperation.h" #include "COM_ExecutionSystem.h" diff --git a/source/blender/compositor/nodes/COM_VectorCurveNode.cpp b/source/blender/compositor/nodes/COM_VectorCurveNode.cpp index ee32c3b77a3..dcf1059ece6 100644 --- a/source/blender/compositor/nodes/COM_VectorCurveNode.cpp +++ b/source/blender/compositor/nodes/COM_VectorCurveNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_VectorCurveNode.h" -#include "DNA_scene_types.h" #include "COM_VectorCurveOperation.h" #include "COM_ExecutionSystem.h" diff --git a/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp b/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp index 309568c3aec..6bb873e0dec 100644 --- a/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp +++ b/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp @@ -21,7 +21,6 @@ */ #include "COM_ViewLevelsNode.h" -#include "DNA_scene_types.h" #include "COM_ExecutionSystem.h" #include "COM_CalculateMeanOperation.h" #include "COM_CalculateStandardDeviationOperation.h" diff --git a/source/blender/compositor/nodes/COM_ViewerNode.cpp b/source/blender/compositor/nodes/COM_ViewerNode.cpp index 1205767cb28..88ce0ff2016 100644 --- a/source/blender/compositor/nodes/COM_ViewerNode.cpp +++ b/source/blender/compositor/nodes/COM_ViewerNode.cpp @@ -35,23 +35,32 @@ void ViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext * { InputSocket *imageSocket = this->getInputSocket(0); InputSocket *alphaSocket = this->getInputSocket(1); + InputSocket *depthSocket = this->getInputSocket(2); Image *image = (Image *)this->getbNode()->id; ImageUser *imageUser = (ImageUser *) this->getbNode()->storage; bNode *editorNode = this->getbNode(); - if (imageSocket->isConnected()) { - ViewerOperation *viewerOperation = new ViewerOperation(); - viewerOperation->setColorManagement(context->getRenderData()->color_mgt_flag & R_COLOR_MANAGEMENT); - viewerOperation->setColorPredivide(context->getRenderData()->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); - viewerOperation->setbNodeTree(context->getbNodeTree()); - viewerOperation->setImage(image); - viewerOperation->setImageUser(imageUser); - viewerOperation->setActive((editorNode->flag & NODE_DO_OUTPUT) && this->isInActiveGroup()); - viewerOperation->setChunkOrder((OrderOfChunks)editorNode->custom1); - viewerOperation->setCenterX(editorNode->custom3); - viewerOperation->setCenterY(editorNode->custom4); - imageSocket->relinkConnections(viewerOperation->getInputSocket(0), 0, graph); - alphaSocket->relinkConnections(viewerOperation->getInputSocket(1)); - graph->addOperation(viewerOperation); - addPreviewOperation(graph, viewerOperation->getInputSocket(0)); + ViewerOperation *viewerOperation = new ViewerOperation(); + viewerOperation->setColorManagement(context->getRenderData()->color_mgt_flag & R_COLOR_MANAGEMENT); + viewerOperation->setColorPredivide(context->getRenderData()->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); + viewerOperation->setbNodeTree(context->getbNodeTree()); + viewerOperation->setImage(image); + viewerOperation->setImageUser(imageUser); + viewerOperation->setActive((editorNode->flag & NODE_DO_OUTPUT) && this->isInActiveGroup()); + viewerOperation->setChunkOrder((OrderOfChunks)editorNode->custom1); + viewerOperation->setCenterX(editorNode->custom3); + viewerOperation->setCenterY(editorNode->custom4); + + viewerOperation->setResolutionInputSocketIndex(0); + if (!imageSocket->isConnected()) + { + if (alphaSocket->isConnected()) { + viewerOperation->setResolutionInputSocketIndex(1); + } } + + imageSocket->relinkConnections(viewerOperation->getInputSocket(0), 0, graph); + alphaSocket->relinkConnections(viewerOperation->getInputSocket(1)); + depthSocket->relinkConnections(viewerOperation->getInputSocket(2)); + graph->addOperation(viewerOperation); + addPreviewOperation(graph, viewerOperation->getInputSocket(0)); } diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp index ef28d55dbc8..46c27496e9a 100644 --- a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp @@ -94,9 +94,14 @@ void BokehBlurOperation::executePixel(float *color, int x, int y, void *data) int bufferstartx = inputBuffer->getRect()->xmin; int bufferstarty = inputBuffer->getRect()->ymin; int pixelSize = this->m_size * this->getWidth() / 100.0f; - if (pixelSize==0) { - this->m_inputProgram->read(color, x, y, COM_PS_NEAREST); - return; + zero_v4(color_accum); + + if (pixelSize<2) { + this->m_inputProgram->read(color_accum, x, y, COM_PS_NEAREST); + multiplier_accum[0] = 1.0f; + multiplier_accum[1] = 1.0f; + multiplier_accum[2] = 1.0f; + multiplier_accum[3] = 1.0f; } int miny = y - pixelSize; int maxy = y + pixelSize; @@ -107,7 +112,6 @@ void BokehBlurOperation::executePixel(float *color, int x, int y, void *data) maxy = min(maxy, inputBuffer->getRect()->ymax); maxx = min(maxx, inputBuffer->getRect()->xmax); - zero_v4(color_accum); int step = getStep(); int offsetadd = getOffsetAdd(); @@ -152,7 +156,8 @@ bool BokehBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBuffe newInput.xmin = input->xmin - (this->m_size * this->getWidth() / 100.0f); newInput.ymax = input->ymax + (this->m_size * this->getWidth() / 100.0f); newInput.ymin = input->ymin - (this->m_size * this->getWidth() / 100.0f); - } else { + } + else { newInput.xmax = input->xmax + (10.0f * this->getWidth() / 100.0f); newInput.xmin = input->xmin - (10.0f * this->getWidth() / 100.0f); newInput.ymax = input->ymax + (10.0f * this->getWidth() / 100.0f); @@ -189,7 +194,7 @@ bool BokehBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBuffe return false; } -void BokehBlurOperation::executeOpenCL(OpenCLDevice* device, +void BokehBlurOperation::executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp) diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.h b/source/blender/compositor/operations/COM_BokehBlurOperation.h index eef5429c409..646587197a9 100644 --- a/source/blender/compositor/operations/COM_BokehBlurOperation.h +++ b/source/blender/compositor/operations/COM_BokehBlurOperation.h @@ -59,6 +59,6 @@ public: void setSize(float size) { this->m_size = size; this->m_sizeavailable = true; } - void executeOpenCL(OpenCLDevice* device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp); + void executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp); }; #endif diff --git a/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp b/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp index 85f606fafdf..e0e68f90289 100644 --- a/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp @@ -100,7 +100,7 @@ void ChannelMatteOperation::executePixel(float *outputValue, float x, float y, P /* flip because 0.0 is transparent, not 1.0 */ alpha = 1.0f - alpha; - /* test range*/ + /* test range */ if (alpha > limit_max) { alpha = inColor[3]; /*whatever it was prior */ } diff --git a/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp b/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp index 85a19d7c60f..4be03e9d914 100644 --- a/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp @@ -65,7 +65,7 @@ void ChromaMatteOperation::executePixel(float *outputValue, float x, float y, Pi */ /* Algorithm from book "Video Demistified," does not include the spill reduction part */ - /* find theta, the angle that the color space should be rotated based on key*/ + /* find theta, the angle that the color space should be rotated based on key */ theta = atan2(inKey[2], inKey[1]); /*rotate the cb and cr into x/z space */ diff --git a/source/blender/compositor/operations/COM_ColorMatteOperation.cpp b/source/blender/compositor/operations/COM_ColorMatteOperation.cpp index 5326e397494..26fbd99b43a 100644 --- a/source/blender/compositor/operations/COM_ColorMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorMatteOperation.cpp @@ -75,7 +75,7 @@ void ColorMatteOperation::executePixel(float *outputValue, float x, float y, Pix /* hue */ ((h_wrap = 2.f * fabsf(inColor[0] - inKey[0])) < hue || (2.f - h_wrap) < hue) ) { - outputValue[0] = 0.0f; /*make transparent*/ + outputValue[0] = 0.0f; /* make transparent */ } else { /*pixel is outside key color */ diff --git a/source/blender/compositor/operations/COM_CombineChannelsOperation.cpp b/source/blender/compositor/operations/COM_CombineChannelsOperation.cpp index d05040c4c12..354fe51c068 100644 --- a/source/blender/compositor/operations/COM_CombineChannelsOperation.cpp +++ b/source/blender/compositor/operations/COM_CombineChannelsOperation.cpp @@ -50,7 +50,8 @@ bool CombineChannelsOperation::determineDependingAreaOfInterest(rcti *input, Rea output->xmax = tempOutput.xmax; output->ymax = tempOutput.ymax; first = false; - } else { + } + else { output->xmin = MIN2(output->xmin, tempOutput.xmin); output->ymin = MIN2(output->ymin, tempOutput.ymin); output->xmax = MAX2(output->xmax, tempOutput.xmax); diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp index 43aad4f19d9..cba8c753d6a 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.cpp +++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp @@ -23,7 +23,6 @@ #include "COM_CompositorOperation.h" #include "COM_SocketConnection.h" #include "BLI_listbase.h" -#include "DNA_scene_types.h" #include "BKE_image.h" extern "C" { @@ -41,11 +40,16 @@ CompositorOperation::CompositorOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); this->setRenderData(NULL); this->m_outputBuffer = NULL; + this->m_depthBuffer = NULL; this->m_imageInput = NULL; this->m_alphaInput = NULL; + this->m_depthInput = NULL; + + this->m_sceneName[0] = '\0'; } void CompositorOperation::initExecution() @@ -53,16 +57,19 @@ void CompositorOperation::initExecution() // When initializing the tree during initial load the width and height can be zero. this->m_imageInput = getInputSocketReader(0); this->m_alphaInput = getInputSocketReader(1); + this->m_depthInput = getInputSocketReader(2); if (this->getWidth() * this->getHeight() != 0) { this->m_outputBuffer = (float *) MEM_callocN(this->getWidth() * this->getHeight() * 4 * sizeof(float), "CompositorOperation"); } + if (this->m_depthInput != NULL) { + this->m_depthBuffer = (float *) MEM_callocN(this->getWidth() * this->getHeight() * sizeof(float), "CompositorOperation"); + } } void CompositorOperation::deinitExecution() { if (!isBreaked()) { - const RenderData *rd = this->m_rd; - Render *re = RE_GetRender_FromData(rd); + Render *re = RE_GetRender(this->m_sceneName); RenderResult *rr = RE_AcquireResultWrite(re); if (rr) { @@ -70,11 +77,18 @@ void CompositorOperation::deinitExecution() MEM_freeN(rr->rectf); } rr->rectf = this->m_outputBuffer; + if (rr->rectz != NULL) { + MEM_freeN(rr->rectz); + } + rr->rectz = this->m_depthBuffer; } else { if (this->m_outputBuffer) { MEM_freeN(this->m_outputBuffer); } + if (this->m_depthBuffer) { + MEM_freeN(this->m_depthBuffer); + } } BLI_lock_thread(LOCK_DRAW_IMAGE); @@ -90,11 +104,16 @@ void CompositorOperation::deinitExecution() if (this->m_outputBuffer) { MEM_freeN(this->m_outputBuffer); } + if (this->m_depthBuffer) { + MEM_freeN(this->m_depthBuffer); + } } this->m_outputBuffer = NULL; + this->m_depthBuffer = NULL; this->m_imageInput = NULL; this->m_alphaInput = NULL; + this->m_depthInput = NULL; } @@ -102,13 +121,16 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber) { float color[8]; // 7 is enough float *buffer = this->m_outputBuffer; + float *zbuffer = this->m_depthBuffer; if (!buffer) return; int x1 = rect->xmin; int y1 = rect->ymin; int x2 = rect->xmax; int y2 = rect->ymax; - int offset = (y1 * this->getWidth() + x1) * COM_NUMBER_OF_CHANNELS; + int offset = (y1 * this->getWidth() + x1); + int add = (this->getWidth() - (x2 - x1)); + int offset4 = offset * COM_NUMBER_OF_CHANNELS; int x; int y; bool breaked = false; @@ -119,13 +141,20 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber) if (this->m_alphaInput != NULL) { this->m_alphaInput->read(&(color[3]), x, y, COM_PS_NEAREST); } - copy_v4_v4(buffer + offset, color); - offset += COM_NUMBER_OF_CHANNELS; + copy_v4_v4(buffer + offset4, color); + + if (this->m_depthInput != NULL) { + this->m_depthInput->read(color, x, y, COM_PS_NEAREST); + zbuffer[offset] = color[0]; + } + offset4 += COM_NUMBER_OF_CHANNELS; + offset++; if (isBreaked()) { breaked = true; } } - offset += (this->getWidth() - (x2 - x1)) * COM_NUMBER_OF_CHANNELS; + offset += add; + offset4 += add * COM_NUMBER_OF_CHANNELS; } } @@ -136,7 +165,7 @@ void CompositorOperation::determineResolution(unsigned int resolution[], unsigne // check actual render resolution with cropping it may differ with cropped border.rendering // FIX for: [31777] Border Crop gives black (easy) - Render *re = RE_GetRender_FromData(this->m_rd); + Render *re = RE_GetRender(this->m_sceneName); if (re) { RenderResult *rr = RE_AcquireResultRead(re); if (rr) { diff --git a/source/blender/compositor/operations/COM_CompositorOperation.h b/source/blender/compositor/operations/COM_CompositorOperation.h index 23d34abbfff..882e50b4922 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.h +++ b/source/blender/compositor/operations/COM_CompositorOperation.h @@ -23,14 +23,16 @@ #ifndef _COM_CompositorOperation_h #define _COM_CompositorOperation_h #include "COM_NodeOperation.h" -#include "DNA_scene_types.h" #include "BLI_rect.h" +#include "BLI_string.h" /** * @brief Compositor output operation */ class CompositorOperation : public NodeOperation { private: + char m_sceneName[MAX_ID_NAME]; + /** * @brief local reference to the scene */ @@ -42,6 +44,11 @@ private: float *m_outputBuffer; /** + * @brief reference to the output depth float buffer + */ + float *m_depthBuffer; + + /** * @brief local reference to the input image operation */ SocketReader *m_imageInput; @@ -50,9 +57,15 @@ private: * @brief local reference to the input alpha operation */ SocketReader *m_alphaInput; + + /** + * @brief local reference to the depth operation + */ + SocketReader *m_depthInput; public: CompositorOperation(); void executeRegion(rcti *rect, unsigned int tileNumber); + void setSceneName(const char *sceneName) { BLI_strncpy(this->m_sceneName, sceneName, sizeof(this->m_sceneName)); } void setRenderData(const RenderData *rd) { this->m_rd = rd; } bool isOutputOperation(bool rendering) const { return true; } void initExecution(); diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp index 80416bbccdf..e3f95eac3b4 100644 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp @@ -71,7 +71,7 @@ void ConvertDepthToRadiusOperation::initExecution() this->m_dof_sp = (float)minsz / (16.f / this->m_cam_lens); // <- == aspect * MIN2(img->x, img->y) / tan(0.5f * fov); if (this->m_blurPostOperation) { - m_blurPostOperation->setSigma(m_aperture*128.0f); + m_blurPostOperation->setSigma(m_aperture * 128.0f); } } @@ -87,9 +87,9 @@ void ConvertDepthToRadiusOperation::executePixel(float *outputValue, float x, fl // bug #6656 part 2b, do not rescale #if 0 - bcrad = 0.5f*fabs(aperture*(dof_sp*(cam_invfdist - iZ) - 1.f)); + bcrad = 0.5f * fabs(aperture * (dof_sp * (cam_invfdist - iZ) - 1.0f)); // scale crad back to original maximum and blend - crad->rect[px] = bcrad + wts->rect[px]*(scf*crad->rect[px] - bcrad); + crad->rect[px] = bcrad + wts->rect[px] * (scf * crad->rect[px] - bcrad); #endif radius = 0.5f * fabsf(this->m_aperture * (this->m_dof_sp * (this->m_inverseFocalDistance - iZ) - 1.f)); // 'bug' #6615, limit minimum radius to 1 pixel, not really a solution, but somewhat mitigates the problem diff --git a/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp b/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp index ed3799fff5e..a95d1eec290 100644 --- a/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp @@ -64,7 +64,7 @@ void DifferenceMatteOperation::executePixel(float *outputValue, float x, float y /* average together the distances */ difference = difference / 3.0f; - /*make 100% transparent*/ + /* make 100% transparent */ if (difference < tolerance) { outputValue[0] = 0.0f; } @@ -81,7 +81,7 @@ void DifferenceMatteOperation::executePixel(float *outputValue, float x, float y } } else { - /*foreground object*/ + /* foreground object */ outputValue[0] = inColor1[3]; } } diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp index 71be94bf2a7..0890bc75049 100644 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp @@ -234,7 +234,7 @@ bool DilateDistanceOperation::determineDependingAreaOfInterest(rcti *input, Read return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } -void DilateDistanceOperation::executeOpenCL(OpenCLDevice* device, +void DilateDistanceOperation::executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp) @@ -291,7 +291,7 @@ void ErodeDistanceOperation::executePixel(float *color, int x, int y, void *data color[0] = value; } -void ErodeDistanceOperation::executeOpenCL(OpenCLDevice* device, +void ErodeDistanceOperation::executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp) @@ -384,7 +384,7 @@ void DilateStepOperation::deinitExecution() this->m_inputProgram = NULL; this->deinitMutex(); if (this->m_cached_buffer) { - delete this->m_cached_buffer; + delete [] this->m_cached_buffer; this->m_cached_buffer = NULL; } } diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.h b/source/blender/compositor/operations/COM_DilateErodeOperation.h index 8c3eefb97e4..bd044e79fbe 100644 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.h +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.h @@ -99,7 +99,7 @@ public: void setDistance(float distance) { this->m_distance = distance; } bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - void executeOpenCL(OpenCLDevice* device, + void executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp); @@ -113,7 +113,7 @@ public: */ void executePixel(float *color, int x, int y, void *data); - void executeOpenCL(OpenCLDevice* device, + void executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp); diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp index 5e6ff2c7da1..34bf9db77ce 100644 --- a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp @@ -101,7 +101,7 @@ void DirectionalBlurOperation::executePixel(float *color, int x, int y, void *da mul_v4_v4fl(color, col2, 1.0f / (iterations+1)); } -void DirectionalBlurOperation::executeOpenCL(OpenCLDevice* device, +void DirectionalBlurOperation::executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp) diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.h b/source/blender/compositor/operations/COM_DirectionalBlurOperation.h index cc49e947f95..4de435a1418 100644 --- a/source/blender/compositor/operations/COM_DirectionalBlurOperation.h +++ b/source/blender/compositor/operations/COM_DirectionalBlurOperation.h @@ -56,7 +56,7 @@ public: void setData(NodeDBlurData *data) { this->m_data = data; } - void executeOpenCL(OpenCLDevice* device, + void executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp); diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp index f647629815b..847e5817675 100644 --- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp @@ -907,7 +907,7 @@ static void do_createEdgeLocationBuffer(unsigned int t, unsigned int rw, unsigne * or outer edge. * * Allocation is done by requesting 4 bytes "sizeof(int)" per pixel, even - * though gbuf[] is declared as unsigned short* (2 bytes) because we don't + * though gbuf[] is declared as (unsigned short *) (2 bytes) because we don't * store the pixel indexes, we only store x,y location of pixel in buffer. * * This does make the assumption that x and y can fit in 16 unsigned bits @@ -1273,8 +1273,8 @@ void *DoubleEdgeMaskOperation::initializeTileData(rcti *rect) float *imask = innerMask->convertToValueBuffer(); float *omask = outerMask->convertToValueBuffer(); doDoubleEdgeMask(imask, omask, data); - delete imask; - delete omask; + delete [] imask; + delete [] omask; this->m_cachedInstance = data; } unlockMutex(); @@ -1282,12 +1282,9 @@ void *DoubleEdgeMaskOperation::initializeTileData(rcti *rect) } void DoubleEdgeMaskOperation::executePixel(float *color, int x, int y, void *data) { - float *buffer = (float *) data; + float *buffer = (float *)data; int index = (y * this->getWidth() + x); - color[0] = buffer[index]; - color[1] = buffer[index + 1]; - color[2] = buffer[index + 2]; - color[3] = buffer[index + 3]; + copy_v4_v4(color, buffer + index); } void DoubleEdgeMaskOperation::deinitExecution() diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp index fd70d0d329a..74043e187bc 100644 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp @@ -257,14 +257,14 @@ void GaussianBlurReferenceOperation::updateGauss() { int i; int x = MAX2(m_radx, m_rady); - this->m_maintabs = (float**)MEM_mallocN(x * sizeof(float *), "gauss array"); + this->m_maintabs = (float **)MEM_mallocN(x * sizeof(float *), "gauss array"); for (i = 0; i < x; i++) m_maintabs[i] = make_gausstab(i + 1); } void GaussianBlurReferenceOperation::executePixel(float *color, int x, int y, void *data) { - MemoryBuffer *memorybuffer = (MemoryBuffer*)data; + MemoryBuffer *memorybuffer = (MemoryBuffer *)data; float *buffer = memorybuffer->getBuffer(); float *gausstabx, *gausstabcenty; float *gausstaby, *gausstabcentx; @@ -286,7 +286,8 @@ void GaussianBlurReferenceOperation::executePixel(float *color, int x, int y, vo if (refradx == 1 && refrady == 1) { memorybuffer->readNoCheck(color, x, y); - } else { + } + else { int minxr = x - refradx < 0 ? -x : -refradx; int maxxr = x + refradx > imgx ? imgx - x : refradx; int minyr = y - refrady < 0 ? -y : -refrady; diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp index 5452e779968..7f7429bf2e6 100644 --- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp @@ -260,6 +260,7 @@ void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2) float *imageBuffer = in1->getBuffer(); MemoryBuffer *rdst = new MemoryBuffer(NULL, in1->getRect()); + memset(rdst->getBuffer(), 0, rdst->getWidth() * rdst->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float)); // convolution result width & height w2 = 2 * kernelWidth - 1; diff --git a/source/blender/compositor/operations/COM_ImageOperation.cpp b/source/blender/compositor/operations/COM_ImageOperation.cpp index 729b3f8f18f..36cc6ca8d6d 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.cpp +++ b/source/blender/compositor/operations/COM_ImageOperation.cpp @@ -23,7 +23,6 @@ #include "COM_ImageOperation.h" #include "BLI_listbase.h" -#include "DNA_scene_types.h" #include "DNA_image_types.h" #include "BKE_image.h" #include "BLI_math.h" diff --git a/source/blender/compositor/operations/COM_ImageOperation.h b/source/blender/compositor/operations/COM_ImageOperation.h index 847096c7d43..ed7b10cd4f5 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.h +++ b/source/blender/compositor/operations/COM_ImageOperation.h @@ -25,7 +25,6 @@ #define _COM_ImageOperation_h #include "COM_NodeOperation.h" -#include "DNA_scene_types.h" #include "BLI_listbase.h" #include "BKE_image.h" extern "C" { diff --git a/source/blender/compositor/operations/COM_KeyingOperation.cpp b/source/blender/compositor/operations/COM_KeyingOperation.cpp index 5912c206a84..ed9e4f1df16 100644 --- a/source/blender/compositor/operations/COM_KeyingOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingOperation.cpp @@ -57,45 +57,33 @@ KeyingOperation::KeyingOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_COLOR); - this->addInputSocket(COM_DT_VALUE); - this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); this->m_screenBalance = 0.5f; this->m_pixelReader = NULL; this->m_screenReader = NULL; - this->m_garbageReader = NULL; - this->m_coreReader = NULL; } void KeyingOperation::initExecution() { this->m_pixelReader = this->getInputSocketReader(0); this->m_screenReader = this->getInputSocketReader(1); - this->m_garbageReader = this->getInputSocketReader(2); - this->m_coreReader = this->getInputSocketReader(3); } void KeyingOperation::deinitExecution() { this->m_pixelReader = NULL; this->m_screenReader = NULL; - this->m_garbageReader = NULL; - this->m_coreReader = NULL; } void KeyingOperation::executePixel(float *color, float x, float y, PixelSampler sampler) { float pixelColor[4]; float screenColor[4]; - float garbageValue[4]; - float coreValue[4]; this->m_pixelReader->read(pixelColor, x, y, sampler); this->m_screenReader->read(screenColor, x, y, sampler); - this->m_garbageReader->read(garbageValue, x, y, sampler); - this->m_coreReader->read(coreValue, x, y, sampler); int primary_channel = get_pixel_primary_channel(screenColor); @@ -130,10 +118,4 @@ void KeyingOperation::executePixel(float *color, float x, float y, PixelSampler color[0] = distance; } } - - /* apply garbage matte */ - color[0] = MIN2(color[0], 1.0f - garbageValue[0]); - - /* apply core matte */ - color[0] = MAX2(color[0], coreValue[0]); } diff --git a/source/blender/compositor/operations/COM_KeyingOperation.h b/source/blender/compositor/operations/COM_KeyingOperation.h index 413aaf6a81e..5ca4db7fc75 100644 --- a/source/blender/compositor/operations/COM_KeyingOperation.h +++ b/source/blender/compositor/operations/COM_KeyingOperation.h @@ -38,8 +38,6 @@ class KeyingOperation : public NodeOperation { protected: SocketReader *m_pixelReader; SocketReader *m_screenReader; - SocketReader *m_garbageReader; - SocketReader *m_coreReader; float m_screenBalance; diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp index 87a8fd22758..050aa3391d5 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp @@ -29,8 +29,6 @@ #include "BLI_math.h" #include "BLI_math_color.h" -#include "DNA_scene_types.h" - extern "C" { #include "BKE_movieclip.h" #include "BKE_tracking.h" @@ -80,7 +78,7 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri TriangulationData *triangulation; MovieTracking *tracking = &this->m_movieClip->tracking; MovieTrackingTrack *track; - VoronoiSite *sites; + VoronoiSite *sites, *site; ImBuf *ibuf; ListBase *tracksbase; ListBase edges = {NULL, NULL}; @@ -133,9 +131,8 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri sites = (VoronoiSite *) MEM_callocN(sizeof(VoronoiSite) * sites_total, "keyingscreen voronoi sites"); track = (MovieTrackingTrack *) tracksbase->first; - for (track = (MovieTrackingTrack *) tracksbase->first, i = 0; track; track = track->next, i++) { + for (track = (MovieTrackingTrack *) tracksbase->first, site = sites; track; track = track->next) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, clip_frame); - VoronoiSite *site; ImBuf *pattern_ibuf; int j; float pos[2]; @@ -151,8 +148,6 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri continue; } - site = &sites[i]; - pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, TRUE, FALSE); zero_v3(site->color); @@ -174,6 +169,8 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri site->co[0] = pos[0] * width; site->co[1] = pos[1] * height; + + site++; } IMB_freeImBuf(ibuf); diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.h b/source/blender/compositor/operations/COM_KeyingScreenOperation.h index f6982ef09f3..04e47e6e77f 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.h +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.h @@ -29,7 +29,6 @@ #include "COM_NodeOperation.h" -#include "DNA_scene_types.h" #include "DNA_movieclip_types.h" #include "BLI_listbase.h" diff --git a/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp b/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp index 7f637c127c1..31aae18992b 100644 --- a/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp @@ -55,7 +55,7 @@ void LuminanceMatteOperation::executePixel(float *outputValue, float x, float y, * outputValue[0] = max(inputValue[3], min(high, max(low, ((inColor[0]-low)/(high-low)))) */ - /* test range*/ + /* test range */ if (inColor[0] > high) { alpha = 1.f; } diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp index c648f3e6f08..1812b7372bb 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.cpp +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -28,12 +28,8 @@ #include "BLI_listbase.h" #include "BLI_math.h" -#include "DNA_scene_types.h" - -#ifdef USE_RASKTER - extern "C" { - #include "../../../../intern/raskter/raskter.h" + #include "BKE_mask.h" } MaskOperation::MaskOperation() : NodeOperation() @@ -42,124 +38,74 @@ MaskOperation::MaskOperation() : NodeOperation() this->m_mask = NULL; this->m_maskWidth = 0; this->m_maskHeight = 0; - this->m_framenumber = 0; - this->m_rasterizedMask = NULL; - setComplex(true); + this->m_maskWidthInv = 0.0f; + this->m_maskHeightInv = 0.0f; + this->m_frame_shutter = 0.0f; + this->m_frame_number = 0; + this->m_rasterMaskHandleTot = 1; + memset(this->m_rasterMaskHandles, 0, sizeof(this->m_rasterMaskHandles)); } void MaskOperation::initExecution() { - initMutex(); - - this->m_rasterizedMask = NULL; - this->m_maskLayers.first = this->m_maskLayers.last = NULL; - - if (this->m_mask) { - BKE_mask_layer_copy_list(&this->m_maskLayers, &this->m_mask->masklayers); - } -} - -void MaskOperation::deinitExecution() -{ - BKE_mask_layer_free_list(&this->m_maskLayers); - - if (this->m_rasterizedMask) { - MEM_freeN(this->m_rasterizedMask); - this->m_rasterizedMask = NULL; - } -} - -void *MaskOperation::initializeTileData(rcti *rect) -{ - if (this->m_rasterizedMask) - return this->m_rasterizedMask; - - if (!this->m_mask) - return NULL; + if (this->m_mask && this->m_rasterMaskHandles[0] == NULL) { + if (this->m_rasterMaskHandleTot == 1) { + this->m_rasterMaskHandles[0] = BKE_maskrasterize_handle_new(); - lockMutex(); - if (this->m_rasterizedMask == NULL) { - int width = this->getWidth(); - int height = this->getHeight(); - float *buffer; - - buffer = (float *)MEM_callocN(sizeof(float) * width * height, "rasterized mask"); - - BKE_mask_rasterize_layers(&this->m_maskLayers, width, height, buffer, TRUE, - this->m_do_smooth, this->m_do_feather); - - if (this->m_do_smooth) { - PLX_antialias_buffer(buffer, width, height); + BKE_maskrasterize_handle_init(this->m_rasterMaskHandles[0], this->m_mask, + this->m_maskWidth, this->m_maskHeight, + TRUE, this->m_do_smooth, this->m_do_feather); } + else { + /* make a throw away copy of the mask */ + const float frame = (float)this->m_frame_number - this->m_frame_shutter; + const float frame_step = (this->m_frame_shutter * 2.0f) / this->m_rasterMaskHandleTot; + float frame_iter = frame; - this->m_rasterizedMask = buffer; - } - unlockMutex(); - return this->m_rasterizedMask; -} - -void MaskOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) -{ - if (this->m_maskWidth == 0 || this->m_maskHeight == 0) { - NodeOperation::determineResolution(resolution, preferredResolution); - } - else { - unsigned int nr[2]; - - nr[0] = this->m_maskWidth; - nr[1] = this->m_maskHeight; - - NodeOperation::determineResolution(resolution, nr); + Mask *mask_temp; - resolution[0] = this->m_maskWidth; - resolution[1] = this->m_maskHeight; - } -} + mask_temp = BKE_mask_copy_nolib(this->m_mask); -void MaskOperation::executePixel(float *color, int x, int y, void *data) -{ - if (!data) { - color[0] = 0.0f; - } - else { - float *buffer = (float *) data; - int index = (y * this->getWidth() + x); + /* trick so we can get unkeyed edits to display */ + { + MaskLayer *masklay; + MaskLayerShape *masklay_shape; - color[0] = buffer[index]; - } -} + for (masklay = (MaskLayer *)mask_temp->masklayers.first; + masklay; + masklay = (MaskLayer *)masklay->next) + { + masklay_shape = BKE_mask_layer_shape_varify_frame(masklay, this->m_frame_number); + BKE_mask_layer_shape_from_mask(masklay, masklay_shape); + } + } -#else /* mask rasterizer by campbell wip */ + for (unsigned int i = 0; i < this->m_rasterMaskHandleTot; i++) { + this->m_rasterMaskHandles[i] = BKE_maskrasterize_handle_new(); -MaskOperation::MaskOperation() : NodeOperation() -{ - this->addOutputSocket(COM_DT_VALUE); - this->m_mask = NULL; - this->m_maskWidth = 0; - this->m_maskHeight = 0; - this->m_framenumber = 0; - this->m_rasterMaskHandle = NULL; -} + /* re-eval frame info */ + BKE_mask_evaluate(mask_temp, frame_iter, TRUE); -void MaskOperation::initExecution() -{ - if (this->m_mask) { - if (this->m_rasterMaskHandle == NULL) { - const int width = this->getWidth(); - const int height = this->getHeight(); + BKE_maskrasterize_handle_init(this->m_rasterMaskHandles[i], mask_temp, + this->m_maskWidth, this->m_maskHeight, + TRUE, this->m_do_smooth, this->m_do_feather); - this->m_rasterMaskHandle = BKE_maskrasterize_handle_new(); + frame_iter += frame_step; + } - BKE_maskrasterize_handle_init(this->m_rasterMaskHandle, this->m_mask, width, height, TRUE, this->m_do_smooth, this->m_do_feather); + BKE_mask_free(mask_temp); + MEM_freeN(mask_temp); } } } void MaskOperation::deinitExecution() { - if (this->m_rasterMaskHandle) { - BKE_maskrasterize_handle_free(this->m_rasterMaskHandle); - this->m_rasterMaskHandle = NULL; + for (unsigned int i = 0; i < this->m_rasterMaskHandleTot; i++) { + if (this->m_rasterMaskHandles[i]) { + BKE_maskrasterize_handle_free(this->m_rasterMaskHandles[i]); + this->m_rasterMaskHandles[i] = NULL; + } } } @@ -183,13 +129,27 @@ void MaskOperation::determineResolution(unsigned int resolution[], unsigned int void MaskOperation::executePixel(float *color, float x, float y, PixelSampler sampler) { - const float xy[2] = {x / (float)this->m_maskWidth, y / (float)this->m_maskHeight}; - if (this->m_rasterMaskHandle) { - color[0] = BKE_maskrasterize_handle_sample(this->m_rasterMaskHandle, xy); + const float xy[2] = {x * this->m_maskWidthInv, y * this->m_maskHeightInv}; + + if (this->m_rasterMaskHandleTot == 1) { + if (this->m_rasterMaskHandles[0]) { + color[0] = BKE_maskrasterize_handle_sample(this->m_rasterMaskHandles[0], xy); + } + else { + color[0] = 0.0f; + } } else { + /* incase loop below fails */ color[0] = 0.0f; + + for (unsigned int i = 0; i < this->m_rasterMaskHandleTot; i++) { + if (this->m_rasterMaskHandles[i]) { + color[0] += BKE_maskrasterize_handle_sample(this->m_rasterMaskHandles[i], xy); + } + } + + /* until we get better falloff */ + color[0] /= this->m_rasterMaskHandleTot; } } - -#endif /* USE_RASKTER */ diff --git a/source/blender/compositor/operations/COM_MaskOperation.h b/source/blender/compositor/operations/COM_MaskOperation.h index f367298b3d6..6e1735bcf9d 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.h +++ b/source/blender/compositor/operations/COM_MaskOperation.h @@ -21,45 +21,37 @@ * Sergey Sharybin */ - #ifndef _COM_MaskOperation_h #define _COM_MaskOperation_h -/* XXX, remove when the USE_RASKTER option is also removed */ -extern "C" { - #include "BKE_mask.h" -} #include "COM_NodeOperation.h" -#include "DNA_scene_types.h" #include "DNA_mask_types.h" #include "BLI_listbase.h" #include "IMB_imbuf_types.h" -#ifdef __PLX_RASKTER_MT__ -#include "../../../../intern/raskter/raskter.h" -#endif - /** * Class with implementation of mask rasterization */ class MaskOperation : public NodeOperation { protected: Mask *m_mask; - int m_maskWidth; - int m_maskHeight; - int m_framenumber; + + /* note, these are used more like aspect, + * but they _do_ impact on mask detail */ + int m_maskWidth; + int m_maskHeight; + float m_maskWidthInv; /* 1 / m_maskWidth */ + float m_maskHeightInv; /* 1 / m_maskHeight */ + + float m_frame_shutter; + int m_frame_number; + bool m_do_smooth; bool m_do_feather; -#ifdef USE_RASKTER - float *m_rasterizedMask; - - ListBase m_maskLayers; - -#else /* USE_RASKTER */ - struct MaskRasterHandle *m_rasterMaskHandle; -#endif /* USE_RASKTER */ + struct MaskRasterHandle *m_rasterMaskHandles[CMP_NODE_MASK_MBLUR_SAMPLES_MAX]; + unsigned int m_rasterMaskHandleTot; /** * Determine the output resolution. The resolution is retrieved from the Renderer @@ -74,18 +66,24 @@ public: void setMask(Mask *mask) { this->m_mask = mask; } - void setMaskWidth(int width) { this->m_maskWidth = width; } - void setMaskHeight(int height) { this->m_maskHeight = height; } - void setFramenumber(int framenumber) { this->m_framenumber = framenumber; } + void setMaskWidth(int width) + { + this->m_maskWidth = width; + this->m_maskWidthInv = 1.0f / (float)width; + } + void setMaskHeight(int height) + { + this->m_maskHeight = height; + this->m_maskHeightInv = 1.0f / (float)height; + } + void setFramenumber(int frame_number) { this->m_frame_number = frame_number; } void setSmooth(bool smooth) { this->m_do_smooth = smooth; } void setFeather(bool feather) { this->m_do_feather = feather; } -#ifdef USE_RASKTER - void *initializeTileData(rcti *rect); - void executePixel(float *color, int x, int y, void *data); -#else /* USE_RASKTER */ + 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 *color, float x, float y, PixelSampler sampler); -#endif /* USE_RASKTER */ }; #endif diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.cpp b/source/blender/compositor/operations/COM_MathBaseOperation.cpp index 6c0c27c2522..4644dce572d 100644 --- a/source/blender/compositor/operations/COM_MathBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_MathBaseOperation.cpp @@ -32,6 +32,7 @@ MathBaseOperation::MathBaseOperation() : NodeOperation() this->addOutputSocket(COM_DT_VALUE); this->m_inputValue1Operation = NULL; this->m_inputValue2Operation = NULL; + this->m_useClamp = false; } void MathBaseOperation::initExecution() diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cpp b/source/blender/compositor/operations/COM_MovieClipOperation.cpp index 8b88f5c7d14..ea267830b86 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieClipOperation.cpp @@ -23,7 +23,6 @@ #include "COM_MovieClipOperation.h" #include "BLI_listbase.h" -#include "DNA_scene_types.h" #include "BLI_math.h" extern "C" { #include "BKE_movieclip.h" diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.h b/source/blender/compositor/operations/COM_MovieClipOperation.h index f3e95818bd7..6ca10e2fa9d 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.h +++ b/source/blender/compositor/operations/COM_MovieClipOperation.h @@ -25,7 +25,6 @@ #define _COM_ImageOperation_h #include "COM_NodeOperation.h" -#include "DNA_scene_types.h" #include "DNA_movieclip_types.h" #include "BLI_listbase.h" #include "IMB_imbuf_types.h" diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl.h b/source/blender/compositor/operations/COM_OpenCLKernels.cl.h index cc18039c5b1..7f60f97dfe8 100644 --- a/source/blender/compositor/operations/COM_OpenCLKernels.cl.h +++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl.h @@ -41,7 +41,7 @@ const char * clkernelstoh_COM_OpenCLKernels_cl = "/*\n" \ " float4 color = {0.0f,0.0f,0.0f,0.0f};\n" \ " float4 multiplyer = {0.0f,0.0f,0.0f,0.0f};\n" \ " float4 bokeh;\n" \ -" const float radius2 = radius*2.0f;\n" \ +" const float radius2 = radius * 2.0f;\n" \ " const int2 realCoordinate = coords + offsetOutput;\n" \ "\n" \ " tempBoundingBox = read_imagef(boundingBox, SAMPLER_NEAREST, coords).s0;\n" \ @@ -56,10 +56,10 @@ const char * clkernelstoh_COM_OpenCLKernels_cl = "/*\n" \ " float2 uv;\n" \ " int2 inputXy;\n" \ "\n" \ -" for (ny = minXY.y, inputXy.y = ny - offsetInput.y ; ny < maxXY.y ; ny +=step, inputXy.y+=step) {\n" \ +" for (ny = minXY.y, inputXy.y = ny - offsetInput.y ; ny < maxXY.y ; ny += step, inputXy.y += step) {\n" \ " uv.y = ((realCoordinate.y-ny)/radius2)*bokehImageDim.y+bokehImageCenter.y;\n" \ "\n" \ -" for (nx = minXY.x, inputXy.x = nx - offsetInput.x; nx < maxXY.x ; nx +=step, inputXy.x+=step) {\n" \ +" for (nx = minXY.x, inputXy.x = nx - offsetInput.x; nx < maxXY.x ; nx += step, inputXy.x += step) {\n" \ " uv.x = ((realCoordinate.x-nx)/radius2)*bokehImageDim.x+bokehImageCenter.x;\n" \ " bokeh = read_imagef(bokehImage, SAMPLER_NEAREST, uv);\n" \ " color += bokeh * read_imagef(inputImage, SAMPLER_NEAREST, inputXy);\n" \ @@ -117,7 +117,7 @@ const char * clkernelstoh_COM_OpenCLKernels_cl = "/*\n" \ " float2 uv = { 256.0f + dx * 256.0f / tempSize, 256.0f + dy * 256.0f / tempSize};\n" \ " bokeh = read_imagef(bokehImage, SAMPLER_NEAREST, uv);\n" \ " readColor = read_imagef(inputImage, SAMPLER_NEAREST, inputCoordinate);\n" \ -" color_accum += bokeh*readColor;\n" \ +" color_accum += bokeh * readColor;\n" \ " multiplier_accum += bokeh;\n" \ " }\n" \ " }\n" \ @@ -152,7 +152,7 @@ const char * clkernelstoh_COM_OpenCLKernels_cl = "/*\n" \ " const float deltaY = (realCoordinate.y - ny);\n" \ " for (nx = minXY.x, inputXy.x = nx - offsetInput.x; nx < maxXY.x ; nx ++, inputXy.x++) {\n" \ " const float deltaX = (realCoordinate.x - nx);\n" \ -" const float measuredDistance = deltaX*deltaX+deltaY*deltaY;\n" \ +" const float measuredDistance = deltaX * deltaX + deltaY * deltaY;\n" \ " if (measuredDistance <= distanceSquared) {\n" \ " value = max(value, read_imagef(inputImage, SAMPLER_NEAREST, inputXy).s0);\n" \ " }\n" \ @@ -183,7 +183,7 @@ const char * clkernelstoh_COM_OpenCLKernels_cl = "/*\n" \ " for (nx = minXY.x, inputXy.x = nx - offsetInput.x; nx < maxXY.x ; nx ++, inputXy.x++) {\n" \ " const float deltaX = (realCoordinate.x - nx);\n" \ " const float deltaY = (realCoordinate.y - ny);\n" \ -" const float measuredDistance = deltaX*deltaX+deltaY*deltaY;\n" \ +" const float measuredDistance = deltaX * deltaX + deltaY * deltaY;\n" \ " if (measuredDistance <= distanceSquared) {\n" \ " value = min(value, read_imagef(inputImage, SAMPLER_NEAREST, inputXy).s0);\n" \ " }\n" \ diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp index 83dae7475fb..b72875ab2f9 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp +++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp @@ -27,7 +27,6 @@ #include "BLI_listbase.h" #include "BLI_path_util.h" #include "BLI_string.h" -#include "DNA_scene_types.h" #include "BKE_image.h" #include "BKE_global.h" #include "BKE_main.h" diff --git a/source/blender/compositor/operations/COM_PreviewOperation.cpp b/source/blender/compositor/operations/COM_PreviewOperation.cpp index 8008c95c734..a400402417b 100644 --- a/source/blender/compositor/operations/COM_PreviewOperation.cpp +++ b/source/blender/compositor/operations/COM_PreviewOperation.cpp @@ -23,7 +23,6 @@ #include "COM_PreviewOperation.h" #include "COM_SocketConnection.h" #include "BLI_listbase.h" -#include "DNA_scene_types.h" #include "BKE_image.h" #include "WM_api.h" #include "WM_types.h" diff --git a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp index daf517876e5..00ad319e3b7 100644 --- a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp @@ -78,11 +78,12 @@ bool ProjectorLensDistortionOperation::determineDependingAreaOfInterest(rcti *in newInput.ymin = input->ymin; newInput.xmin = input->xmin - this->m_kr2 - 2; newInput.xmax = input->xmax + this->m_kr2 + 2; - } else { - newInput.xmin = input->xmin - 7; //(0.25f*20*1)+2 == worse case dispersion + } + else { + newInput.xmin = input->xmin - 7; /* (0.25f * 20 * 1) + 2 == worse case dispersion */ newInput.ymin = input->ymin; newInput.ymax = input->ymax; - newInput.xmax = input->xmax + 7; //(0.25f*20*1)+2 == worse case dispersion + newInput.xmax = input->xmax + 7; /* (0.25f * 20 * 1) + 2 == worse case dispersion */ } return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } @@ -95,7 +96,7 @@ void ProjectorLensDistortionOperation::updateDispersion() float result[4]; this->getInputSocketReader(1)->read(result, 0, 0, COM_PS_NEAREST); this->m_dispersion = result[0]; - this->m_kr = 0.25f * MAX2(MIN2(this->m_dispersion, 1.f), 0.f); + this->m_kr = 0.25f * maxf(minf(this->m_dispersion, 1.0f), 0.0f); this->m_kr2 = this->m_kr * 20; this->m_dispersionAvailable = true; } diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cpp b/source/blender/compositor/operations/COM_ScaleOperation.cpp index f4a3dc5fa25..642d1878049 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.cpp +++ b/source/blender/compositor/operations/COM_ScaleOperation.cpp @@ -184,6 +184,7 @@ ScaleFixedSizeOperation::ScaleFixedSizeOperation() : NodeOperation() this->addOutputSocket(COM_DT_COLOR); this->setResolutionInputSocketIndex(0); this->m_inputOperation = NULL; + this->m_is_offset = false; } void ScaleFixedSizeOperation::initExecution() { diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp index d431ce29554..f8628be3ff8 100644 --- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp @@ -301,11 +301,11 @@ bool ScreenLensDistortionOperation::determineDependingAreaOfInterest(rcti *input void ScreenLensDistortionOperation::updateVariables(float distortion, float dispersion) { - this->m_kg = MAX2(MIN2(distortion, 1.f), -0.999f); + this->m_kg = maxf(minf(distortion, 1.0f), -0.999f); // smaller dispersion range for somewhat more control - const float d = 0.25f * MAX2(MIN2(dispersion, 1.f), 0.f); - this->m_kr = MAX2(MIN2((this->m_kg + d), 1.0f), -0.999f); - this->m_kb = MAX2(MIN2((this->m_kg - d), 1.0f), -0.999f); + const float d = 0.25f * maxf(minf(dispersion, 1.0f), 0.0f); + this->m_kr = maxf(minf((this->m_kg + d), 1.0f), -0.999f); + this->m_kb = maxf(minf((this->m_kg - d), 1.0f), -0.999f); this->m_maxk = MAX3(this->m_kr, this->m_kg, this->m_kb); this->m_sc = (this->m_data->fit && (this->m_maxk > 0.f)) ? (1.f / (1.f + 2.f * this->m_maxk)) : (1.f / (1.f + this->m_maxk)); this->m_drg = 4.f * (this->m_kg - this->m_kr); diff --git a/source/blender/compositor/operations/COM_SplitViewerOperation.cpp b/source/blender/compositor/operations/COM_SplitViewerOperation.cpp index 80de4e71fce..d59d1f9f10d 100644 --- a/source/blender/compositor/operations/COM_SplitViewerOperation.cpp +++ b/source/blender/compositor/operations/COM_SplitViewerOperation.cpp @@ -23,7 +23,6 @@ #include "COM_SplitViewerOperation.h" #include "COM_SocketConnection.h" #include "BLI_listbase.h" -#include "DNA_scene_types.h" #include "BKE_image.h" #include "BLI_utildefines.h" #include "BLI_math_color.h" diff --git a/source/blender/compositor/operations/COM_TextureOperation.cpp b/source/blender/compositor/operations/COM_TextureOperation.cpp index 4cf935799cb..5a32bcb76ac 100644 --- a/source/blender/compositor/operations/COM_TextureOperation.cpp +++ b/source/blender/compositor/operations/COM_TextureOperation.cpp @@ -23,7 +23,6 @@ #include "COM_TextureOperation.h" #include "BLI_listbase.h" -#include "DNA_scene_types.h" TextureBaseOperation::TextureBaseOperation() : NodeOperation() { diff --git a/source/blender/compositor/operations/COM_TextureOperation.h b/source/blender/compositor/operations/COM_TextureOperation.h index 8735aff19dc..3631f8d24ff 100644 --- a/source/blender/compositor/operations/COM_TextureOperation.h +++ b/source/blender/compositor/operations/COM_TextureOperation.h @@ -25,7 +25,6 @@ #define _COM_TextureOperation_h #include "COM_NodeOperation.h" -#include "DNA_scene_types.h" #include "DNA_texture_types.h" #include "BLI_listbase.h" extern "C" { diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.cpp b/source/blender/compositor/operations/COM_TrackPositionOperation.cpp index cf516401a3c..869ec71614a 100644 --- a/source/blender/compositor/operations/COM_TrackPositionOperation.cpp +++ b/source/blender/compositor/operations/COM_TrackPositionOperation.cpp @@ -29,8 +29,6 @@ #include "BLI_math.h" #include "BLI_math_color.h" -#include "DNA_scene_types.h" - extern "C" { #include "BKE_movieclip.h" #include "BKE_tracking.h" @@ -39,58 +37,78 @@ extern "C" { TrackPositionOperation::TrackPositionOperation() : NodeOperation() { this->addOutputSocket(COM_DT_VALUE); - this->movieClip = NULL; - this->framenumber = 0; - this->trackingObject[0] = 0; - this->trackName[0] = 0; - this->axis = 0; - this->relative = false; + this->m_movieClip = NULL; + this->m_framenumber = 0; + this->m_trackingObjectName[0] = 0; + this->m_trackName[0] = 0; + this->m_axis = 0; + this->m_position = POSITION_ABSOLUTE;; + this->m_relativeFrame = 0; } -void TrackPositionOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +void TrackPositionOperation::initExecution() { + MovieTracking *tracking = NULL; MovieClipUser user = {0}; - MovieTracking *tracking = &movieClip->tracking; - MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, this->trackingObject); - MovieTrackingTrack *track; - MovieTrackingMarker *marker; - int width, height; + MovieTrackingObject *object; - outputValue[0] = 0.0f; + zero_v2(this->m_markerPos); + zero_v2(this->m_relativePos); - if (!object) + if (!this->m_movieClip) return; - track = BKE_tracking_track_get_named(tracking, object, this->trackName); + tracking = &this->m_movieClip->tracking; - if (!track) - return; + BKE_movieclip_user_set_frame(&user, this->m_framenumber); + BKE_movieclip_get_size(this->m_movieClip, &user, &this->m_width, &this->m_height); + + object = BKE_tracking_object_get_named(tracking, this->m_trackingObjectName); + if (object) { + MovieTrackingTrack *track; - BKE_movieclip_user_set_frame(&user, this->framenumber); - BKE_movieclip_get_size(this->movieClip, &user, &width, &height); + track = BKE_tracking_track_get_named(tracking, object, this->m_trackName); - marker = BKE_tracking_marker_get(track, this->framenumber); + if (track) { + MovieTrackingMarker *marker; + int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip, this->m_framenumber); - outputValue[0] = marker->pos[this->axis]; + marker = BKE_tracking_marker_get(track, clip_framenr); - if (this->relative) { - int i; + copy_v2_v2(this->m_markerPos, marker->pos); - for (i = 0; i < track->markersnr; i++) { - marker = &track->markers[i]; + if (this->m_position == POSITION_RELATIVE_START) { + int i; - if ((marker->flag & MARKER_DISABLED) == 0) { - outputValue[0] -= marker->pos[this->axis]; + for (i = 0; i < track->markersnr; i++) { + marker = &track->markers[i]; - break; + if ((marker->flag & MARKER_DISABLED) == 0) { + copy_v2_v2(this->m_relativePos, marker->pos); + + break; + } + } + } + else if (this->m_position == POSITION_RELATIVE_FRAME) { + int relative_clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip, + this->m_relativeFrame); + + marker = BKE_tracking_marker_get(track, relative_clip_framenr); + copy_v2_v2(this->m_relativePos, marker->pos); } } } +} + +void TrackPositionOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler) +{ + outputValue[0] = this->m_markerPos[this->m_axis] - this->m_relativePos[this->m_axis]; - if (this->axis == 0) - outputValue[0] *= width; + if (this->m_axis == 0) + outputValue[0] *= this->m_width; else - outputValue[0] *= height; + outputValue[0] *= this->m_height; } void TrackPositionOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.h b/source/blender/compositor/operations/COM_TrackPositionOperation.h index caf444db0d5..fe4f703d26c 100644 --- a/source/blender/compositor/operations/COM_TrackPositionOperation.h +++ b/source/blender/compositor/operations/COM_TrackPositionOperation.h @@ -29,8 +29,8 @@ #include "COM_NodeOperation.h" -#include "DNA_scene_types.h" #include "DNA_movieclip_types.h" +#include "DNA_tracking_types.h" #include "BLI_listbase.h" @@ -39,12 +39,23 @@ */ class TrackPositionOperation : public NodeOperation { protected: - MovieClip *movieClip; - int framenumber; - char trackingObject[64]; - char trackName[64]; - int axis; - bool relative; + enum { + POSITION_ABSOLUTE = 0, + POSITION_RELATIVE_START, + POSITION_RELATIVE_FRAME + }; + + MovieClip *m_movieClip; + int m_framenumber; + char m_trackingObjectName[64]; + char m_trackName[64]; + int m_axis; + int m_position; + int m_relativeFrame; + + int m_width, m_height; + float m_markerPos[2]; + float m_relativePos[2]; /** * Determine the output resolution. The resolution is retrieved from the Renderer @@ -54,14 +65,17 @@ protected: public: TrackPositionOperation(); - void setMovieClip(MovieClip *clip) {this->movieClip = clip;} - void setTrackingObject(char *object) {strncpy(this->trackingObject, object, sizeof(this->trackingObject));} - void setTrackName(char *track) {strncpy(this->trackName, track, sizeof(this->trackName));} - void setFramenumber(int framenumber) {this->framenumber = framenumber;} - void setAxis(int value) {this->axis = value;} - void setRelative(bool value) {this->relative = value;} + void setMovieClip(MovieClip *clip) {this->m_movieClip = clip;} + void setTrackingObject(char *object) {strncpy(this->m_trackingObjectName, object, sizeof(this->m_trackingObjectName));} + void setTrackName(char *track) {strncpy(this->m_trackName, track, sizeof(this->m_trackName));} + void setFramenumber(int framenumber) {this->m_framenumber = framenumber;} + void setAxis(int value) {this->m_axis = value;} + void setPosition(int value) {this->m_position = value;} + void setRelativeFrame(int value) {this->m_relativeFrame = value;} + + void initExecution(); - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]); + void executePixel(float *color, float x, float y, PixelSampler sampler); const bool isSetOperation() const { return true; } }; diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp index 8faa571dc38..cd2438ecd12 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp @@ -61,35 +61,49 @@ void VariableSizeBokehBlurOperation::initExecution() #endif QualityStepHelper::initExecution(COM_QH_INCREASE); } +struct VariableSizeBokehBlurTileData +{ + MemoryBuffer *color; + MemoryBuffer *bokeh; + MemoryBuffer *size; + int maxBlur; +}; void *VariableSizeBokehBlurOperation::initializeTileData(rcti *rect) { - MemoryBuffer** result = new MemoryBuffer*[3]; - result[0] = (MemoryBuffer*)this->m_inputProgram->initializeTileData(rect); - result[1] = (MemoryBuffer*)this->m_inputBokehProgram->initializeTileData(rect); - result[2] = (MemoryBuffer*)this->m_inputSizeProgram->initializeTileData(rect); - return result; + VariableSizeBokehBlurTileData *data = new VariableSizeBokehBlurTileData(); + data->color = (MemoryBuffer *)this->m_inputProgram->initializeTileData(rect); + data->bokeh = (MemoryBuffer *)this->m_inputBokehProgram->initializeTileData(rect); + data->size = (MemoryBuffer *)this->m_inputSizeProgram->initializeTileData(rect); + + + rcti rect2; + this->determineDependingAreaOfInterest(rect, (ReadBufferOperation *)this->m_inputSizeProgram, &rect2); + data->maxBlur = (int)data->size->getMaximumValue(&rect2); + CLAMP(data->maxBlur, 1.0f, this->m_maxBlur); + return data; } void VariableSizeBokehBlurOperation::deinitializeTileData(rcti *rect, void *data) { - MemoryBuffer** result = (MemoryBuffer**)data; - delete[] result; + VariableSizeBokehBlurTileData *result = (VariableSizeBokehBlurTileData *)data; + delete result; } void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, void *data) { - MemoryBuffer** buffers = (MemoryBuffer**)data; - MemoryBuffer* inputProgramBuffer = buffers[0]; - MemoryBuffer* inputBokehBuffer = buffers[1]; - MemoryBuffer* inputSizeBuffer = buffers[2]; - float* inputSizeFloatBuffer = inputSizeBuffer->getBuffer(); - float* inputProgramFloatBuffer = inputProgramBuffer->getBuffer(); + VariableSizeBokehBlurTileData *tileData = (VariableSizeBokehBlurTileData *)data; + MemoryBuffer *inputProgramBuffer = tileData->color; + MemoryBuffer *inputBokehBuffer = tileData->bokeh; + MemoryBuffer *inputSizeBuffer = tileData->size; + float *inputSizeFloatBuffer = inputSizeBuffer->getBuffer(); + float *inputProgramFloatBuffer = inputProgramBuffer->getBuffer(); float readColor[4]; float bokeh[4]; float tempSize[4]; float multiplier_accum[4] = {0.0f, 0.0f, 0.0f, 0.0f}; float color_accum[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + int maxBlur = tileData->maxBlur; #ifdef COM_DEFOCUS_SEARCH float search[4]; @@ -99,10 +113,10 @@ void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, vo int maxx = search[2]; int maxy = search[3]; #else - int minx = MAX2(x - this->m_maxBlur, 0.0f); - int miny = MAX2(y - this->m_maxBlur, 0.0f); - int maxx = MIN2(x + this->m_maxBlur, m_width); - int maxy = MIN2(y + this->m_maxBlur, m_height); + int minx = MAX2(x - maxBlur, 0.0f); + int miny = MAX2(y - maxBlur, 0.0f); + int maxx = MIN2(x + maxBlur, m_width); + int maxy = MIN2(y + maxBlur, m_height); #endif { inputSizeBuffer->readNoCheck(tempSize, x, y); @@ -112,13 +126,13 @@ void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, vo add_v4_fl(multiplier_accum, 1.0f); float sizeCenter = tempSize[0]; - const int addXStep = QualityStepHelper::getStep()*COM_NUMBER_OF_CHANNELS; + const int addXStep = QualityStepHelper::getStep() * COM_NUMBER_OF_CHANNELS; if (sizeCenter > this->m_threshold) { for (int ny = miny; ny < maxy; ny += QualityStepHelper::getStep()) { float dy = ny - y; int offsetNy = ny * inputSizeBuffer->getWidth() * COM_NUMBER_OF_CHANNELS; - int offsetNxNy = offsetNy + (minx*COM_NUMBER_OF_CHANNELS); + int offsetNxNy = offsetNy + (minx * COM_NUMBER_OF_CHANNELS); for (int nx = minx; nx < maxx; nx += QualityStepHelper::getStep()) { if (nx != x || ny != y) { @@ -148,7 +162,7 @@ void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, vo } -void VariableSizeBokehBlurOperation::executeOpenCL(OpenCLDevice* device, +void VariableSizeBokehBlurOperation::executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp) @@ -156,9 +170,13 @@ void VariableSizeBokehBlurOperation::executeOpenCL(OpenCLDevice* device, cl_kernel defocusKernel = device->COM_clCreateKernel("defocusKernel", NULL); cl_int step = this->getStep(); - cl_int maxBlur = this->m_maxBlur; + cl_int maxBlur; cl_float threshold = this->m_threshold; + MemoryBuffer *sizeMemoryBuffer = (MemoryBuffer *)this->m_inputSizeProgram->getInputMemoryBuffer(inputMemoryBuffers); + maxBlur = (cl_int)sizeMemoryBuffer->getMaximumValue(); + maxBlur = MIN2(maxBlur, this->m_maxBlur); + device->COM_clAttachMemoryBufferToKernelParameter(defocusKernel, 0, -1, clMemToCleanUp, inputMemoryBuffers, this->m_inputProgram); device->COM_clAttachMemoryBufferToKernelParameter(defocusKernel, 1, -1, clMemToCleanUp, inputMemoryBuffers, this->m_inputBokehProgram); device->COM_clAttachMemoryBufferToKernelParameter(defocusKernel, 2, 4, clMemToCleanUp, inputMemoryBuffers, this->m_inputSizeProgram); @@ -238,10 +256,10 @@ void InverseSearchRadiusOperation::initExecution() this->m_inputRadius = this->getInputSocketReader(0); } -void* InverseSearchRadiusOperation::initializeTileData(rcti *rect) +voi *InverseSearchRadiusOperation::initializeTileData(rcti *rect) { MemoryBuffer * data = new MemoryBuffer(NULL, rect); - float* buffer = data->getBuffer(); + float *buffer = data->getBuffer(); int x, y; int width = this->m_inputRadius->getWidth(); int height = this->m_inputRadius->getHeight(); @@ -294,14 +312,14 @@ void* InverseSearchRadiusOperation::initializeTileData(rcti *rect) void InverseSearchRadiusOperation::executePixel(float *color, int x, int y, void *data) { - MemoryBuffer *buffer = (MemoryBuffer*)data; + MemoryBuffer *buffer = (MemoryBuffer *)data; buffer->readNoCheck(color, x, y); } void InverseSearchRadiusOperation::deinitializeTileData(rcti *rect, void *data) { if (data) { - MemoryBuffer* mb = (MemoryBuffer*)data; + MemoryBuffer *mb = (MemoryBuffer *)data; delete mb; } } @@ -321,10 +339,10 @@ void InverseSearchRadiusOperation::determineResolution(unsigned int resolution[] bool InverseSearchRadiusOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { rcti newRect; - newRect.ymin = input->ymin*DIVIDER - m_maxBlur; - newRect.ymax = input->ymax*DIVIDER + m_maxBlur; - newRect.xmin = input->xmin*DIVIDER - m_maxBlur; - newRect.xmax = input->xmax*DIVIDER + m_maxBlur; + newRect.ymin = input->ymin * DIVIDER - m_maxBlur; + newRect.ymax = input->ymax * DIVIDER + m_maxBlur; + newRect.xmin = input->xmin * DIVIDER - m_maxBlur; + newRect.xmax = input->xmax * DIVIDER + m_maxBlur; return NodeOperation::determineDependingAreaOfInterest(&newRect, readOperation, output); } #endif diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h index e5430545323..f53d54f8c2c 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h @@ -66,7 +66,7 @@ public: void setThreshold(float threshold) { this->m_threshold = threshold; } - void executeOpenCL(OpenCLDevice* device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp); + void executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp); }; #ifdef COM_DEFOCUS_SEARCH @@ -88,7 +88,7 @@ public: * Initialize the execution */ void initExecution(); - void* initializeTileData(rcti *rect); + void *initializeTileData(rcti *rect); void deinitializeTileData(rcti *rect, void *data); /** diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp index 8934dd80ad8..134597531c2 100644 --- a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp @@ -66,7 +66,7 @@ void VectorBlurOperation::deinitExecution() this->m_inputSpeedProgram = NULL; this->m_inputZProgram = NULL; if (this->m_cachedInstance) { - delete this->m_cachedInstance; + delete [] this->m_cachedInstance; this->m_cachedInstance = NULL; } } @@ -115,6 +115,6 @@ void VectorBlurOperation::generateVectorBlur(float *data, MemoryBuffer *inputIma blurdata.curved = this->m_settings->curved; blurdata.fac = this->m_settings->fac; RE_zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), zbuf); - delete zbuf; + delete [] zbuf; return; } diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp index 2470b239987..f443c33cd54 100644 --- a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp @@ -23,7 +23,6 @@ #include "COM_ViewerBaseOperation.h" #include "COM_SocketConnection.h" #include "BLI_listbase.h" -#include "DNA_scene_types.h" #include "BKE_image.h" #include "WM_api.h" #include "WM_types.h" @@ -43,9 +42,11 @@ ViewerBaseOperation::ViewerBaseOperation() : NodeOperation() this->setImage(NULL); this->setImageUser(NULL); this->m_outputBuffer = NULL; + this->m_depthBuffer = NULL; this->m_outputBufferDisplay = NULL; this->m_active = false; this->m_doColorManagement = true; + this->m_doDepthBuffer = false; } void ViewerBaseOperation::initExecution() @@ -61,8 +62,8 @@ void ViewerBaseOperation::initImage() ImBuf *ibuf = BKE_image_acquire_ibuf(anImage, this->m_imageUser, &this->m_lock); if (!ibuf) return; + BLI_lock_thread(LOCK_DRAW_IMAGE); if (ibuf->x != (int)getWidth() || ibuf->y != (int)getHeight()) { - BLI_lock_thread(LOCK_DRAW_IMAGE); imb_freerectImBuf(ibuf); imb_freerectfloatImBuf(ibuf); @@ -73,12 +74,21 @@ void ViewerBaseOperation::initImage() imb_addrectfloatImBuf(ibuf); anImage->ok = IMA_OK_LOADED; - BLI_unlock_thread(LOCK_DRAW_IMAGE); } + if (m_doDepthBuffer) + { + addzbuffloatImBuf(ibuf); + } + BLI_unlock_thread(LOCK_DRAW_IMAGE); + /* now we combine the input with ibuf */ this->m_outputBuffer = ibuf->rect_float; this->m_outputBufferDisplay = (unsigned char *)ibuf->rect; + if (m_doDepthBuffer) + { + this->m_depthBuffer = ibuf->zbuf_float; + } BKE_image_release_ibuf(this->m_image, this->m_lock); } diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.h b/source/blender/compositor/operations/COM_ViewerBaseOperation.h index f3fd1e9c9df..d90eb343f6c 100644 --- a/source/blender/compositor/operations/COM_ViewerBaseOperation.h +++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.h @@ -29,6 +29,7 @@ class ViewerBaseOperation : public NodeOperation { protected: float *m_outputBuffer; + float *m_depthBuffer; unsigned char *m_outputBufferDisplay; Image *m_image; ImageUser *m_imageUser; @@ -39,6 +40,7 @@ protected: OrderOfChunks m_chunkOrder; bool m_doColorManagement; bool m_doColorPredivide; + bool m_doDepthBuffer; public: bool isOutputOperation(bool rendering) const { return isActiveViewerOutput(); } diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cpp b/source/blender/compositor/operations/COM_ViewerOperation.cpp index f7c2ff93b3e..b85b86bddc3 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.cpp +++ b/source/blender/compositor/operations/COM_ViewerOperation.cpp @@ -23,7 +23,6 @@ #include "COM_ViewerOperation.h" #include "COM_SocketConnection.h" #include "BLI_listbase.h" -#include "DNA_scene_types.h" #include "BKE_image.h" #include "WM_api.h" #include "WM_types.h" @@ -43,9 +42,11 @@ ViewerOperation::ViewerOperation() : ViewerBaseOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); this->m_imageInput = NULL; this->m_alphaInput = NULL; + this->m_depthInput = NULL; } void ViewerOperation::initExecution() @@ -53,6 +54,8 @@ void ViewerOperation::initExecution() // When initializing the tree during initial load the width and height can be zero. this->m_imageInput = getInputSocketReader(0); this->m_alphaInput = getInputSocketReader(1); + this->m_depthInput = getInputSocketReader(2); + this->m_doDepthBuffer = (this->m_depthInput != NULL); ViewerBaseOperation::initExecution(); } @@ -60,6 +63,7 @@ void ViewerOperation::deinitExecution() { this->m_imageInput = NULL; this->m_alphaInput = NULL; + this->m_depthInput = NULL; ViewerBaseOperation::deinitExecution(); } @@ -67,47 +71,55 @@ void ViewerOperation::deinitExecution() void ViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber) { float *buffer = this->m_outputBuffer; + float *depthbuffer = this->m_depthBuffer; unsigned char *bufferDisplay = this->m_outputBufferDisplay; if (!buffer) return; const int x1 = rect->xmin; const int y1 = rect->ymin; const int x2 = rect->xmax; const int y2 = rect->ymax; - const int offsetadd = (this->getWidth() - (x2 - x1)) * 4; - int offset = (y1 * this->getWidth() + x1) * 4; - float alpha[4], srgb[4]; + const int offsetadd = (this->getWidth() - (x2 - x1)); + const int offsetadd4 = offsetadd * 4; + int offset = (y1 * this->getWidth() + x1); + int offset4 = offset * 4; + float alpha[4], srgb[4], depth[4]; int x; int y; bool breaked = false; for (y = y1; y < y2 && (!breaked); y++) { for (x = x1; x < x2; x++) { - this->m_imageInput->read(&(buffer[offset]), x, y, COM_PS_NEAREST); + this->m_imageInput->read(&(buffer[offset4]), x, y, COM_PS_NEAREST); if (this->m_alphaInput != NULL) { this->m_alphaInput->read(alpha, x, y, COM_PS_NEAREST); - buffer[offset + 3] = alpha[0]; + buffer[offset4 + 3] = alpha[0]; } + if (m_depthInput) { + this->m_depthInput->read(depth, x, y, COM_PS_NEAREST); + depthbuffer[offset] = depth[0]; + } if (this->m_doColorManagement) { if (this->m_doColorPredivide) { - linearrgb_to_srgb_predivide_v4(srgb, buffer + offset); + linearrgb_to_srgb_predivide_v4(srgb, buffer + offset4); } else { - linearrgb_to_srgb_v4(srgb, buffer + offset); + linearrgb_to_srgb_v4(srgb, buffer + offset4); } } else { - copy_v4_v4(srgb, buffer + offset); + copy_v4_v4(srgb, buffer + offset4); } - rgba_float_to_uchar(bufferDisplay + offset, srgb); + rgba_float_to_uchar(bufferDisplay + offset4, srgb); - offset += 4; + offset ++; + offset4 += 4; } if (isBreaked()) { breaked = true; } - offset += offsetadd; + offset4 += offsetadd4; } updateImage(rect); } diff --git a/source/blender/compositor/operations/COM_ViewerOperation.h b/source/blender/compositor/operations/COM_ViewerOperation.h index d900d8db408..262efd87dba 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.h +++ b/source/blender/compositor/operations/COM_ViewerOperation.h @@ -31,6 +31,7 @@ class ViewerOperation : public ViewerBaseOperation { private: SocketReader *m_imageInput; SocketReader *m_alphaInput; + SocketReader *m_depthInput; public: ViewerOperation(); diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp index 0a31a6e170b..06ec5b51efd 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp @@ -110,7 +110,7 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber) memoryBuffer->setCreatedState(); } -void WriteBufferOperation::executeOpenCLRegion(OpenCLDevice* device, rcti *rect, unsigned int chunkNumber, MemoryBuffer **inputMemoryBuffers, MemoryBuffer *outputBuffer) +void WriteBufferOperation::executeOpenCLRegion(OpenCLDevice *device, rcti *rect, unsigned int chunkNumber, MemoryBuffer **inputMemoryBuffers, MemoryBuffer *outputBuffer) { float *outputFloatBuffer = outputBuffer->getBuffer(); cl_int error; diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.h b/source/blender/compositor/operations/COM_WriteBufferOperation.h index 1aa93c658cb..f1632689dbe 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.h +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.h @@ -44,7 +44,7 @@ public: void executeRegion(rcti *rect, unsigned int tileNumber); void initExecution(); void deinitExecution(); - void executeOpenCLRegion(OpenCLDevice* device, rcti *rect, unsigned int chunkNumber, MemoryBuffer **memoryBuffers, MemoryBuffer *outputBuffer); + void executeOpenCLRegion(OpenCLDevice *device, rcti *rect, unsigned int chunkNumber, MemoryBuffer **memoryBuffers, MemoryBuffer *outputBuffer); void readResolutionFromInputSocket(); inline NodeOperation *getInput() { return m_input; diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index d4b30814403..837230d9719 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -87,12 +87,9 @@ #define ANIM_CHAN_NAME_SIZE 256 -/* macros used for type defines */ - -/* get the pointer used for some flag and return */ +/* get the pointer used for some flag */ #define GET_ACF_FLAG_PTR(ptr, type) ((*(type) = sizeof((ptr))), &(ptr)) - /* *********************************************** */ /* Generic Functions (Type independent) */ @@ -119,7 +116,7 @@ static void acf_generic_root_backdrop(bAnimContext *ac, bAnimListElem *ale, floa glColor3fv(color); /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */ - uiSetRoundBox(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT)); + uiSetRoundBox((expanded) ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT)); uiDrawBox(GL_POLYGON, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8); } diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 0d48bf19c9e..9c9d7f8e34a 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -100,7 +100,7 @@ void ANIM_timecode_string_from_frame(char *str, Scene *scene, int power, short t } else { /* seconds (with pixel offset rounding) */ - seconds = (int)floor(cfra + 0.375f); + seconds = (int)floor(cfra + GLA_PIXEL_OFS); } switch (U.timecode_style) { @@ -150,7 +150,7 @@ void ANIM_timecode_string_from_frame(char *str, Scene *scene, int power, short t /* only show the original seconds display */ /* round to whole numbers if power is >= 1 (i.e. scale is coarse) */ if (power <= 0) sprintf(str, "%.*f", 1 - power, raw_seconds); - else sprintf(str, "%d", (int)floor(raw_seconds + 0.375f)); + else sprintf(str, "%d", (int)floor(raw_seconds + GLA_PIXEL_OFS)); } break; @@ -166,7 +166,7 @@ void ANIM_timecode_string_from_frame(char *str, Scene *scene, int power, short t else { /* round to whole numbers if power is >= 1 (i.e. scale is coarse) */ if (power <= 0) sprintf(str, "%.*f", 1 - power, cfra); - else sprintf(str, "%d", (int)floor(cfra + 0.375f)); + else sprintf(str, "%d", (int)floor(cfra + GLA_PIXEL_OFS)); } } diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 1dcb9f79a09..07e773b1e9a 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1806,11 +1806,18 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b /* sub-data filtering... */ switch (ob->type) { - case OB_LAMP: /* lamp - textures */ + case OB_LAMP: /* lamp - textures + nodetree */ { + Lamp *la = ob->data; + bNodeTree *ntree = la->nodetree; + + /* nodetree */ + if ((ntree) && !(ads->filterflag & ADS_FILTER_NONTREE)) + tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, &la->id, ntree, filter_mode); + /* textures */ if (!(ads->filterflag & ADS_FILTER_NOTEX)) - tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, ob->data, filter_mode); + tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, &la->id, filter_mode); } break; } diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 85731933168..d024e2b0393 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -796,7 +796,7 @@ void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos) { DLRBT_Tree keys, blocks; - short locked = (act->id.lib != 0); + short locked = (act && act->id.lib != 0); BLI_dlrbTree_init(&keys); BLI_dlrbTree_init(&blocks); diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index e0aa33d0207..dd2400ca302 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -4775,7 +4775,7 @@ static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], i distance = distfactor_to_bone(verts[i], root[j], tip[j], bone->rad_head * scale, bone->rad_tail * scale, bone->dist * scale); - /* add the vert to the deform group if weight!=0.0 */ + /* add the vert to the deform group if (weight != 0.0) */ if (distance != 0.0f) ED_vgroup_vert_add(ob, dgroup, i, distance, WEIGHT_REPLACE); else diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c index caadee5f941..fad06f0d020 100644 --- a/source/blender/editors/armature/editarmature_retarget.c +++ b/source/blender/editors/armature/editarmature_retarget.c @@ -2379,7 +2379,7 @@ static void findCorrespondingArc(RigGraph *rigg, RigArc *start_arc, RigNode *sta // printf("CANDIDATES\n"); // for (i = 0; i < enode->degree; i++) // { -// next_earc = (ReebArc*)enode->arcs[i]; +// next_earc = (ReebArc *)enode->arcs[i]; // printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group); // } diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index a9646aaabf4..bc154de9691 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -1427,8 +1427,8 @@ void CURVE_OT_separate(wmOperatorType *ot) static short isNurbselUV(Nurb *nu, int *u, int *v, int flag) { - /* return u!=-1: 1 row in u-direction selected. U has value between 0-pntsv - * return v!=-1: 1 column in v-direction selected. V has value between 0-pntsu + /* return (u != -1): 1 row in u-direction selected. U has value between 0-pntsv + * return (v != -1): 1 column in v-direction selected. V has value between 0-pntsu */ BPoint *bp; int a, b, sel; diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index bb66b1f4347..b11d640256c 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -422,7 +422,8 @@ void FONT_OT_file_paste(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE | TEXTFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | TEXTFILE, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); } /******************* text to object operator ********************/ @@ -1665,7 +1666,7 @@ static int font_open_exec(bContext *C, wmOperator *op) static int open_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { - VFont *font = NULL; + VFont *vfont = NULL; char *path; PointerRNA idptr; @@ -1678,10 +1679,10 @@ static int open_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) if (pprop->prop) { idptr = RNA_property_pointer_get((PointerRNA *)pprop, pprop->prop); - font = idptr.id.data; + vfont = idptr.id.data; } - path = (font && strcmp(font->name, FO_BUILTIN_NAME) != 0) ? font->name : U.fontdir; + path = (vfont && !BKE_vfont_is_builtin(vfont)) ? vfont->name : U.fontdir; if (RNA_struct_property_is_set(op->ptr, "filepath")) return font_open_exec(C, op); @@ -1708,7 +1709,8 @@ void FONT_OT_open(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE | FTFONTFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | FTFONTFILE, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); } /******************* delete operator *********************/ diff --git a/source/blender/editors/include/BIF_gl.h b/source/blender/editors/include/BIF_gl.h index a5e5d7ce2e0..479e0b65177 100644 --- a/source/blender/editors/include/BIF_gl.h +++ b/source/blender/editors/include/BIF_gl.h @@ -50,5 +50,7 @@ #define glMultMatrixf(x) glMultMatrixf( (float *)(x)) #define glLoadMatrixf(x) glLoadMatrixf( (float *)(x)) +#define GLA_PIXEL_OFS 0.375f + #endif /* #ifdef __BIF_GL_H__ */ diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h index b939ae47ead..577113927d1 100644 --- a/source/blender/editors/include/BIF_glutil.h +++ b/source/blender/editors/include/BIF_glutil.h @@ -116,8 +116,8 @@ void glaRasterPosSafe2f(float x, float y, float known_good_x, float known_good_y * * \attention This routine makes many assumptions: the rect data * is expected to be in RGBA unsigned byte format, the coordinate - * (0.375, 0.375) is assumed to be within the view frustum, and the - * modelview and projection matrices are assumed to define a + * (GLA_PIXEL_OFS, GLA_PIXEL_OFS) is assumed to be within the view frustum, + * and the modelview and projection matrices are assumed to define a * 1-to-1 mapping to screen space. * \attention Furthermore, in the case of zoomed or unpixel aligned * images extending outside the view frustum, but still within the diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h index 2670fb5b042..3a1d63574a6 100644 --- a/source/blender/editors/include/ED_clip.h +++ b/source/blender/editors/include/ED_clip.h @@ -39,7 +39,6 @@ struct Main; struct Mask; struct MovieClip; struct SpaceClip; -struct wmEvent; /* ** clip_editor.c ** */ @@ -52,8 +51,9 @@ int ED_space_clip_tracking_poll(struct bContext *C); int ED_space_clip_maskedit_poll(struct bContext *C); int ED_space_clip_maskedit_mask_poll(bContext *C); -void ED_space_clip_get_size(const struct bContext *C, int *width, int *height); -void ED_space_clip_get_zoom(const struct bContext *C, float *zoomx, float *zoomy); +void ED_space_clip_get_size(struct SpaceClip *sc, int *width, int *height); +void ED_space_clip_get_size_fl(struct SpaceClip *sc, float size[2]); +void ED_space_clip_get_zoom(struct SpaceClip *sc, struct ARegion *ar, float *zoomx, float *zoomy); void ED_space_clip_get_aspect(struct SpaceClip *sc, float *aspx, float *aspy); void ED_space_clip_get_aspect_dimension_aware(struct SpaceClip *sc, float *aspx, float *aspy); @@ -65,10 +65,10 @@ struct ImBuf *ED_space_clip_get_stable_buffer(struct SpaceClip *sc, float loc[2] void ED_clip_update_frame(const struct Main *mainp, int cfra); int ED_clip_view_selection(const struct bContext *C, struct ARegion *ar, int fit); -void ED_clip_point_undistorted_pos(SpaceClip *sc, const float co[2], float r_co[2]); -void ED_clip_point_stable_pos(const struct bContext *C, float x, float y, float *xr, float *yr); -void ED_clip_point_stable_pos__reverse(const struct bContext *C, const float co[2], float r_co[2]); -void ED_clip_mouse_pos(const struct bContext *C, struct wmEvent *event, float co[2]); +void ED_clip_point_undistorted_pos(struct SpaceClip *sc, const float co[2], float r_co[2]); +void ED_clip_point_stable_pos(struct SpaceClip *sc, struct ARegion *ar, float x, float y, float *xr, float *yr); +void ED_clip_point_stable_pos__reverse(struct SpaceClip *sc, struct ARegion *ar, const float co[2], float r_co[2]); +void ED_clip_mouse_pos(struct SpaceClip *sc, struct ARegion *ar, const int mval[2], float co[2]); int ED_space_clip_check_show_trackedit(struct SpaceClip *sc); int ED_space_clip_check_show_maskedit(struct SpaceClip *sc); diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h index b95615ce365..d291c500547 100644 --- a/source/blender/editors/include/ED_image.h +++ b/source/blender/editors/include/ED_image.h @@ -38,32 +38,43 @@ struct ImageUser; struct ToolSettings; struct uiBlock; struct wmWindowManager; +struct ARegion; -/* space_image.c, exported for transform */ +/* image_edit.c, exported for transform */ struct Image *ED_space_image(struct SpaceImage *sima); -void ED_space_image_set(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit, struct Image *ima); +void ED_space_image_set(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit, struct Image *ima); +struct Mask *ED_space_image_get_mask(struct SpaceImage *sima); +void ED_space_image_set_mask(struct bContext *C, struct SpaceImage *sima, struct Mask *mask); struct ImBuf *ED_space_image_acquire_buffer(struct SpaceImage *sima, void **lock_r); void ED_space_image_release_buffer(struct SpaceImage *sima, void *lock); int ED_space_image_has_buffer(struct SpaceImage *sima); -void ED_space_image_size(struct SpaceImage *sima, int *width, int *height); -void ED_space_image_aspect(struct SpaceImage *sima, float *aspx, float *aspy); -void ED_space_image_zoom(struct SpaceImage *sima, struct ARegion *ar, float *zoomx, float *zoomy); -void ED_space_image_uv_aspect(struct SpaceImage *sima, float *aspx, float *aspy); +void ED_space_image_get_size(struct SpaceImage *sima, int *width, int *height); +void ED_space_image_get_size_fl(struct SpaceImage *sima, float size[2]); +void ED_space_image_get_aspect(struct SpaceImage *sima, float *aspx, float *aspy); +void ED_space_image_get_zoom(struct SpaceImage *sima, struct ARegion *ar, float *zoomx, float *zoomy); +void ED_space_image_get_uv_aspect(struct SpaceImage *sima, float *aspx, float *aspy); void ED_space_image_paint_update(struct wmWindowManager *wm, struct ToolSettings *settings); void ED_space_image_uv_sculpt_update(struct wmWindowManager *wm, struct ToolSettings *settings); -void ED_image_size(struct Image *ima, int *width, int *height); -void ED_image_aspect(struct Image *ima, float *aspx, float *aspy); -void ED_image_uv_aspect(struct Image *ima, float *aspx, float *aspy); +void ED_image_get_size(struct Image *ima, int *width, int *height); +void ED_image_get_aspect(struct Image *ima, float *aspx, float *aspy); +void ED_image_get_uv_aspect(struct Image *ima, float *aspx, float *aspy); +void ED_image_mouse_pos(struct SpaceImage *sima, struct ARegion *ar, const int mval[2], float co[2]); +void ED_image_point_pos(struct SpaceImage *sima, struct ARegion *ar, float x, float y, float *xr, float *yr); +void ED_image_point_pos__reverse(struct SpaceImage *sima, struct ARegion *ar, const float co[2], float r_co[2]); int ED_space_image_show_render(struct SpaceImage *sima); int ED_space_image_show_paint(struct SpaceImage *sima); int ED_space_image_show_uvedit(struct SpaceImage *sima, struct Object *obedit); int ED_space_image_show_uvshadow(struct SpaceImage *sima, struct Object *obedit); +int ED_space_image_check_show_maskedit(struct Scene *scene, struct SpaceImage *sima); +int ED_space_image_maskedit_poll(struct bContext *C); +int ED_space_image_maskedit_mask_poll(struct bContext *C); + /* UI level image (texture) updating... render calls own stuff (too) */ void ED_image_update_frame(const struct Main *mainp, int cfra); diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h index 773da04bc7b..88667729eee 100644 --- a/source/blender/editors/include/ED_mask.h +++ b/source/blender/editors/include/ED_mask.h @@ -34,14 +34,34 @@ struct wmKeyConfig; struct MaskLayer; struct MaskLayerShape; +struct wmEvent; + +/* mask_edit.c */ +void ED_mask_get_size(struct ScrArea *sa, int *width, int *height); +void ED_mask_zoom(struct ScrArea *sa, struct ARegion *ar, float *zoomx, float *zoomy); +void ED_mask_get_aspect(struct ScrArea *sa, struct ARegion *ar, float *aspx, float *aspy); + +void ED_mask_pixelspace_factor(struct ScrArea *sa, struct ARegion *ar, float *scalex, float *scaley); +void ED_mask_mouse_pos(struct ScrArea *sa, struct ARegion *ar, const int mval[2], float co[2]); + +void ED_mask_point_pos(struct ScrArea *sa, struct ARegion *ar, float x, float y, float *xr, float *yr); +void ED_mask_point_pos__reverse(struct ScrArea *sa, struct ARegion *ar, + float x, float y, float *xr, float *yr); -/* mask_editor.c */ void ED_operatortypes_mask(void); void ED_keymap_mask(struct wmKeyConfig *keyconf); void ED_operatormacros_mask(void); /* mask_draw.c */ void ED_mask_draw(const bContext *C, const char draw_flag, const char draw_type); +void ED_mask_draw_region(struct Mask *mask, struct ARegion *ar, + const char draw_flag, const char draw_type, + int width, int height, + const short do_scale_applied, const short do_post_draw, + float stabmat[4][4], + const bContext *C); + +void ED_mask_draw_frames(struct Mask *mask, struct ARegion *ar, const int cfra, const int sfra, const int efra); /* mask_shapekey.c */ void ED_mask_layer_shape_auto_key(struct MaskLayer *masklay, const int frame); diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h index 6f86d01fb98..b6a1fd0f979 100644 --- a/source/blender/editors/include/ED_node.h +++ b/source/blender/editors/include/ED_node.h @@ -41,6 +41,7 @@ struct bNodeTree; struct bNode; struct bNodeTree; struct ScrArea; +struct Scene; struct View2D; typedef enum { @@ -51,9 +52,9 @@ typedef enum { } NodeBorder; /* drawnode.c */ -void ED_init_node_butfuncs(void); - -void drawnodesnap(struct View2D *v2d, const float cent[2], float size, NodeBorder border); +void ED_node_init_butfuncs(void); +void ED_node_sample_set(const float col[4]); +void ED_node_draw_snap(struct View2D *v2d, const float cent[2], float size, NodeBorder border); /* node_draw.c */ void ED_node_tree_update(struct SpaceNode *snode, struct Scene *scene); @@ -61,18 +62,19 @@ void ED_node_changed_update(struct ID *id, struct bNode *node); void ED_node_generic_update(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node); void ED_node_sort(struct bNodeTree *ntree); +/* node_relationships.c */ +void ED_node_link_intersect_test(struct ScrArea *sa, int test); +void ED_node_link_insert(struct ScrArea *sa); + /* node_edit.c */ void ED_node_shader_default(struct Scene *scene, struct ID *id); void ED_node_composit_default(struct Scene *sce); void ED_node_texture_default(struct Tex *tex); -void ED_node_link_intersect_test(struct ScrArea *sa, int test); -void ED_node_link_insert(struct ScrArea *sa); - +int ED_node_select_check(ListBase *lb); void ED_node_post_apply_transform(struct bContext *C, struct bNodeTree *ntree); - void ED_node_set_active(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node); -void ED_node_sample_set(const float col[4]); +void ED_node_composite_job(const bContext *C, struct bNodeTree *nodetree, struct Scene *scene_owner); /* node ops.c */ void ED_operatormacros_node(void); diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 38f0077c368..d876d311d30 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -41,6 +41,7 @@ struct bContext; struct bPoseChannel; struct Curve; struct EnumPropertyItem; +struct ID; struct KeyBlock; struct Lattice; struct Main; @@ -178,11 +179,14 @@ int ED_object_modifier_apply(struct ReportList *reports, struct Scene *scene, int ED_object_modifier_copy(struct ReportList *reports, struct Object *ob, struct ModifierData *md); int ED_object_iter_other(struct Main *bmain, struct Object *orig_ob, int include_orig, - int (*callback)(struct Object *ob, void *callback_data), - void *callback_data); + int (*callback)(struct Object *ob, void *callback_data), + void *callback_data); int ED_object_multires_update_totlevels_cb(struct Object *ob, void *totlevel_v); +/* ibject_select.c */ +void ED_object_select_linked_by_id(struct bContext *C, struct ID *id); + #ifdef __cplusplus } #endif diff --git a/source/blender/editors/include/ED_sequencer.h b/source/blender/editors/include/ED_sequencer.h index 7ba26f30c39..7807f06594e 100644 --- a/source/blender/editors/include/ED_sequencer.h +++ b/source/blender/editors/include/ED_sequencer.h @@ -29,10 +29,15 @@ struct Scene; struct Sequence; +struct SpaceSeq; void ED_sequencer_select_sequence_single(struct Scene *scene, struct Sequence *seq, int deselect_all); void ED_sequencer_deselect_all(struct Scene *scene); +int ED_space_sequencer_maskedit_mask_poll(struct bContext *C); +int ED_space_sequencer_check_show_maskedit(struct SpaceSeq *sseq, struct Scene *scene); +int ED_space_sequencer_maskedit_poll(bContext *C); + void ED_operatormacros_sequencer(void); #endif /* __ED_SEQUENCER_H__ */ diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index 2427ed1a333..56f8a455c52 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -85,6 +85,7 @@ void ED_uvedit_live_unwrap(struct Scene *scene, struct Object *obedit); void ED_unwrap_lscm(struct Scene *scene, struct Object *obedit, const short sel); /* uvedit_draw.c */ +void draw_image_cursor(struct SpaceImage *sima, struct ARegion *ar); void draw_uvedit_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene, struct Object *obedit, struct Object *obact); /* uvedit_buttons.c */ diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index 51df30d6c28..e879a01dbfb 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -127,6 +127,7 @@ enum { TH_BONE_SOLID, TH_BONE_POSE, + TH_BONE_POSE_ACTIVE, TH_STRIP, TH_STRIP_SELECT, diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 8f15a63ac33..7b1150669e8 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -2674,10 +2674,11 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, * of our UI functions take prop rather then propname. */ -#define UI_DEF_BUT_RNA_DISABLE(but) \ - but->flag |= UI_BUT_DISABLED; \ - but->lock = 1; \ - but->lockstr = "" +#define UI_DEF_BUT_RNA_DISABLE(but) { \ + but->flag |= UI_BUT_DISABLED; \ + but->lock = TRUE; \ + but->lockstr = ""; \ + } (void)0 static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *str, @@ -3713,7 +3714,7 @@ void uiButGetStrInfo(bContext *C, uiBut *but, int nbr, ...) va_start(args, nbr); while (nbr--) { - uiStringInfo *si = (uiStringInfo*) va_arg(args, void*); + uiStringInfo *si = (uiStringInfo *) va_arg(args, void *); int type = si->type; char *tmp = NULL; @@ -3727,14 +3728,15 @@ void uiButGetStrInfo(bContext *C, uiBut *but, int nbr, ...) tmp = BLI_strdup(but->str); } else - type = BUT_GET_RNA_LABEL; /* Fail-safe solution... */ + type = BUT_GET_RNA_LABEL; /* Fail-safe solution... */ } else if (type == BUT_GET_TIP) { if (but->tip && but->tip[0]) tmp = BLI_strdup(but->tip); else - type = BUT_GET_RNA_TIP; /* Fail-safe solution... */ + type = BUT_GET_RNA_TIP; /* Fail-safe solution... */ } + if (type == BUT_GET_RNAPROP_IDENTIFIER) { if (but->rnaprop) tmp = BLI_strdup(RNA_property_identifier(but->rnaprop)); @@ -3772,12 +3774,15 @@ void uiButGetStrInfo(bContext *C, uiBut *but, int nbr, ...) else if (ELEM(but->type, MENU, PULLDOWN)) { MenuType *mt = uiButGetMenuType(but); if (mt) { - if (type == BUT_GET_RNA_LABEL) - tmp = BLI_strdup(RNA_struct_ui_name(mt->ext.srna)); - else { - const char *t = RNA_struct_ui_description(mt->ext.srna); - if (t && t[0]) - tmp = BLI_strdup(t); + /* not all menus are from python */ + if (mt->ext.srna) { + if (type == BUT_GET_RNA_LABEL) + tmp = BLI_strdup(RNA_struct_ui_name(mt->ext.srna)); + else { + const char *t = RNA_struct_ui_description(mt->ext.srna); + if (t && t[0]) + tmp = BLI_strdup(t); + } } } } diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 1d88838ecc5..f7eff2cb22b 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -479,7 +479,7 @@ static void ui_draw_but_CHARTAB(uiBut *but) int charmax = G.charmax; /* FO_BUILTIN_NAME font in use. There are TTF FO_BUILTIN_NAME and non-TTF FO_BUILTIN_NAME fonts */ - if (!strcmp(G.selfont->name, FO_BUILTIN_NAME)) { + if (BKE_vfont_is_builtin(G.selfont)) { if (G.ui_international == TRUE) { charmax = 0xff; } @@ -508,7 +508,7 @@ static void ui_draw_but_CHARTAB(uiBut *but) cs = G.charstart; /* Set the font, in case it is not FO_BUILTIN_NAME font */ - if (G.selfont && strcmp(G.selfont->name, FO_BUILTIN_NAME)) { + if (G.selfont && BKE_vfont_is_builtin(G.selfont) == FALSE) { /* Is the font file packed, if so then use the packed file */ if (G.selfont->packedfile) { pf = G.selfont->packedfile; @@ -559,7 +559,7 @@ static void ui_draw_but_CHARTAB(uiBut *but) /* Set the font to be either unicode or FO_BUILTIN_NAME */ wstr[0] = cs; - if (strcmp(G.selfont->name, FO_BUILTIN_NAME)) { + if (BKE_vfont_is_builtin(G.selfont) == FALSE) { BLI_strncpy_wchar_as_utf8((char *)ustr, (wchar_t *)wstr, sizeof(ustr)); } else { @@ -572,8 +572,8 @@ static void ui_draw_but_CHARTAB(uiBut *but) } } - if ((G.selfont && strcmp(G.selfont->name, FO_BUILTIN_NAME)) || - (G.selfont && !strcmp(G.selfont->name, FO_BUILTIN_NAME) && G.ui_international == TRUE)) + if ((G.selfont && (BKE_vfont_is_builtin(G.selfont) == FALSE)) || + (G.selfont && (BKE_vfont_is_builtin(G.selfont) == TRUE) && G.ui_international == TRUE)) { float wid; float llx, lly, llz, urx, ury, urz; @@ -714,6 +714,8 @@ static void histogram_draw_one(float r, float g, float b, float alpha, } } +#define HISTOGRAM_TOT_GRID_LINES 4 + void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti) { Histogram *hist = (Histogram *)but->poin; @@ -749,9 +751,16 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol) glColor4f(1.f, 1.f, 1.f, 0.08f); /* draw grid lines here */ - for (i = 1; i < 4; i++) { - fdrawline(rect.xmin, rect.ymin + (i / 4.f) * h, rect.xmax, rect.ymin + (i / 4.f) * h); - fdrawline(rect.xmin + (i / 4.f) * w, rect.ymin, rect.xmin + (i / 4.f) * w, rect.ymax); + for (i = 1; i < (HISTOGRAM_TOT_GRID_LINES + 1); i++) { + const float fac = (float)i / (float)HISTOGRAM_TOT_GRID_LINES; + + /* so we can tell the 1.0 color point */ + if (i == HISTOGRAM_TOT_GRID_LINES) { + glColor4f(1.0f, 1.0f, 1.0f, 0.5f); + } + + fdrawline(rect.xmin, rect.ymin + fac * h, rect.xmax, rect.ymin + fac * h); + fdrawline(rect.xmin + fac * w, rect.ymin, rect.xmin + fac * w, rect.ymax); } if (hist->mode == HISTO_MODE_LUMA) { @@ -773,6 +782,8 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol) draw_scope_end(&rect, scissor); } +#undef HISTOGRAM_TOT_GRID_LINES + void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti) { Scopes *scopes = (Scopes *)but->poin; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 2a93ab794af..ce9e63076fb 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -3725,7 +3725,7 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt offsy = cumap->curr.ymin; if (event->ctrl) { - fx = ((float)my - but->x1) / zoomx + offsx; + fx = ((float)mx - but->x1) / zoomx + offsx; fy = ((float)my - but->y1) / zoomy + offsy; curvemap_insert(cuma, fx, fy); @@ -3868,11 +3868,12 @@ static int ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx hist->height = (but->y2 - but->y1) + (data->dragstarty - my); } else { - /* scale histogram values */ + /* scale histogram values (dy / 10 for better control) */ const float yfac = minf(powf(hist->ymax, 2.0f), 1.0f) * 0.5f; - hist->ymax += dy * yfac; + hist->ymax += (dy * 0.1f) * yfac; - CLAMP(hist->ymax, 1.f, 100.f); + /* 0.1 allows us to see HDR colors up to 10 */ + CLAMP(hist->ymax, 0.1f, 100.f); } data->draglastx = mx; @@ -5845,6 +5846,8 @@ static int ui_handle_list_event(bContext *C, wmEvent *event, ARegion *ar) else value++; + CLAMP(value, 0, pa->list_last_len - 1); + if (value < pa->list_scroll) pa->list_scroll = value; else if (value >= pa->list_scroll + pa->list_size) diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 002c3d48a01..2bfead708be 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -1091,7 +1091,7 @@ static int ui_id_brush_get_icon(bContext *C, ID *id) mode = OB_MODE_TEXTURE_PAINT; } else if ((sima = CTX_wm_space_image(C)) && - (sima->flag & SI_DRAWTOOL)) + (sima->mode == SI_MODE_PAINT)) { mode = OB_MODE_TEXTURE_PAINT; } diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 3270015271a..10fde402acc 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1960,6 +1960,7 @@ static void ui_litem_estimate_column_flow(uiLayout *litem) x += maxw + litem->space; maxw = 0; y = 0; + emy = 0; /* need to reset height again for next column */ col++; } } @@ -2010,6 +2011,7 @@ static void ui_litem_layout_column_flow(uiLayout *litem) if (col < flow->totcol - 1 && emy <= -emh) { x += itemw + style->columnspace; y = litem->y; + emy = 0; /* need to reset height again for next column */ col++; } } diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 76485571096..d04c1af2769 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -831,14 +831,15 @@ static void ui_do_animate(const bContext *C, Panel *panel) float fac; fac = (PIL_check_seconds_timer() - data->starttime) / ANIMATION_TIME; - fac = sqrt(fac); - fac = MIN2(fac, 1.0f); + fac = minf(sqrt(fac), 1.0f); /* for max 1 second, interpolate positions */ - if (uiAlignPanelStep(sa, ar, fac, 0)) + if (uiAlignPanelStep(sa, ar, fac, 0)) { ED_region_tag_redraw(ar); - else + } + else { fac = 1.0f; + } if (fac >= 1.0f) { panel_activate_state(C, panel, PANEL_STATE_EXIT); diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 83366ec204b..70f2bf7b028 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -2418,7 +2418,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi * on the first item */ offset[0] = 0; for (bt = block->buttons.first; bt; bt = bt->next) - offset[0] = MIN2(offset[0], -(bt->x1 + 0.8f * (bt->x2 - bt->x1))); + offset[0] = mini(offset[0], -(bt->x1 + 0.8f * (bt->x2 - bt->x1))); offset[1] = 1.5 * UI_UNIT_Y; } @@ -2649,7 +2649,7 @@ void uiPupMenuOkee(bContext *C, const char *opname, const char *str, ...) * The operator state for this is implicitly OPERATOR_RUNNING_MODAL */ void uiPupMenuSaveOver(bContext *C, wmOperator *op, const char *filename) { - confirm_operator(C, op, "Save Over", filename); + confirm_operator(C, op, "Save Over?", filename); } void uiPupMenuNotice(bContext *C, const char *str, ...) diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 4702253140a..2620fc46e74 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -254,7 +254,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) break; case UI_ID_OPEN: case UI_ID_ADD_NEW: - /* these call uiIDContextPropertySet */ + /* these call uiIDContextProperty */ break; case UI_ID_DELETE: memset(&idptr, 0, sizeof(idptr)); @@ -1635,7 +1635,7 @@ static void curvemap_buttons_delete(bContext *C, void *cb_v, void *cumap_v) } /* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */ -static uiBlock *curvemap_clipping_func(bContext *C, struct ARegion *ar, void *cumap_v) +static uiBlock *curvemap_clipping_func(bContext *C, ARegion *ar, void *cumap_v) { CurveMapping *cumap = cumap_v; uiBlock *block; @@ -1696,7 +1696,7 @@ static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event) ED_region_tag_redraw(CTX_wm_region(C)); } -static uiBlock *curvemap_tools_func(bContext *C, struct ARegion *ar, void *cumap_v) +static uiBlock *curvemap_tools_func(bContext *C, ARegion *ar, void *cumap_v) { uiBlock *block; short yco = 0, menuwidth = 10 * UI_UNIT_X; @@ -1718,7 +1718,7 @@ static uiBlock *curvemap_tools_func(bContext *C, struct ARegion *ar, void *cumap return block; } -static uiBlock *curvemap_brush_tools_func(bContext *C, struct ARegion *ar, void *cumap_v) +static uiBlock *curvemap_brush_tools_func(bContext *C, ARegion *ar, void *cumap_v) { uiBlock *block; short yco = 0, menuwidth = 10 * UI_UNIT_X; diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 7b139d81a1c..b439271b23d 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -346,7 +346,8 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl const int vnum = ((roundboxalign & (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT)) == (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT) || (roundboxalign & (UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT)) == (UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT)) ? 1 : 2; - minsize = MIN2((rect->xmax - rect->xmin) * hnum, (rect->ymax - rect->ymin) * vnum); + minsize = mini((rect->xmax - rect->xmin) * hnum, + (rect->ymax - rect->ymin) * vnum); if (2.0f * rad > minsize) rad = 0.5f * minsize; diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 50f93f7e9f5..9489e6b5440 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -303,6 +303,8 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo cp = ts->bone_solid; break; case TH_BONE_POSE: cp = ts->bone_pose; break; + case TH_BONE_POSE_ACTIVE: + cp = ts->bone_pose_active; break; case TH_STRIP: cp = ts->strip; break; case TH_STRIP_SELECT: @@ -739,6 +741,7 @@ void ui_theme_init_default(void) rgba_char_args_set(btheme->tv3d.bone_solid, 200, 200, 200, 255); /* alpha 80 is not meant editable, used for wire+action draw */ rgba_char_args_set(btheme->tv3d.bone_pose, 80, 200, 255, 80); + rgba_char_args_set(btheme->tv3d.bone_pose_active, 140, 255, 255, 80); rgba_char_args_set(btheme->tv3d.bundle_solid, 200, 200, 200, 255); rgba_char_args_set(btheme->tv3d.camera_path, 0x00, 0x00, 0x00, 255); @@ -1914,6 +1917,25 @@ void init_userdef_do_versions(void) } } + if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 15)) { + bTheme *btheme; + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + rgba_char_args_set(btheme->tv3d.bone_pose_active, 140, 255, 255, 80); + } + } + + if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 16)) { + bTheme *btheme; + + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + if (btheme->tact.anim_active[3] == 0) + rgba_char_args_set(btheme->tact.anim_active, 204, 112, 26, 102); + + if (btheme->tnla.anim_active[3] == 0) + rgba_char_args_set(btheme->tnla.anim_active, 204, 112, 26, 102); + } + } + /* GL Texture Garbage Collection (variable abused above!) */ if (U.textimeout == 0) { U.texcollectrate = 60; diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index a693e9eb627..8ae08c08693 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -980,7 +980,7 @@ void UI_view2d_view_ortho(View2D *v2d) rctf curmasked; float xofs, yofs; - /* pixel offsets (-0.375f) are needed to get 1:1 correspondence with pixels for smooth UI drawing, + /* pixel offsets (-GLA_PIXEL_OFS) are needed to get 1:1 correspondence with pixels for smooth UI drawing, * but only applied where requested */ /* XXX brecht: instead of zero at least use a tiny offset, otherwise @@ -1019,12 +1019,12 @@ void UI_view2d_view_orthoSpecial(ARegion *ar, View2D *v2d, short xaxis) rctf curmasked; float xofs, yofs; - /* pixel offsets (-0.375f) are needed to get 1:1 correspondence with pixels for smooth UI drawing, + /* pixel offsets (-GLA_PIXEL_OFS) are needed to get 1:1 correspondence with pixels for smooth UI drawing, * but only applied where requested */ /* XXX temp (ton) */ - xofs = 0.0f; // (v2d->flag & V2D_PIXELOFS_X) ? 0.375f : 0.0f; - yofs = 0.0f; // (v2d->flag & V2D_PIXELOFS_Y) ? 0.375f : 0.0f; + xofs = 0.0f; // (v2d->flag & V2D_PIXELOFS_X) ? GLA_PIXEL_OFS : 0.0f; + yofs = 0.0f; // (v2d->flag & V2D_PIXELOFS_Y) ? GLA_PIXEL_OFS : 0.0f; /* apply mask-based adjustments to cur rect (due to scrollers), to eliminate scaling artifacts */ view2d_map_cur_using_mask(v2d, &curmasked); diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c index 6e4da6b7e88..ebfc0522f17 100644 --- a/source/blender/editors/io/io_collada.c +++ b/source/blender/editors/io/io_collada.c @@ -242,7 +242,8 @@ void WM_OT_collada_export(wmOperatorType *ot) ot->ui = wm_collada_export_draw; - WM_operator_properties_filesel(ot, FOLDERFILE | COLLADAFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | COLLADAFILE, FILE_BLENDER, FILE_SAVE, + WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, "apply_modifiers", 0, "Apply Modifiers", @@ -319,6 +320,7 @@ void WM_OT_collada_import(wmOperatorType *ot) ot->exec = wm_collada_import_exec; ot->poll = WM_operator_winactive; - WM_operator_properties_filesel(ot, FOLDERFILE | COLLADAFILE, FILE_BLENDER, FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | COLLADAFILE, FILE_BLENDER, FILE_OPENFILE, + WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); } #endif diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c index c9f6dc0c5fb..e20a7b51d13 100644 --- a/source/blender/editors/mask/mask_add.c +++ b/source/blender/editors/mask/mask_add.c @@ -38,6 +38,7 @@ #include "BKE_mask.h" #include "DNA_scene_types.h" +#include "DNA_screen_types.h" #include "DNA_mask_types.h" #include "DNA_object_types.h" /* SELECT */ @@ -57,17 +58,19 @@ static int find_nearest_diff_point(const bContext *C, Mask *mask, const float no float *u_r, float tangent[2], const short use_deform) { + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + MaskLayer *masklay, *point_masklay; MaskSpline *point_spline; MaskSplinePoint *point = NULL; float dist, co[2]; int width, height; float u; - float scalex, scaley, aspx, aspy; + float scalex, scaley; - ED_mask_size(C, &width, &height); - ED_mask_aspect(C, &aspx, &aspy); - ED_mask_pixelspace_factor(C, &scalex, &scaley); + ED_mask_get_size(sa, &width, &height); + ED_mask_pixelspace_factor(sa, ar, &scalex, &scaley); co[0] = normal_co[0] * scalex; co[1] = normal_co[1] * scaley; @@ -88,13 +91,14 @@ static int find_nearest_diff_point(const bContext *C, Mask *mask, const float no i++, cur_point++) { float *diff_points; - int tot_diff_point; + unsigned int tot_diff_point; diff_points = BKE_mask_point_segment_diff_with_resolution(spline, cur_point, width, height, &tot_diff_point); if (diff_points) { - int i, tot_feather_point, tot_point; + int i, tot_point; + unsigned int tot_feather_point; float *feather_points = NULL, *points; if (feather) { @@ -180,6 +184,8 @@ static void setup_vertex_point(const bContext *C, Mask *mask, MaskSpline *spline const float point_co[2], const float tangent[2], const float u, MaskSplinePoint *reference_point, const short reference_adjacent) { + ScrArea *sa = CTX_wm_area(C); + MaskSplinePoint *prev_point = NULL; MaskSplinePoint *next_point = NULL; BezTriple *bezt; @@ -190,7 +196,7 @@ static void setup_vertex_point(const bContext *C, Mask *mask, MaskSpline *spline copy_v2_v2(co, point_co); co[2] = 0.0f; - ED_mask_size(C, &width, &height); + ED_mask_get_size(sa, &width, &height); /* point coordinate */ bezt = &new_point->bezt; @@ -315,6 +321,7 @@ static void finSelectedSplinePoint(MaskLayer *masklay, MaskSpline **spline, Mask *point = NULL; if (check_active) { + /* TODO, having an active point but no active spline is possible, why? */ if (masklay->act_spline && masklay->act_point && MASKPOINT_ISSEL_ANY(masklay->act_point)) { *spline = masklay->act_spline; *point = masklay->act_point; @@ -556,7 +563,8 @@ static int add_vertex_exec(bContext *C, wmOperator *op) RNA_float_get_array(op->ptr, "location", co); - if (masklay && masklay->act_point && MASKPOINT_ISSEL_ANY(masklay->act_point)) { + /* TODO, having an active point but no active spline is possible, why? */ + if (masklay && masklay->act_spline && masklay->act_point && MASKPOINT_ISSEL_ANY(masklay->act_point)) { /* cheap trick - double click for cyclic */ MaskSpline *spline = masklay->act_spline; @@ -610,9 +618,12 @@ static int add_vertex_exec(bContext *C, wmOperator *op) static int add_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event) { + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + float co[2]; - ED_mask_mouse_pos(C, event, co); + ED_mask_mouse_pos(sa, ar, event->mval, co); RNA_float_set_array(op->ptr, "location", co); @@ -681,9 +692,12 @@ static int add_feather_vertex_exec(bContext *C, wmOperator *op) static int add_feather_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event) { + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + float co[2]; - ED_mask_mouse_pos(C, event, co); + ED_mask_mouse_pos(sa, ar, event->mval, co); RNA_float_set_array(op->ptr, "location", co); diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index f378d5452a4..2f5a918a488 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -32,17 +32,21 @@ #include "MEM_guardedalloc.h" #include "BLI_utildefines.h" +#include "BLI_math.h" #include "BKE_context.h" #include "BKE_mask.h" #include "DNA_mask_types.h" +#include "DNA_screen_types.h" #include "DNA_object_types.h" /* SELECT */ #include "ED_mask.h" /* own include */ +#include "ED_space_api.h" #include "BIF_gl.h" #include "UI_resources.h" +#include "UI_view2d.h" #include "mask_intern.h" /* own include */ @@ -129,7 +133,8 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, if (!spline->tot_point) return; - hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); + /* TODO, add this to sequence editor */ + hsize = 4; /* UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); */ glPointSize(hsize); @@ -451,13 +456,116 @@ static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type void ED_mask_draw(const bContext *C, const char draw_flag, const char draw_type) { + ScrArea *sa = CTX_wm_area(C); + Mask *mask = CTX_data_edit_mask(C); int width, height; if (!mask) return; - ED_mask_size(C, &width, &height); + ED_mask_get_size(sa, &width, &height); + + draw_masklays(mask, draw_flag, draw_type, width, height); +} + +/* sets up the opengl context. + * width, height are to match the values from ED_mask_get_size() */ +void ED_mask_draw_region(Mask *mask, ARegion *ar, + const char draw_flag, const char draw_type, + int width, int height, + const short do_scale_applied, const short do_post_draw, + float stabmat[4][4], /* optional - only used by clip */ + const bContext *C /* optional - only used when do_post_draw is set */ + ) +{ + struct View2D *v2d = &ar->v2d; + + int x, y; + /* int w, h; */ + float zoomx, zoomy; + + /* frame image */ + float maxdim; + float xofs, yofs; + + /* find window pixel coordinates of origin */ + UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y); + + + /* w = v2d->tot.xmax - v2d->tot.xmin; */ + /* h = v2d->tot.ymax - v2d->tot.ymin;/*/ + + + zoomx = (float)(ar->winrct.xmax - ar->winrct.xmin + 1) / (float)((ar->v2d.cur.xmax - ar->v2d.cur.xmin)); + zoomy = (float)(ar->winrct.ymax - ar->winrct.ymin + 1) / (float)((ar->v2d.cur.ymax - ar->v2d.cur.ymin)); + + if (do_scale_applied) { + zoomx /= width; + zoomy /= height; + } + + x += v2d->tot.xmin * zoomx; + y += v2d->tot.ymin * zoomy; + + /* frame the image */ + maxdim = maxf(width, height); + if (width == height) { + xofs = yofs = 0; + } + else if (width < height) { + xofs = ((height - width) / -2.0f) * zoomx; + yofs = 0.0f; + } + else { /* (width > height) */ + xofs = 0.0f; + yofs = ((width - height) / -2.0f) * zoomy; + } + + /* apply transformation so mask editing tools will assume drawing from the origin in normalized space */ + glPushMatrix(); + glTranslatef(x + xofs, y + yofs, 0); + glScalef(maxdim * zoomx, maxdim * zoomy, 0); + + if (stabmat) { + glMultMatrixf(stabmat); + } + /* draw! */ draw_masklays(mask, draw_flag, draw_type, width, height); + + if (do_post_draw) { + ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); + } + + glPopMatrix(); +} + +void ED_mask_draw_frames(Mask *mask, ARegion *ar, const int cfra, const int sfra, const int efra) +{ + const float framelen = ar->winx / (float)(efra - sfra + 1); + + MaskLayer *masklay = BKE_mask_layer_active(mask); + + glBegin(GL_LINES); + glColor4ub(255, 175, 0, 255); + + if (masklay) { + MaskLayerShape *masklay_shape; + + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + int frame = masklay_shape->frame; + + /* draw_keyframe(i, CFRA, sfra, framelen, 1); */ + int height = (frame == cfra) ? 22 : 10; + int x = (frame - sfra) * framelen; + glVertex2i(x, 0); + glVertex2i(x, height); + } + } + + glEnd(); } diff --git a/source/blender/editors/mask/mask_edit.c b/source/blender/editors/mask/mask_edit.c index b9522540e67..85a8ae11111 100644 --- a/source/blender/editors/mask/mask_edit.c +++ b/source/blender/editors/mask/mask_edit.c @@ -42,10 +42,14 @@ #include "ED_screen.h" #include "ED_mask.h" /* own include */ +#include "ED_image.h" #include "ED_object.h" /* ED_keymap_proportional_maskmode only */ #include "ED_clip.h" +#include "ED_sequencer.h" #include "ED_transform.h" +#include "UI_view2d.h" + #include "RNA_access.h" #include "mask_intern.h" /* own include */ @@ -54,55 +58,113 @@ int ED_maskedit_poll(bContext *C) { - SpaceClip *sc = CTX_wm_space_clip(C); - - if (sc) { - return ED_space_clip_maskedit_poll(C); + ScrArea *sa = CTX_wm_area(C); + if (sa) { + switch (sa->spacetype) { + case SPACE_CLIP: + return ED_space_clip_maskedit_poll(C); + case SPACE_SEQ: + return ED_space_sequencer_maskedit_poll(C); + case SPACE_IMAGE: + return ED_space_image_maskedit_poll(C); + } } - return FALSE; } int ED_maskedit_mask_poll(bContext *C) { - SpaceClip *sc = CTX_wm_space_clip(C); - - if (sc) { - return ED_space_clip_maskedit_mask_poll(C); + ScrArea *sa = CTX_wm_area(C); + if (sa) { + switch (sa->spacetype) { + case SPACE_CLIP: + return ED_space_clip_maskedit_mask_poll(C); + case SPACE_SEQ: + return ED_space_sequencer_maskedit_mask_poll(C); + case SPACE_IMAGE: + return ED_space_image_maskedit_mask_poll(C); + } } - return FALSE; } /********************** registration *********************/ -void ED_mask_mouse_pos(const bContext *C, wmEvent *event, float co[2]) +/* takes event->mval */ +void ED_mask_mouse_pos(ScrArea *sa, ARegion *ar, const int mval[2], float co[2]) { - SpaceClip *sc = CTX_wm_space_clip(C); - - if (sc) { - ED_clip_mouse_pos(C, event, co); - BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co); + if (sa) { + switch (sa->spacetype) { + case SPACE_CLIP: + { + SpaceClip *sc = sa->spacedata.first; + ED_clip_mouse_pos(sc, ar, mval, co); + BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co); + break; + } + case SPACE_SEQ: + { + UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &co[0], &co[1]); + break; + } + case SPACE_IMAGE: + { + float frame_size[2]; + SpaceImage *sima = sa->spacedata.first; + ED_space_image_get_size_fl(sima, frame_size); + ED_image_mouse_pos(sima, ar, mval, co); + BKE_mask_coord_from_frame(co, co, frame_size); + break; + } + default: + /* possible other spaces from which mask editing is available */ + BLI_assert(0); + zero_v2(co); + break; + } } else { - /* possible other spaces from which mask editing is available */ + BLI_assert(0); zero_v2(co); } } /* input: x/y - mval space * output: xr/yr - mask point space */ -void ED_mask_point_pos(const bContext *C, float x, float y, float *xr, float *yr) +void ED_mask_point_pos(ScrArea *sa, ARegion *ar, float x, float y, float *xr, float *yr) { - SpaceClip *sc = CTX_wm_space_clip(C); float co[2]; - if (sc) { - ED_clip_point_stable_pos(C, x, y, &co[0], &co[1]); - BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co); + if (sa) { + switch (sa->spacetype) { + case SPACE_CLIP: + { + SpaceClip *sc = sa->spacedata.first; + ED_clip_point_stable_pos(sc, ar, x, y, &co[0], &co[1]); + BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co); + break; + } + case SPACE_SEQ: + zero_v2(co); /* MASKTODO */ + break; + case SPACE_IMAGE: + { + float frame_size[2]; + SpaceImage *sima = sa->spacedata.first; + ED_space_image_get_size_fl(sima, frame_size); + ED_image_point_pos(sima, ar, x, y, &co[0], &co[1]); + BKE_mask_coord_from_frame(co, co, frame_size); + break; + } + default: + /* possible other spaces from which mask editing is available */ + BLI_assert(0); + zero_v2(co); + break; + } } else { - /* possible other spaces from which mask editing is available */ + BLI_assert(0); zero_v2(co); } @@ -110,21 +172,45 @@ void ED_mask_point_pos(const bContext *C, float x, float y, float *xr, float *yr *yr = co[1]; } -void ED_mask_point_pos__reverse(const bContext *C, float x, float y, float *xr, float *yr) +void ED_mask_point_pos__reverse(ScrArea *sa, ARegion *ar, float x, float y, float *xr, float *yr) { - SpaceClip *sc = CTX_wm_space_clip(C); - ARegion *ar = CTX_wm_region(C); - float co[2]; - if (sc && ar) { - co[0] = x; - co[1] = y; - BKE_mask_coord_to_movieclip(sc->clip, &sc->user, co, co); - ED_clip_point_stable_pos__reverse(C, co, co); + if (sa) { + switch (sa->spacetype) { + case SPACE_CLIP: + { + SpaceClip *sc = sa->spacedata.first; + co[0] = x; + co[1] = y; + BKE_mask_coord_to_movieclip(sc->clip, &sc->user, co, co); + ED_clip_point_stable_pos__reverse(sc, ar, co, co); + break; + } + case SPACE_SEQ: + zero_v2(co); /* MASKTODO */ + break; + case SPACE_IMAGE: + { + float frame_size[2]; + SpaceImage *sima = sa->spacedata.first; + ED_space_image_get_size_fl(sima, frame_size); + + co[0] = x; + co[1] = y; + BKE_mask_coord_to_frame(co, co, frame_size); + ED_image_point_pos__reverse(sima, ar, co, co); + break; + } + default: + /* possible other spaces from which mask editing is available */ + BLI_assert(0); + zero_v2(co); + break; + } } else { - /* possible other spaces from which mask editing is available */ + BLI_assert(0); zero_v2(co); } @@ -132,60 +218,159 @@ void ED_mask_point_pos__reverse(const bContext *C, float x, float y, float *xr, *yr = co[1]; } -void ED_mask_size(const bContext *C, int *width, int *height) +void ED_mask_get_size(ScrArea *sa, int *width, int *height) { - ScrArea *sa = CTX_wm_area(C); if (sa && sa->spacedata.first) { - if (sa->spacetype == SPACE_CLIP) { - ED_space_clip_get_size(C, width, height); - return; - } - else if (sa->spacetype == SPACE_SEQ) { - Scene *scene = CTX_data_scene(C); - *width = (scene->r.size * scene->r.xsch) / 100; - *height = (scene->r.size * scene->r.ysch) / 100; - return; + switch (sa->spacetype) { + case SPACE_CLIP: + { + SpaceClip *sc = sa->spacedata.first; + ED_space_clip_get_size(sc, width, height); + break; + } + case SPACE_SEQ: + { +// Scene *scene = CTX_data_scene(C); +// *width = (scene->r.size * scene->r.xsch) / 100; +// *height = (scene->r.size * scene->r.ysch) / 100; + break; + } + case SPACE_IMAGE: + { + SpaceImage *sima = sa->spacedata.first; + ED_space_image_get_size(sima, width, height); + break; + } + default: + /* possible other spaces from which mask editing is available */ + BLI_assert(0); + *width = 0; + *height = 0; + break; } } - - /* possible other spaces from which mask editing is available */ - *width = 0; - *height = 0; + else { + BLI_assert(0); + *width = 0; + *height = 0; + } } -void ED_mask_aspect(const bContext *C, float *aspx, float *aspy) +void ED_mask_zoom(ScrArea *sa, ARegion *ar, float *zoomx, float *zoomy) { - SpaceClip *sc = CTX_wm_space_clip(C); - - if (sc) { - ED_space_clip_get_aspect(sc, aspx, aspy); + if (sa && sa->spacedata.first) { + switch (sa->spacetype) { + case SPACE_CLIP: + { + SpaceClip *sc = sa->spacedata.first; + ED_space_clip_get_zoom(sc, ar, zoomx, zoomy); + break; + } + case SPACE_SEQ: + { + *zoomx = *zoomy = 1.0f; + break; + } + case SPACE_IMAGE: + { + SpaceImage *sima = sa->spacedata.first; + ED_space_image_get_zoom(sima, ar, zoomx, zoomy); + break; + } + default: + /* possible other spaces from which mask editing is available */ + BLI_assert(0); + *zoomx = *zoomy = 1.0f; + break; + } } else { - /* possible other spaces from which mask editing is available */ - *aspx = 1.0f; - *aspy = 1.0f; + BLI_assert(0); + *zoomx = *zoomy = 1.0f; } } -void ED_mask_pixelspace_factor(const bContext *C, float *scalex, float *scaley) +void ED_mask_get_aspect(ScrArea *sa, ARegion *UNUSED(ar), float *aspx, float *aspy) { - SpaceClip *sc = CTX_wm_space_clip(C); - - if (sc) { - int width, height; - float zoomx, zoomy, aspx, aspy; - - ED_space_clip_get_size(C, &width, &height); - ED_space_clip_get_zoom(C, &zoomx, &zoomy); - ED_space_clip_get_aspect(sc, &aspx, &aspy); + if (sa && sa->spacedata.first) { + switch (sa->spacetype) { + case SPACE_CLIP: + { + SpaceClip *sc = sa->spacedata.first; + ED_space_clip_get_aspect(sc, aspx, aspy); + break; + } + case SPACE_SEQ: + { + *aspx = *aspy = 1.0f; /* MASKTODO - render aspect? */ + break; + } + case SPACE_IMAGE: + { + SpaceImage *sima = sa->spacedata.first; + ED_space_image_get_aspect(sima, aspx, aspy); + break; + } + default: + /* possible other spaces from which mask editing is available */ + BLI_assert(0); + *aspx = *aspy = 1.0f; + break; + } + } + else { + BLI_assert(0); + *aspx = *aspy = 1.0f; + } +} - *scalex = ((float)width * aspx) * zoomx; - *scaley = ((float)height * aspy) * zoomy; +void ED_mask_pixelspace_factor(ScrArea *sa, ARegion *ar, float *scalex, float *scaley) +{ + if (sa && sa->spacedata.first) { + switch (sa->spacetype) { + case SPACE_CLIP: + { + SpaceClip *sc = sa->spacedata.first; + int width, height; + float zoomx, zoomy, aspx, aspy; + + ED_space_clip_get_size(sc, &width, &height); + ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy); + ED_space_clip_get_aspect(sc, &aspx, &aspy); + + *scalex = ((float)width * aspx) * zoomx; + *scaley = ((float)height * aspy) * zoomy; + break; + } + case SPACE_SEQ: + { + *scalex = *scaley = 1.0f; /* MASKTODO? */ + break; + } + case SPACE_IMAGE: + { + SpaceImage *sima = sa->spacedata.first; + int width, height; + float zoomx, zoomy, aspx, aspy; + + ED_space_image_get_size(sima, &width, &height); + ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy); + ED_space_image_get_aspect(sima, &aspx, &aspy); + + *scalex = ((float)width * aspx) * zoomx; + *scaley = ((float)height * aspy) * zoomy; + break; + } + default: + /* possible other spaces from which mask editing is available */ + BLI_assert(0); + *scalex = *scaley = 1.0f; + break; + } } else { - /* possible other spaces from which mask editing is available */ - *scalex = 1.0f; - *scaley = 1.0f; + BLI_assert(0); + *scalex = *scaley = 1.0f; } } @@ -313,8 +498,6 @@ void ED_keymap_mask(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MASK_OT_normals_make_consistent", NKEY, KM_PRESS, KM_CTRL, 0); // WM_keymap_add_item(keymap, "MASK_OT_feather_weight_clear", SKEY, KM_PRESS, KM_ALT, 0); /* ... matches curve editmode */ - RNA_enum_set(WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, KM_ALT, 0)->ptr, - "mode", TFM_MASK_SHRINKFATTEN); /* relationships */ WM_keymap_add_item(keymap, "MASK_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); @@ -323,8 +506,16 @@ void ED_keymap_mask(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MASK_OT_shape_key_insert", IKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "MASK_OT_shape_key_clear", IKEY, KM_PRESS, KM_ALT, 0); + /* for image editor only */ + WM_keymap_add_item(keymap, "UV_OT_cursor_set", ACTIONMOUSE, KM_PRESS, 0, 0); - transform_keymap_for_space(keyconf, keymap, SPACE_CLIP); + /* Transform (don't use transform_keymap_for_space() since this maps to different spaces) */ + WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", GKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", EVT_TWEAK_S, KM_ANY, 0, 0); + WM_keymap_add_item(keymap, "TRANSFORM_OT_resize", SKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "TRANSFORM_OT_rotate", RKEY, KM_PRESS, 0, 0); + kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, KM_ALT, 0); + RNA_enum_set(kmi->ptr, "mode", TFM_MASK_SHRINKFATTEN); } void ED_operatormacros_mask(void) diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h index bad0a9c28a8..ffd4afca182 100644 --- a/source/blender/editors/mask/mask_intern.h +++ b/source/blender/editors/mask/mask_intern.h @@ -99,15 +99,6 @@ void ED_mask_select_flush_all(struct Mask *mask); int ED_maskedit_poll(struct bContext *C); int ED_maskedit_mask_poll(struct bContext *C); -void ED_mask_size(const struct bContext *C, int *width, int *height); -void ED_mask_aspect(const struct bContext *C, float *aspx, float *aspy); - -void ED_mask_pixelspace_factor(const struct bContext *C, float *scalex, float *scaley); -void ED_mask_mouse_pos(const struct bContext *C, struct wmEvent *event, float co[2]); - -void ED_mask_point_pos(const struct bContext *C, float x, float y, float *xr, float *yr); -void ED_mask_point_pos__reverse(const struct bContext *C, float x, float y, float *xr, float *yr); - /* mask_shapekey.c */ void MASK_OT_shape_key_insert(struct wmOperatorType *ot); void MASK_OT_shape_key_clear(struct wmOperatorType *ot); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index c8246fd53bc..1df1e5a66fe 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -45,10 +45,11 @@ #include "WM_api.h" #include "WM_types.h" -#include "ED_screen.h" -#include "ED_mask.h" #include "ED_clip.h" +#include "ED_image.h" #include "ED_keyframing.h" +#include "ED_mask.h" +#include "ED_screen.h" #include "RNA_access.h" #include "RNA_define.h" @@ -61,17 +62,19 @@ MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C, Mask *mask, float MaskLayer **masklay_r, MaskSpline **spline_r, int *is_handle_r, float *score) { + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + MaskLayer *masklay; MaskLayer *point_masklay = NULL; MaskSpline *point_spline = NULL; MaskSplinePoint *point = NULL; - float co[2], aspx, aspy; + float co[2]; float len = FLT_MAX, scalex, scaley; int is_handle = FALSE, width, height; - ED_mask_size(C, &width, &height); - ED_mask_aspect(C, &aspx, &aspy); - ED_mask_pixelspace_factor(C, &scalex, &scaley); + ED_mask_get_size(sa, &width, &height); + ED_mask_pixelspace_factor(sa, ar, &scalex, &scaley); co[0] = normal_co[0] * scalex; co[1] = normal_co[1] * scaley; @@ -157,17 +160,19 @@ int ED_mask_feather_find_nearest(const bContext *C, Mask *mask, float normal_co[ MaskLayer **masklay_r, MaskSpline **spline_r, MaskSplinePoint **point_r, MaskSplinePointUW **uw_r, float *score) { + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + MaskLayer *masklay, *point_masklay = NULL; MaskSpline *point_spline = NULL; MaskSplinePoint *point = NULL; MaskSplinePointUW *uw = NULL; float len = FLT_MAX, co[2]; - float scalex, scaley, aspx, aspy; + float scalex, scaley; int width, height; - ED_mask_size(C, &width, &height); - ED_mask_aspect(C, &aspx, &aspy); - ED_mask_pixelspace_factor(C, &scalex, &scaley); + ED_mask_get_size(sa, &width, &height); + ED_mask_pixelspace_factor(sa, ar, &scalex, &scaley); co[0] = normal_co[0] * scalex; co[1] = normal_co[1] * scaley; @@ -255,7 +260,7 @@ int ED_mask_feather_find_nearest(const bContext *C, Mask *mask, float normal_co[ static int mask_new_exec(bContext *C, wmOperator *op) { - SpaceClip *sc = CTX_wm_space_clip(C); + ScrArea *sa = CTX_wm_area(C); Mask *mask; char name[MAX_ID_NAME - 2]; @@ -263,8 +268,27 @@ static int mask_new_exec(bContext *C, wmOperator *op) mask = BKE_mask_new(name); - if (sc) - ED_space_clip_set_mask(C, sc, mask); + if (sa && sa->spacedata.first) { + switch (sa->spacetype) { + case SPACE_CLIP: + { + SpaceClip *sc = sa->spacedata.first; + ED_space_clip_set_mask(C, sc, mask); + break; + } + case SPACE_SEQ: + { + /* do nothing */ + break; + } + case SPACE_IMAGE: + { + SpaceImage *sima = sa->spacedata.first; + ED_space_image_set_mask(C, sima, mask); + break; + } + } + } return OPERATOR_FINISHED; } @@ -406,6 +430,9 @@ static int slide_point_check_initial_feather(MaskSpline *spline) static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) { + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + Mask *mask = CTX_data_edit_mask(C); SlidePointData *customdata = NULL; MaskLayer *masklay, *cv_masklay, *feather_masklay; @@ -417,8 +444,8 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) float co[2], cv_score, feather_score; const float threshold = 19; - ED_mask_mouse_pos(C, event, co); - ED_mask_size(C, &width, &height); + ED_mask_mouse_pos(sa, ar, event->mval, co); + ED_mask_get_size(sa, &width, &height); cv_point = ED_mask_point_find_nearest(C, mask, co, threshold, &cv_masklay, &cv_spline, &is_handle, &cv_score); @@ -482,7 +509,7 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) copy_m3_m3(customdata->vec, point->bezt.vec); if (BKE_mask_point_has_handle(point)) BKE_mask_point_handle(point, customdata->handle); - ED_mask_mouse_pos(C, event, customdata->co); + ED_mask_mouse_pos(sa, ar, event->mval, customdata->co); } return customdata; @@ -499,6 +526,7 @@ static int slide_point_invoke(bContext *C, wmOperator *op, wmEvent *event) WM_event_add_modal_handler(C, op); +#if 0 if (slidedata->uw) { if ((slidedata->uw->flag & SELECT) == 0) { ED_mask_select_toggle_all(mask, SEL_DESELECT); @@ -515,6 +543,7 @@ static int slide_point_invoke(bContext *C, wmOperator *op, wmEvent *event) ED_mask_select_flush_all(mask); } +#endif slidedata->masklay->act_spline = slidedata->spline; slidedata->masklay->act_point = slidedata->point; @@ -602,24 +631,28 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) float co[2], dco[2]; switch (event->type) { - case LEFTCTRLKEY: - case RIGHTCTRLKEY: + case LEFTALTKEY: + case RIGHTALTKEY: case LEFTSHIFTKEY: case RIGHTSHIFTKEY: - if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) { + if (ELEM(event->type, LEFTALTKEY, RIGHTALTKEY)) { if (data->action == SLIDE_ACTION_FEATHER) - data->overall_feather = event->val == KM_PRESS; + data->overall_feather = (event->val == KM_PRESS); else - data->curvature_only = event->val == KM_PRESS; + data->curvature_only = (event->val == KM_PRESS); } if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) - data->accurate = event->val == KM_PRESS; + data->accurate = (event->val == KM_PRESS); /* no break! update CV position */ case MOUSEMOVE: - ED_mask_mouse_pos(C, event, co); + { + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + + ED_mask_mouse_pos(sa, ar, event->mval, co); sub_v2_v2v2(dco, co, data->co); if (data->action == SLIDE_ACTION_HANDLE) { @@ -748,6 +781,7 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) DAG_id_tag_update(&data->mask->id, 0); break; + } case LEFTMOUSE: if (event->val == KM_RELEASE) { diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index a2a7a07d089..e746f4258a5 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -147,7 +147,26 @@ void ED_mask_select_toggle_all(Mask *mask, int action) continue; } - ED_mask_layer_select_set(masklay, (action == SEL_SELECT) ? TRUE : FALSE); + if (action == SEL_INVERT) { + /* we don't have generic functons for this, its restricted to this operator + * if one day we need to re-use such functionality, they can be split out */ + + MaskSpline *spline; + if (masklay->restrictflag & MASK_RESTRICT_SELECT) { + continue; + } + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + BKE_mask_point_select_set(point, !MASKPOINT_ISSEL_ANY(point)); + } + } + + } + else { + ED_mask_layer_select_set(masklay, (action == SEL_SELECT) ? TRUE : FALSE); + } } } @@ -343,9 +362,12 @@ static int select_exec(bContext *C, wmOperator *op) static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) { + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + float co[2]; - ED_mask_mouse_pos(C, event, co); + ED_mask_mouse_pos(sa, ar, event->mval, co); RNA_float_set_array(op->ptr, "location", co); @@ -380,6 +402,9 @@ void MASK_OT_select(wmOperatorType *ot) static int border_select_exec(bContext *C, wmOperator *op) { + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; int i; @@ -394,8 +419,8 @@ static int border_select_exec(bContext *C, wmOperator *op) rect.xmax = RNA_int_get(op->ptr, "xmax"); rect.ymax = RNA_int_get(op->ptr, "ymax"); - ED_mask_point_pos(C, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin); - ED_mask_point_pos(C, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax); + ED_mask_point_pos(sa, ar, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin); + ED_mask_point_pos(sa, ar, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax); mode = RNA_int_get(op->ptr, "gesture_mode"); extend = RNA_boolean_get(op->ptr, "extend"); @@ -465,6 +490,9 @@ void MASK_OT_select_border(wmOperatorType *ot) static int do_lasso_select_mask(bContext *C, int mcords[][2], short moves, short select) { + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; int i; @@ -496,7 +524,7 @@ static int do_lasso_select_mask(bContext *C, int mcords[][2], short moves, short float screen_co[2]; /* marker in screen coords */ - ED_mask_point_pos__reverse(C, + ED_mask_point_pos__reverse(sa, ar, point_deform->bezt.vec[1][0], point_deform->bezt.vec[1][1], &screen_co[0], &screen_co[1]); @@ -577,6 +605,9 @@ static int mask_spline_point_inside_ellipse(BezTriple *bezt, float offset[2], fl static int circle_select_exec(bContext *C, wmOperator *op) { + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; int i; @@ -591,16 +622,15 @@ static int circle_select_exec(bContext *C, wmOperator *op) mode = RNA_int_get(op->ptr, "gesture_mode"); - /* TODO - make generic! - this is SpaceClip only! */ /* compute ellipse and position in unified coordinates */ - ED_space_clip_get_size(C, &width, &height); - ED_space_clip_get_zoom(C, &zoomx, &zoomy); + ED_mask_get_size(sa, &width, &height); + ED_mask_zoom(sa, ar, &zoomx, &zoomy); width = height = MAX2(width, height); ellipse[0] = width * zoomx / radius; ellipse[1] = height * zoomy / radius; - ED_mask_point_pos(C, x, y, &offset[0], &offset[1]); + ED_mask_point_pos(sa, ar, x, y, &offset[0], &offset[1]); /* do actual selection */ for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { @@ -663,6 +693,9 @@ void MASK_OT_select_circle(wmOperatorType *ot) static int mask_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event) { + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; MaskSpline *spline; @@ -674,7 +707,7 @@ static int mask_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent * const float threshold = 19; int change = FALSE; - ED_mask_mouse_pos(C, event, co); + ED_mask_mouse_pos(sa, ar, event->mval, co); point = ED_mask_point_find_nearest(C, mask, co, threshold, &masklay, &spline, &is_handle, NULL); diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 5907d066c83..8a3cf87e96a 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -84,6 +84,7 @@ typedef struct KnifeColors { typedef struct KnifeVert { BMVert *v; /* non-NULL if this is an original vert */ ListBase edges; + ListBase faces; float co[3], cageco[3], sco[3]; /* sco is screen coordinates for cageco */ short flag, draw, isface, inspace; @@ -277,6 +278,32 @@ static void knife_add_to_vert_edges(KnifeTool_OpData *kcd, KnifeEdge *kfe) knife_append_list(kcd, &kfe->v2->edges, kfe); } +/* Add faces of an edge to a KnifeVert's faces list. No checks for dups. */ +static void knife_add_edge_faces_to_vert(KnifeTool_OpData *kcd, KnifeVert *kfv, BMEdge *e) +{ + BMIter bmiter; + BMFace *f; + + BM_ITER_ELEM(f, &bmiter, e, BM_FACES_OF_EDGE) { + knife_append_list(kcd, &kfv->faces, f); + } +} + +/* Find a face in common in the two faces lists. + If more than one, return the first; if none, return NULL */ +static BMFace *knife_find_common_face(ListBase *faces1, ListBase *faces2) +{ + Ref *ref1, *ref2; + + for (ref1 = faces1->first; ref1; ref1 = ref1->next) { + for (ref2 = faces2->first; ref2; ref2 = ref2->next) { + if (ref1->ref == ref2->ref) + return (BMFace *)(ref1->ref); + } + } + return NULL; +} + static KnifeVert *new_knife_vert(KnifeTool_OpData *kcd, const float co[3], float *cageco) { KnifeVert *kfv = BLI_mempool_calloc(kcd->kverts); @@ -298,9 +325,15 @@ static KnifeVert *get_bm_knife_vert(KnifeTool_OpData *kcd, BMVert *v) KnifeVert *kfv = BLI_ghash_lookup(kcd->origvertmap, v); if (!kfv) { + BMIter bmiter; + BMFace *f; + kfv = new_knife_vert(kcd, v->co, kcd->cagecos[BM_elem_index_get(v)]); kfv->v = v; BLI_ghash_insert(kcd->origvertmap, v, kfv); + BM_ITER_ELEM(f, &bmiter, v, BM_FACES_OF_VERT) { + knife_append_list(kcd, &kfv->faces, f); + } } return kfv; @@ -389,35 +422,9 @@ static ListBase *knife_get_face_kedges(KnifeTool_OpData *kcd, BMFace *f) } /* finds the proper face to restrict face fill to */ -static void knife_find_basef(KnifeTool_OpData *kcd, KnifeEdge *kfe) +static void knife_find_basef(KnifeEdge *kfe) { - if (!kfe->basef) { - Ref *r1, *r2, *r3, *r4; - - if (kfe->v1->isface || kfe->v2->isface) { - if (kfe->v2->isface) - kfe->basef = kcd->cur.bmface; - else - kfe->basef = kcd->prev.bmface; - } - else { - for (r1 = kfe->v1->edges.first; r1 && !kfe->basef; r1 = r1->next) { - KnifeEdge *ke1 = r1->ref; - for (r2 = ke1->faces.first; r2 && !kfe->basef; r2 = r2->next) { - for (r3 = kfe->v2->edges.first; r3 && !kfe->basef; r3 = r3->next) { - KnifeEdge *ke2 = r3->ref; - - for (r4 = ke2->faces.first; r4 && !kfe->basef; r4 = r4->next) { - if (r2->ref == r4->ref) { - kfe->basef = r2->ref; - } - } - } - } - } - } - /* ok, at this point kfe->basef should be set if any valid possibility exists */ - } + 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) @@ -430,6 +437,7 @@ static KnifeVert *knife_split_edge(KnifeTool_OpData *kcd, KnifeEdge *kfe, float { KnifeEdge *newkfe = new_knife_edge(kcd); Ref *ref; + BMFace *f; float perc, cageco[3], l12; l12 = len_v3v3(kfe->v1->co, kfe->v2->co); @@ -444,6 +452,17 @@ static KnifeVert *knife_split_edge(KnifeTool_OpData *kcd, KnifeEdge *kfe, float newkfe->v1 = kfe->v1; newkfe->v2 = new_knife_vert(kcd, co, cageco); newkfe->v2->draw = 1; + if (kfe->e) { + knife_add_edge_faces_to_vert(kcd, newkfe->v2, kfe->e); + } + else { + /* kfe cuts across an existing face. + If v1 and v2 are in multiple faces together (e.g., if they + are in doubled polys) then this arbitrarily chooses one of them */ + f = knife_find_common_face(&kfe->v1->faces, &kfe->v2->faces); + if (f) + knife_append_list(kcd, &newkfe->v2->faces, f); + } newkfe->basef = kfe->basef; ref = find_ref(&kfe->v1->edges, kfe); @@ -490,6 +509,8 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd) kfe->v1->inspace = kcd->prev.is_space; kfe->draw = !kcd->prev.is_space; kfe->v1->isface = 1; + if (kfe->v1->draw && kcd->prev.bmface) + knife_append_list(kcd, &kfe->v1->faces, kcd->prev.bmface); } if (kcd->cur.vert) { @@ -504,6 +525,8 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd) kfe->v2->draw = !kcd->cur.is_space; kfe->v2->isface = 1; kfe->v2->inspace = kcd->cur.is_space; + if (kfe->v2->draw && kcd->cur.bmface) + knife_append_list(kcd, &kfe->v2->faces, kcd->cur.bmface); if (kcd->cur.is_space) kfe->draw = 0; @@ -511,7 +534,7 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd) kcd->cur.vert = kfe->v2; } - knife_find_basef(kcd, kfe); + knife_find_basef(kfe); knife_add_to_vert_edges(kcd, kfe); @@ -716,6 +739,7 @@ static void knife_add_cut(KnifeTool_OpData *kcd) BMEdgeHit *lh, *lastlh, *firstlh; int i; + /* TODO: not a stable sort! need to figure out what to do for equal lambdas */ qsort(kcd->linehits, kcd->totlinehit, sizeof(BMEdgeHit), verge_linehit); lh = kcd->linehits; @@ -1074,7 +1098,7 @@ static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree, /* for comparing distances, error of intersection depends on triangle scale. * need to scale down before squaring for accurate comparison */ - const float depsilon = 50 * FLT_EPSILON * len_v3_tri_side_max(v1, v2, v3); + const float depsilon = 50 *FLT_EPSILON *len_v3_tri_side_max(v1, v2, v3); const float depsilon_squared = depsilon * depsilon; copy_v3_v3(cos + 0, v1); @@ -1153,7 +1177,7 @@ static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree, hit.kfe = kfe; hit.v = NULL; - knife_find_basef(kcd, kfe); + 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); @@ -2921,7 +2945,8 @@ wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf) {KNF_MODAL_CUT_THROUGH_TOGGLE, "CUT_THROUGH_TOGGLE", 0, "Toggle Cut Through", ""}, {KNF_MODAL_NEW_CUT, "NEW_CUT", 0, "End Current Cut", ""}, {KNF_MODAL_ADD_CUT, "ADD_CUT", 0, "Add Cut", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Knife Tool Modal Map"); diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 7dc0ed78dfc..765091a3d1d 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -2337,7 +2337,7 @@ static int edbm_select_sharp_edges_exec(bContext *C, wmOperator *op) /* edge has exactly two neighboring faces, check angle */ angle = angle_normalized_v3v3(l1->f->no, l2->f->no); - if (fabsf(angle) > sharp) { + if (fabsf(angle) < sharp) { BM_edge_select_set(em->bm, e, TRUE); } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 072c66c60d8..6db8960977a 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -31,6 +31,7 @@ #include "MEM_guardedalloc.h" +#include "DNA_key_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_modifier_types.h" @@ -1532,6 +1533,10 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op) int i, repeat; float clipdist = 0.0f; + int xaxis = RNA_boolean_get(op->ptr, "xaxis"); + int yaxis = RNA_boolean_get(op->ptr, "yaxis"); + int zaxis = RNA_boolean_get(op->ptr, "zaxis"); + /* mirror before smooth */ if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) { EDBM_verts_mirror_cache_begin(em, TRUE); @@ -1563,8 +1568,9 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op) for (i = 0; i < repeat; i++) { if (!EDBM_op_callf(em, op, - "smooth_vert verts=%hv mirror_clip_x=%b mirror_clip_y=%b mirror_clip_z=%b clipdist=%f", - BM_ELEM_SELECT, mirrx, mirry, mirrz, clipdist)) + "smooth_vert verts=%hv mirror_clip_x=%b mirror_clip_y=%b mirror_clip_z=%b clipdist=%f " + "use_axis_x=%b use_axis_y=%b use_axis_z=%b", + BM_ELEM_SELECT, mirrx, mirry, mirrz, clipdist, xaxis, yaxis, zaxis)) { return OPERATOR_CANCELLED; } @@ -1596,6 +1602,9 @@ void MESH_OT_vertices_smooth(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; RNA_def_int(ot->srna, "repeat", 1, 1, 100, "Number of times to smooth the mesh", "", 1, INT_MAX); + RNA_def_boolean(ot->srna, "xaxis", 1, "X-Axis", "Smooth along the X axis"); + RNA_def_boolean(ot->srna, "yaxis", 1, "Y-Axis", "Smooth along the Y axis"); + RNA_def_boolean(ot->srna, "zaxis", 1, "Z-Axis", "Smooth along the Z axis"); } /********************** Smooth/Solid Operators *************************/ @@ -2231,6 +2240,8 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); Mesh *me = obedit->data; + Key *key = me->key; + KeyBlock *kb = NULL; BMEditMesh *em = me->edit_btmesh; BMVert *eve; BMIter iter; @@ -2244,24 +2255,34 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op) totshape = CustomData_number_of_layers(&em->bm->vdata, CD_SHAPEKEY); if (totshape == 0 || shape < 0 || shape >= totshape) return OPERATOR_CANCELLED; - + + /* get shape key - needed for finding reference shape (for add mode only) */ + if (key) { + kb = BLI_findlink(&key->block, shape); + } + + /* perform blending on selected vertices*/ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (!BM_elem_flag_test(eve, BM_ELEM_SELECT) || BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) continue; - + + /* get coordinates of shapekey we're blending from */ sco = CustomData_bmesh_get_n(&em->bm->vdata, eve->head.data, CD_SHAPEKEY, shape); copy_v3_v3(co, sco); - - + if (add) { - mul_v3_fl(co, blend); - add_v3_v3v3(eve->co, eve->co, co); + /* in add mode, we add relative shape key offset */ + if (kb) { + float *rco = CustomData_bmesh_get_n(&em->bm->vdata, eve->head.data, CD_SHAPEKEY, kb->relative); + sub_v3_v3v3(co, co, rco); + } + + madd_v3_v3fl(eve->co, co, blend); } else { + /* in blend mode, we interpolate to the shape key */ interp_v3_v3v3(eve->co, eve->co, co, blend); } - - copy_v3_v3(sco, co); } EDBM_update_generic(C, em, TRUE); @@ -2603,21 +2624,21 @@ static float bm_edge_seg_isect(BMEdge *e, CutCurve *c, int len, char mode, m1 = MAXSLOPE; b1 = x12; } - x2max = MAX2(x21, x22) + 0.001f; /* prevent missed edges */ - x2min = MIN2(x21, x22) - 0.001f; /* due to round off error */ - y2max = MAX2(y21, y22) + 0.001f; - y2min = MIN2(y21, y22) - 0.001f; + x2max = maxf(x21, x22) + 0.001f; /* prevent missed edges */ + x2min = minf(x21, x22) - 0.001f; /* due to round off error */ + y2max = maxf(y21, y22) + 0.001f; + y2min = minf(y21, y22) - 0.001f; /* Found an intersect, calc intersect point */ if (m1 == m2) { /* co-incident lines */ /* cut at 50% of overlap area */ - x1max = MAX2(x11, x12); - x1min = MIN2(x11, x12); - xi = (MIN2(x2max, x1max) + MAX2(x2min, x1min)) / 2.0f; + x1max = maxf(x11, x12); + x1min = minf(x11, x12); + xi = (minf(x2max, x1max) + maxf(x2min, x1min)) / 2.0f; - y1max = MAX2(y11, y12); - y1min = MIN2(y11, y12); - yi = (MIN2(y2max, y1max) + MAX2(y2min, y1min)) / 2.0f; + y1max = maxf(y11, y12); + y1min = minf(y11, y12); + yi = (minf(y2max, y1max) + maxf(y2min, y1min)) / 2.0f; } else if (m2 == MAXSLOPE) { xi = x22; @@ -2823,18 +2844,14 @@ static int mesh_separate_tagged(Main *bmain, Scene *scene, Base *base_old, BMesh BMO_op_callf(bm_old, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE), "delete geom=%hvef context=%i", BM_ELEM_TAG, DEL_FACES); - /* clean up any loose edges */ + /* deselect loose data - this used to get deleted */ BM_ITER_MESH (e, &iter, bm_old, BM_EDGES_OF_MESH) { - if (BM_edge_is_wire(e)) { - BM_edge_kill(bm_old, e); - } + BM_edge_select_set(bm_old, e, FALSE); } /* clean up any loose verts */ BM_ITER_MESH (v, &iter, bm_old, BM_VERTS_OF_MESH) { - if (BM_vert_edge_count(v) == 0) { - BM_vert_kill(bm_old, v); - } + BM_vert_select_set(bm_old, v, FALSE); } BM_mesh_normals_update(bm_new, FALSE); @@ -3770,13 +3787,13 @@ static int bmelemsort_comp(const void *v1, const void *v2) } /* Reorders vertices/edges/faces using a given methods. Loops are not supported. */ -static void sort_bmelem_flag(bContext *C, const int types, const int flag, const int action, +static void sort_bmelem_flag(Scene *scene, Object *ob, + View3D *v3d, RegionView3D *rv3d, + const int types, const int flag, const int action, const int reverse, const unsigned int seed) { - Scene *scene = CTX_data_scene(C); - Object *ob = CTX_data_edit_object(C); - ViewContext vc; - BMEditMesh *em; + BMEditMesh *em = BMEdit_FromObject(ob); + BMVert *ve; BMEdge *ed; BMFace *fa; @@ -3794,9 +3811,6 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (!(types && flag && action)) return; - em_setup_viewcontext(C, &vc); - em = vc.em; - if (types & BM_VERT) totelem[0] = em->bm->totvert; if (types & BM_EDGE) @@ -3805,7 +3819,6 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const totelem[2] = em->bm->totface; if (ELEM(action, SRT_VIEW_ZAXIS, SRT_VIEW_XAXIS)) { - RegionView3D *rv3d = ED_view3d_context_rv3d(C); float mat[4][4]; float fact = reverse ? -1.0 : 1.0; int coidx = (action == SRT_VIEW_ZAXIS) ? 2 : 0; @@ -3873,7 +3886,6 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const } else if (action == SRT_CURSOR_DISTANCE) { - View3D *v3d = CTX_wm_view3d(C); float cur[3]; float mat[4][4]; float fact = reverse ? -1.0 : 1.0; @@ -4203,18 +4215,32 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const static int edbm_sort_elements_exec(bContext *C, wmOperator *op) { + Scene *scene = CTX_data_scene(C); + Object *ob = CTX_data_edit_object(C); + + /* may be NULL */ + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d = ED_view3d_context_rv3d(C); + int action = RNA_enum_get(op->ptr, "type"); PropertyRNA *prop_elem_types = RNA_struct_find_property(op->ptr, "elements"); - int elem_types = 0; int reverse = RNA_boolean_get(op->ptr, "reverse"); unsigned int seed = RNA_int_get(op->ptr, "seed"); + int elem_types = 0; + + if (ELEM(action, SRT_VIEW_ZAXIS, SRT_VIEW_XAXIS)) { + if (rv3d == NULL) { + BKE_report(op->reports, RPT_ERROR, "View not found, can't sort by view axis"); + return OPERATOR_CANCELLED; + } + } /* If no elem_types set, use current selection mode to set it! */ if (RNA_property_is_set(op->ptr, prop_elem_types)) { elem_types = RNA_property_enum_get(op->ptr, prop_elem_types); } else { - BMEditMesh *em = BMEdit_FromObject(CTX_data_edit_object(C)); + BMEditMesh *em = BMEdit_FromObject(ob); if (em->selectmode & SCE_SELECT_VERTEX) elem_types |= BM_VERT; if (em->selectmode & SCE_SELECT_EDGE) @@ -4224,7 +4250,8 @@ static int edbm_sort_elements_exec(bContext *C, wmOperator *op) RNA_enum_set(op->ptr, "elements", elem_types); } - sort_bmelem_flag(C, elem_types, BM_ELEM_SELECT, action, reverse, seed); + sort_bmelem_flag(scene, ob, v3d, rv3d, + elem_types, BM_ELEM_SELECT, action, reverse, seed); return OPERATOR_FINISHED; } @@ -4637,6 +4664,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_RUNNING_MODAL; } } + switch (event->type) { case ESCKEY: case RIGHTMOUSE: @@ -4669,7 +4697,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) edbm_bevel_calc(C, op); edbm_bevel_update_header(op, C); } - return OPERATOR_RUNNING_MODAL; + break; case LEFTMOUSE: case PADENTER: @@ -4686,7 +4714,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) edbm_bevel_calc(C, op); edbm_bevel_update_header(op, C); } - return OPERATOR_RUNNING_MODAL; + break; case DKEY: if (event->val == KM_PRESS) { @@ -4696,7 +4724,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) edbm_bevel_calc(C, op); edbm_bevel_update_header(op, C); } - return OPERATOR_RUNNING_MODAL; + break; } return OPERATOR_RUNNING_MODAL; @@ -4776,7 +4804,12 @@ static void edbm_inset_update_header(wmOperator *op, bContext *C) { InsetData *opdata = op->customdata; - static char str[] = "Confirm: Enter/LClick, Cancel: (Esc/RClick), thickness: %s, depth (Ctrl to tweak): %s (%s), Outset (O): (%s)"; + static const char str[] = "Confirm: Enter/LClick, " + "Cancel: (Esc/RClick), " + "thickness: %s, " + "depth (Ctrl to tweak): %s (%s), " + "Outset (O): (%s), " + "Boundary (B): (%s)"; char msg[HEADER_LENGTH]; ScrArea *sa = CTX_wm_area(C); @@ -4793,7 +4826,8 @@ static void edbm_inset_update_header(wmOperator *op, bContext *C) flts_str, flts_str + NUM_STR_REP_LEN, opdata->modify_depth ? "On" : "Off", - RNA_boolean_get(op->ptr, "use_outset") ? "On" : "Off" + RNA_boolean_get(op->ptr, "use_outset") ? "On" : "Off", + RNA_boolean_get(op->ptr, "use_boundary") ? "On" : "Off" ); ED_area_headerprint(sa, msg); @@ -4959,7 +4993,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) if (handleNumInput(&opdata->num_input, event)) { applyNumInput(&opdata->num_input, amounts); - amounts[0] = MAX2(amounts[0], 0.0f); + amounts[0] = maxf(amounts[0], 0.0f); RNA_float_set(op->ptr, "thickness", amounts[0]); RNA_float_set(op->ptr, "depth", amounts[1]); @@ -4973,6 +5007,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) } } } + switch (event->type) { case ESCKEY: case RIGHTMOUSE: @@ -4999,7 +5034,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) if (opdata->modify_depth) RNA_float_set(op->ptr, "depth", amount); else { - amount = MAX2(amount, 0.0f); + amount = maxf(amount, 0.0f); RNA_float_set(op->ptr, "thickness", amount); } @@ -5010,7 +5045,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED; } } - return OPERATOR_RUNNING_MODAL; + break; case LEFTMOUSE: case PADENTER: @@ -5032,7 +5067,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) opdata->shift_amount = 0.0f; opdata->shift = FALSE; } - return OPERATOR_RUNNING_MODAL; + break; case LEFTCTRLKEY: case RIGHTCTRLKEY: @@ -5057,7 +5092,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) opdata->initial_length = len_v2(mlen); edbm_inset_update_header(op, C); - return OPERATOR_RUNNING_MODAL; + break; } case OKEY: @@ -5066,13 +5101,26 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) RNA_boolean_set(op->ptr, "use_outset", !use_outset); if (edbm_inset_calc(C, op)) { edbm_inset_update_header(op, C); - return OPERATOR_RUNNING_MODAL; } else { edbm_inset_cancel(C, op); return OPERATOR_CANCELLED; } } + break; + case BKEY: + if (event->val == KM_PRESS) { + int use_boundary = RNA_boolean_get(op->ptr, "use_boundary"); + RNA_boolean_set(op->ptr, "use_boundary", !use_boundary); + if (edbm_inset_calc(C, op)) { + edbm_inset_update_header(op, C); + } + else { + edbm_inset_cancel(C, op); + return OPERATOR_CANCELLED; + } + } + break; } return OPERATOR_RUNNING_MODAL; diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 21eab5bd4dc..d90735ca5ac 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -105,6 +105,8 @@ #include "UI_interface.h" #include "UI_resources.h" +#include "GPU_material.h" + #include "object_intern.h" /* this is an exact copy of the define in rna_lamp.c @@ -893,12 +895,24 @@ void OBJECT_OT_group_instance_add(wmOperatorType *ot) /**************************** Delete Object *************************/ +static void object_delete_check_glsl_update(Object *ob) +{ + /* some objects could affect on GLSL shading, make sure GLSL settings + * are being tagged to be updated when object is removing from scene + */ + if (ob->type == OB_LAMP) { + if (ob->gpulamp.first) + GPU_lamp_free(ob); + } +} + /* remove base from a specific scene */ /* note: now unlinks constraints as well */ void ED_base_object_free_and_unlink(Main *bmain, Scene *scene, Base *base) { DAG_id_type_tag(bmain, ID_OB); BLI_remlink(&scene->base, base); + object_delete_check_glsl_update(base->object); BKE_libblock_free_us(&bmain->object, base->object); if (scene->basact == base) scene->basact = NULL; MEM_freeN(base); diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 3d9e62b1a16..1b18bfe193a 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -212,10 +212,10 @@ int ED_object_iter_other(Main *bmain, Object *orig_ob, int include_orig, int totfound = include_orig ? 0 : 1; for (ob = bmain->object.first; ob && totfound < users; - ob = ob->id.next) + ob = ob->id.next) { if (((ob != orig_ob) || include_orig) && - (ob->data == orig_ob->data)) + (ob->data == orig_ob->data)) { if (callback(ob, callback_data)) return TRUE; @@ -233,7 +233,7 @@ int ED_object_iter_other(Main *bmain, Object *orig_ob, int include_orig, static int object_has_modifier_cb(Object *ob, void *data) { - ModifierType type = *((ModifierType*)data); + ModifierType type = *((ModifierType *)data); return object_has_modifier(ob, NULL, type); } @@ -244,7 +244,7 @@ static int object_has_modifier_cb(Object *ob, void *data) int ED_object_multires_update_totlevels_cb(Object *ob, void *totlevel_v) { ModifierData *md; - int totlevel = *((int*)totlevel_v); + int totlevel = *((int *)totlevel_v); for (md = ob->modifiers.first; md; md = md->next) { if (md->type == eModifierType_Multires) { @@ -1148,8 +1148,8 @@ static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op) multiresModifier_del_levels(mmd, ob, 1); ED_object_iter_other(CTX_data_main(C), ob, TRUE, - ED_object_multires_update_totlevels_cb, - &mmd->totlvl); + ED_object_multires_update_totlevels_cb, + &mmd->totlvl); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); @@ -1192,8 +1192,8 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op) multiresModifier_subdivide(mmd, ob, 0, mmd->simple); ED_object_iter_other(CTX_data_main(C), ob, TRUE, - ED_object_multires_update_totlevels_cb, - &mmd->totlvl); + ED_object_multires_update_totlevels_cb, + &mmd->totlvl); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); @@ -1361,7 +1361,8 @@ void OBJECT_OT_multires_external_save(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; - WM_operator_properties_filesel(ot, FOLDERFILE | BTXFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | BTXFILE, FILE_SPECIAL, FILE_SAVE, + WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); edit_modifier_properties(ot); } @@ -1518,8 +1519,8 @@ static void skin_root_clear(BMesh *bm, BMVert *bm_vert, GHash *visited) static int skin_root_mark_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = CTX_data_edit_object(C); - Mesh *me = ob->data; - BMesh *bm = me->edit_btmesh->bm; + BMEditMesh *em = BMEdit_FromObject(ob); + BMesh *bm = em->bm; BMVert *bm_vert; BMIter bm_iter; GHash *visited; @@ -1574,12 +1575,16 @@ typedef enum { static int skin_loose_mark_clear_exec(bContext *C, wmOperator *op) { Object *ob = CTX_data_edit_object(C); - Mesh *me = ob->data; - BMesh *bm = me->edit_btmesh->bm; + BMEditMesh *em = BMEdit_FromObject(ob); + BMesh *bm = em->bm; BMVert *bm_vert; BMIter bm_iter; SkinLooseAction action = RNA_enum_get(op->ptr, "action"); + if (!CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) { + return OPERATOR_CANCELLED; + } + BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) { if (bm_vert->head.hflag & BM_ELEM_SELECT) { MVertSkin *vs = CustomData_bmesh_get(&bm->vdata, @@ -1628,11 +1633,15 @@ void OBJECT_OT_skin_loose_mark_clear(wmOperatorType *ot) static int skin_radii_equalize_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = CTX_data_edit_object(C); - Mesh *me = ob->data; - BMesh *bm = me->edit_btmesh->bm; + BMEditMesh *em = BMEdit_FromObject(ob); + BMesh *bm = em->bm; BMVert *bm_vert; BMIter bm_iter; + if (!CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) { + return OPERATOR_CANCELLED; + } + BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) { if (bm_vert->head.hflag & BM_ELEM_SELECT) { MVertSkin *vs = CustomData_bmesh_get(&bm->vdata, @@ -1804,9 +1813,15 @@ static int skin_armature_create_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C), *arm_ob; + Mesh *me = ob->data; ModifierData *skin_md; ArmatureModifierData *arm_md; + if (!CustomData_has_layer(&me->vdata, CD_MVERT_SKIN)) { + BKE_reportf(op->reports, RPT_WARNING, "Mesh '%s' has no skin vertex data", me->id.name + 2); + return OPERATOR_CANCELLED; + } + /* create new armature */ arm_ob = modifier_skin_armature_create(scene, ob); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 1c48a8bfcab..561ebafc0d7 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -47,6 +47,7 @@ #include "DNA_speaker_types.h" #include "DNA_world_types.h" #include "DNA_object_types.h" +#include "DNA_vfont_types.h" #include "BLI_math.h" #include "BLI_listbase.h" @@ -135,6 +136,9 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) em = me->edit_btmesh; + EDBM_mesh_normals_update(em); + BMEdit_RecalcTessellation(em); + /* derivedMesh might be needed for solving parenting, * so re-create it here */ makeDerivedMesh(scene, obedit, em, CD_MASK_BAREMESH, 0); @@ -1281,20 +1285,21 @@ enum { MAKE_LINKS_ANIMDATA, MAKE_LINKS_GROUP, MAKE_LINKS_DUPLIGROUP, - MAKE_LINKS_MODIFIERS + MAKE_LINKS_MODIFIERS, + MAKE_LINKS_FONTS }; /* Return 1 if make link data is allow, zero otherwise */ -static int allow_make_links_data(const int type, Object *ob, Object *obt) +static int allow_make_links_data(const int type, Object *ob_src, Object *ob_dst) { switch (type) { case MAKE_LINKS_OBDATA: - if (ob->type == obt->type && ob->type != OB_EMPTY) + if (ob_src->type == ob_dst->type && ob_src->type != OB_EMPTY) return 1; break; case MAKE_LINKS_MATERIALS: - if (OB_TYPE_SUPPORT_MATERIAL(ob->type) && - OB_TYPE_SUPPORT_MATERIAL(obt->type)) + if (OB_TYPE_SUPPORT_MATERIAL(ob_src->type) && + OB_TYPE_SUPPORT_MATERIAL(ob_dst->type)) { return 1; } @@ -1304,9 +1309,17 @@ static int allow_make_links_data(const int type, Object *ob, Object *obt) case MAKE_LINKS_DUPLIGROUP: return 1; case MAKE_LINKS_MODIFIERS: - if (ob->type != OB_EMPTY && obt->type != OB_EMPTY) + if (ob_src->type != OB_EMPTY && ob_dst->type != OB_EMPTY) return 1; break; + case MAKE_LINKS_FONTS: + if ((ob_src->data != ob_dst->data) && + (ob_src->type == OB_FONT) && + (ob_dst->type == OB_FONT)) + { + return 1; + } + break; } return 0; } @@ -1390,6 +1403,27 @@ static int make_links_data_exec(bContext *C, wmOperator *op) BKE_object_link_modifiers(ob_dst, ob_src); ob_dst->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; break; + case MAKE_LINKS_FONTS: + { + Curve *cu_src = ob_src->data; + Curve *cu_dst = ob_dst->data; + + if (cu_dst->vfont) cu_dst->vfont->id.us--; + cu_dst->vfont = cu_src->vfont; + id_us_plus((ID *)cu_dst->vfont); + if (cu_dst->vfontb) cu_dst->vfontb->id.us--; + cu_dst->vfontb = cu_src->vfontb; + id_us_plus((ID *)cu_dst->vfontb); + if (cu_dst->vfonti) cu_dst->vfonti->id.us--; + cu_dst->vfonti = cu_src->vfonti; + id_us_plus((ID *)cu_dst->vfonti); + if (cu_dst->vfontbi) cu_dst->vfontbi->id.us--; + cu_dst->vfontbi = cu_src->vfontbi; + id_us_plus((ID *)cu_dst->vfontbi); + + ob_dst->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; + break; + } } } } @@ -1446,6 +1480,7 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot) {MAKE_LINKS_GROUP, "GROUPS", 0, "Group", ""}, {MAKE_LINKS_DUPLIGROUP, "DUPLIGROUP", 0, "DupliGroup", ""}, {MAKE_LINKS_MODIFIERS, "MODIFIERS", 0, "Modifiers", ""}, + {MAKE_LINKS_FONTS, "FONTS", 0, "Fonts", ""}, {0, NULL, 0, NULL, NULL}}; /* identifiers */ diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index 3d3f4ef1260..79ee57d3f91 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -186,36 +186,217 @@ void OBJECT_OT_select_by_type(wmOperatorType *ot) /*********************** Selection by Links *********************/ +enum { + OBJECT_SELECT_LINKED_IPO = 1, + OBJECT_SELECT_LINKED_OBDATA, + OBJECT_SELECT_LINKED_MATERIAL, + OBJECT_SELECT_LINKED_TEXTURE, + OBJECT_SELECT_LINKED_DUPGROUP, + OBJECT_SELECT_LINKED_PARTICLE, + OBJECT_SELECT_LINKED_LIBRARY, + OBJECT_SELECT_LINKED_LIBRARY_OBDATA +}; + static EnumPropertyItem prop_select_linked_types[] = { - //{1, "IPO", 0, "Object IPO", ""}, // XXX depreceated animation system stuff... - {2, "OBDATA", 0, "Object Data", ""}, - {3, "MATERIAL", 0, "Material", ""}, - {4, "TEXTURE", 0, "Texture", ""}, - {5, "DUPGROUP", 0, "Dupligroup", ""}, - {6, "PARTICLE", 0, "Particle System", ""}, - {7, "LIBRARY", 0, "Library", ""}, - {8, "LIBRARY_OBDATA", 0, "Library (Object Data)", ""}, + //{OBJECT_SELECT_LINKED_IPO, "IPO", 0, "Object IPO", ""}, // XXX depreceated animation system stuff... + {OBJECT_SELECT_LINKED_OBDATA, "OBDATA", 0, "Object Data", ""}, + {OBJECT_SELECT_LINKED_MATERIAL, "MATERIAL", 0, "Material", ""}, + {OBJECT_SELECT_LINKED_TEXTURE, "TEXTURE", 0, "Texture", ""}, + {OBJECT_SELECT_LINKED_DUPGROUP, "DUPGROUP", 0, "Dupligroup", ""}, + {OBJECT_SELECT_LINKED_PARTICLE, "PARTICLE", 0, "Particle System", ""}, + {OBJECT_SELECT_LINKED_LIBRARY, "LIBRARY", 0, "Library", ""}, + {OBJECT_SELECT_LINKED_LIBRARY_OBDATA, "LIBRARY_OBDATA", 0, "Library (Object Data)", ""}, {0, NULL, 0, NULL, NULL} }; +// XXX old animation system +#if 0 +static int object_select_all_by_ipo(bContext *C, Ipo *ipo) +{ + int changed = FALSE; + + CTX_DATA_BEGIN (C, Base *, base, visible_bases) + { + if (base->object->ipo == ipo) { + base->flag |= SELECT; + base->object->flag = base->flag; + + changed = TRUE; + } + } + CTX_DATA_END; + + return changed; +} +#endif + +static int object_select_all_by_obdata(bContext *C, void *obdata) +{ + int changed = FALSE; + + CTX_DATA_BEGIN (C, Base *, base, visible_bases) + { + if (base->object->data == obdata) { + base->flag |= SELECT; + base->object->flag = base->flag; + + changed = TRUE; + } + } + CTX_DATA_END; + + return changed; +} + +static int object_select_all_by_material_texture(bContext *C, int use_texture, Material *mat, Tex *tex) +{ + int changed = FALSE; + + CTX_DATA_BEGIN (C, Base *, base, visible_bases) + { + Object *ob = base->object; + Material *mat1; + int a, b; + + for (a = 1; a <= ob->totcol; a++) { + mat1 = give_current_material(ob, a); + + if (!use_texture) { + if (mat1 == mat) { + base->flag |= SELECT; + changed = TRUE; + } + } + else if (mat1 && use_texture) { + for (b = 0; b < MAX_MTEX; b++) { + if (mat1->mtex[b]) { + if (tex == mat1->mtex[b]->tex) { + base->flag |= SELECT; + changed = TRUE; + break; + } + } + } + } + } + + base->object->flag = base->flag; + } + CTX_DATA_END; + + return changed; +} + +static int object_select_all_by_dup_group(bContext *C, Group *dup_group) +{ + int changed = FALSE; + + CTX_DATA_BEGIN (C, Base *, base, visible_bases) + { + if (base->object->dup_group == dup_group) { + base->flag |= SELECT; + base->object->flag = base->flag; + + changed = TRUE; + } + } + CTX_DATA_END; + + return changed; +} + +static int object_select_all_by_particle(bContext *C, Object *ob) +{ + int changed = FALSE; + + CTX_DATA_BEGIN (C, Base *, base, visible_bases) + { + /* loop through other, then actives particles*/ + ParticleSystem *psys; + ParticleSystem *psys_act; + + for (psys = base->object->particlesystem.first; psys; psys = psys->next) { + for (psys_act = ob->particlesystem.first; psys_act; psys_act = psys_act->next) { + if (psys->part == psys_act->part) { + base->flag |= SELECT; + changed = TRUE; + break; + } + } + + if (base->flag & SELECT) { + break; + } + } + + base->object->flag = base->flag; + } + CTX_DATA_END; + + return changed; +} + +static int object_select_all_by_library(bContext *C, Library *lib) +{ + int changed = FALSE; + + CTX_DATA_BEGIN (C, Base *, base, visible_bases) + { + if (lib == base->object->id.lib) { + base->flag |= SELECT; + base->object->flag = base->flag; + + changed = TRUE; + } + } + CTX_DATA_END; + + return changed; +} + +static int object_select_all_by_library_obdata(bContext *C, Library *lib) +{ + int changed = FALSE; + + CTX_DATA_BEGIN (C, Base *, base, visible_bases) + { + if (base->object->data && lib == ((ID *)base->object->data)->lib) { + base->flag |= SELECT; + base->object->flag = base->flag; + + changed = TRUE; + } + } + CTX_DATA_END; + + return changed; +} + +void ED_object_select_linked_by_id(bContext *C, ID *id) +{ + int gs = GS(id->name); + int changed = FALSE; + + if (ELEM8(gs, ID_ME, ID_CU, ID_MB, ID_LT, ID_LA, ID_CA, ID_TXT, ID_SPK)) { + changed = object_select_all_by_obdata(C, id); + } + else if (gs == ID_MA) { + changed = object_select_all_by_material_texture(C, FALSE, (Material *)id, NULL); + } + else if (gs == ID_LI) { + changed = object_select_all_by_library(C, (Library *) id); + } + + if (changed) + WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C)); +} + static int object_select_linked_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *ob; - void *obdata = NULL; - Material *mat = NULL, *mat1; - Tex *tex = NULL; - int a, b; int nr = RNA_enum_get(op->ptr, "type"); - short changed = 0, extend; - /* events (nr): - * Object Ipo: 1 - * ObData: 2 - * Current Material: 3 - * Current Texture: 4 - * DupliGroup: 5 - * PSys: 6 - */ + short changed = FALSE, extend; extend = RNA_boolean_get(op->ptr, "extend"); @@ -233,113 +414,59 @@ static int object_select_linked_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if (nr == 1) { + if (nr == OBJECT_SELECT_LINKED_IPO) { // XXX old animation system - //ipo= ob->ipo; - //if (ipo==0) return OPERATOR_CANCELLED; + //if (ob->ipo == 0) return OPERATOR_CANCELLED; + //object_select_all_by_ipo(C, ob->ipo) return OPERATOR_CANCELLED; } - else if (nr == 2) { - if (ob->data == NULL) return OPERATOR_CANCELLED; - obdata = ob->data; + else if (nr == OBJECT_SELECT_LINKED_OBDATA) { + if (ob->data == 0) + return OPERATOR_CANCELLED; + + changed = object_select_all_by_obdata(C, ob->data); } - else if (nr == 3 || nr == 4) { + else if (nr == OBJECT_SELECT_LINKED_MATERIAL || nr == OBJECT_SELECT_LINKED_TEXTURE) { + Material *mat = NULL; + Tex *tex = NULL; + int use_texture = FALSE; + mat = give_current_material(ob, ob->actcol); if (mat == NULL) return OPERATOR_CANCELLED; - if (nr == 4) { + if (nr == OBJECT_SELECT_LINKED_TEXTURE) { + use_texture = TRUE; + if (mat->mtex[(int)mat->texact]) tex = mat->mtex[(int)mat->texact]->tex; if (tex == NULL) return OPERATOR_CANCELLED; } + + changed = object_select_all_by_material_texture(C, use_texture, mat, tex); } - else if (nr == 5) { - if (ob->dup_group == NULL) return OPERATOR_CANCELLED; + else if (nr == OBJECT_SELECT_LINKED_DUPGROUP) { + if (ob->dup_group == NULL) + return OPERATOR_CANCELLED; + + changed = object_select_all_by_dup_group(C, ob->dup_group); } - else if (nr == 6) { - if (ob->particlesystem.first == NULL) return OPERATOR_CANCELLED; + else if (nr == OBJECT_SELECT_LINKED_PARTICLE) { + if (ob->particlesystem.first == NULL) + return OPERATOR_CANCELLED; + + changed = object_select_all_by_particle(C, ob); } - else if (nr == 7) { + else if (nr == OBJECT_SELECT_LINKED_LIBRARY) { /* do nothing */ + changed = object_select_all_by_library(C, ob->id.lib); } - else if (nr == 8) { - if (ob->data == NULL) return OPERATOR_CANCELLED; + else if (nr == OBJECT_SELECT_LINKED_LIBRARY_OBDATA) { + if (ob->data == NULL) + return OPERATOR_CANCELLED; + + changed = object_select_all_by_library_obdata(C, ((ID *) ob->data)->lib); } else return OPERATOR_CANCELLED; - - CTX_DATA_BEGIN (C, Base *, base, visible_bases) - { - if (nr == 1) { - // XXX old animation system - //if (base->object->ipo == ipo) base->flag |= SELECT; - //changed = 1; - } - else if (nr == 2) { - if (base->object->data == obdata) base->flag |= SELECT; - changed = 1; - } - else if (nr == 3 || nr == 4) { - ob = base->object; - - for (a = 1; a <= ob->totcol; a++) { - mat1 = give_current_material(ob, a); - if (nr == 3) { - if (mat1 == mat) base->flag |= SELECT; - changed = 1; - } - else if (mat1 && nr == 4) { - for (b = 0; b < MAX_MTEX; b++) { - if (mat1->mtex[b]) { - if (tex == mat1->mtex[b]->tex) { - base->flag |= SELECT; - changed = 1; - break; - } - } - } - } - } - } - else if (nr == 5) { - if (base->object->dup_group == ob->dup_group) { - base->flag |= SELECT; - changed = 1; - } - } - else if (nr == 6) { - /* loop through other, then actives particles*/ - ParticleSystem *psys; - ParticleSystem *psys_act; - - for (psys = base->object->particlesystem.first; psys; psys = psys->next) { - for (psys_act = ob->particlesystem.first; psys_act; psys_act = psys_act->next) { - if (psys->part == psys_act->part) { - base->flag |= SELECT; - changed = 1; - break; - } - } - - if (base->flag & SELECT) { - break; - } - } - } - else if (nr == 7) { - if (ob->id.lib == base->object->id.lib) { - base->flag |= SELECT; - changed = 1; - } - } - else if (nr == 8) { - if (base->object->data && ((ID *)ob->data)->lib == ((ID *)base->object->data)->lib) { - base->flag |= SELECT; - changed = 1; - } - } - base->object->flag = base->flag; - } - CTX_DATA_END; - + if (changed) { WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C)); return OPERATOR_FINISHED; @@ -989,5 +1116,3 @@ void OBJECT_OT_select_random(wmOperatorType *ot) RNA_def_float_percentage(ot->srna, "percent", 50.f, 0.0f, 100.0f, "Percent", "Percentage of objects to select randomly", 0.f, 100.0f); RNA_def_boolean(ot->srna, "extend", FALSE, "Extend Selection", "Extend selection instead of deselecting everything first"); } - - diff --git a/source/blender/editors/physics/particle_boids.c b/source/blender/editors/physics/particle_boids.c index 23ce4776b73..aff66b272fe 100644 --- a/source/blender/editors/physics/particle_boids.c +++ b/source/blender/editors/physics/particle_boids.c @@ -56,23 +56,18 @@ /************************ add/del boid rule operators *********************/ static int rule_add_exec(bContext *C, wmOperator *op) { - PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); - ParticleSystem *psys= ptr.data; - Object *ob= ptr.id.data; - ParticleSettings *part; + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings); + ParticleSettings *part = ptr.data; int type= RNA_enum_get(op->ptr, "type"); BoidRule *rule; BoidState *state; - if (!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) + if (!part || part->phystype != PART_PHYS_BOIDS) return OPERATOR_CANCELLED; - part = psys->part; - state = boid_get_current_state(part->boids); - for (rule=state->rules.first; rule; rule=rule->next) rule->flag &= ~BOIDRULE_CURRENT; @@ -82,7 +77,6 @@ static int rule_add_exec(bContext *C, wmOperator *op) BLI_addtail(&state->rules, rule); DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); return OPERATOR_FINISHED; } @@ -107,25 +101,22 @@ static int rule_del_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); - ParticleSystem *psys= ptr.data; - Object *ob = ptr.id.data; + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings); + ParticleSettings *part = ptr.data; BoidRule *rule; BoidState *state; - if (!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) + if (!part || part->phystype != PART_PHYS_BOIDS) return OPERATOR_CANCELLED; - state = boid_get_current_state(psys->part->boids); + state = boid_get_current_state(part->boids); - for (rule=state->rules.first; rule; rule=rule->next) { if (rule->flag & BOIDRULE_CURRENT) { BLI_remlink(&state->rules, rule); MEM_freeN(rule); break; } - } rule = state->rules.first; @@ -133,10 +124,8 @@ static int rule_del_exec(bContext *C, wmOperator *UNUSED(op)) rule->flag |= BOIDRULE_CURRENT; DAG_scene_sort(bmain, scene); - DAG_id_tag_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); + DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); - return OPERATOR_FINISHED; } @@ -157,23 +146,21 @@ void BOID_OT_rule_del(wmOperatorType *ot) /************************ move up/down boid rule operators *********************/ static int rule_move_up_exec(bContext *C, wmOperator *UNUSED(op)) { - PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); - ParticleSystem *psys= ptr.data; - Object *ob = ptr.id.data; + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings); + ParticleSettings *part = ptr.data; BoidRule *rule; BoidState *state; - if (!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) + if (!part || part->phystype != PART_PHYS_BOIDS) return OPERATOR_CANCELLED; - state = boid_get_current_state(psys->part->boids); + state = boid_get_current_state(part->boids); for (rule = state->rules.first; rule; rule=rule->next) { if (rule->flag & BOIDRULE_CURRENT && rule->prev) { BLI_remlink(&state->rules, rule); BLI_insertlink(&state->rules, rule->prev->prev, rule); - DAG_id_tag_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); break; } } @@ -195,23 +182,21 @@ void BOID_OT_rule_move_up(wmOperatorType *ot) static int rule_move_down_exec(bContext *C, wmOperator *UNUSED(op)) { - PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); - ParticleSystem *psys= ptr.data; - Object *ob = ptr.id.data; + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings); + ParticleSettings *part = ptr.data; BoidRule *rule; BoidState *state; - if (!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) + if (!part || part->phystype != PART_PHYS_BOIDS) return OPERATOR_CANCELLED; - state = boid_get_current_state(psys->part->boids); + state = boid_get_current_state(part->boids); for (rule = state->rules.first; rule; rule=rule->next) { if (rule->flag & BOIDRULE_CURRENT && rule->next) { BLI_remlink(&state->rules, rule); BLI_insertlink(&state->rules, rule->next, rule); - DAG_id_tag_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); break; } } @@ -235,17 +220,13 @@ void BOID_OT_rule_move_down(wmOperatorType *ot) /************************ add/del boid state operators *********************/ static int state_add_exec(bContext *C, wmOperator *UNUSED(op)) { - PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); - ParticleSystem *psys= ptr.data; - Object *ob= ptr.id.data; - ParticleSettings *part; + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings); + ParticleSettings *part = ptr.data; BoidState *state; - if (!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) + if (!part || part->phystype != PART_PHYS_BOIDS) return OPERATOR_CANCELLED; - part = psys->part; - for (state=part->boids->states.first; state; state=state->next) state->flag &= ~BOIDSTATE_CURRENT; @@ -254,8 +235,6 @@ static int state_add_exec(bContext *C, wmOperator *UNUSED(op)) BLI_addtail(&part->boids->states, state); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); - return OPERATOR_FINISHED; } @@ -276,24 +255,19 @@ static int state_del_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); - ParticleSystem *psys= ptr.data; - Object *ob = ptr.id.data; - ParticleSettings *part; + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings); + ParticleSettings *part = ptr.data; BoidState *state; - if (!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) + if (!part || part->phystype != PART_PHYS_BOIDS) return OPERATOR_CANCELLED; - part = psys->part; - for (state=part->boids->states.first; state; state=state->next) { if (state->flag & BOIDSTATE_CURRENT) { BLI_remlink(&part->boids->states, state); MEM_freeN(state); break; } - } /* there must be at least one state */ @@ -307,9 +281,7 @@ static int state_del_exec(bContext *C, wmOperator *UNUSED(op)) state->flag |= BOIDSTATE_CURRENT; DAG_scene_sort(bmain, scene); - DAG_id_tag_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); - - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); return OPERATOR_FINISHED; } @@ -331,22 +303,20 @@ void BOID_OT_state_del(wmOperatorType *ot) /************************ move up/down boid state operators *********************/ static int state_move_up_exec(bContext *C, wmOperator *UNUSED(op)) { - PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); - ParticleSystem *psys= ptr.data; - Object *ob = ptr.id.data; + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings); + ParticleSettings *part = ptr.data; BoidSettings *boids; BoidState *state; - if (!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) + if (!part || part->phystype != PART_PHYS_BOIDS) return OPERATOR_CANCELLED; - boids = psys->part->boids; + boids = part->boids; for (state = boids->states.first; state; state=state->next) { if (state->flag & BOIDSTATE_CURRENT && state->prev) { BLI_remlink(&boids->states, state); BLI_insertlink(&boids->states, state->prev->prev, state); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); break; } } @@ -368,21 +338,21 @@ void BOID_OT_state_move_up(wmOperatorType *ot) static int state_move_down_exec(bContext *C, wmOperator *UNUSED(op)) { - PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); - ParticleSystem *psys= ptr.data; + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings); + ParticleSettings *part = ptr.data; BoidSettings *boids; BoidState *state; - if (!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) + if (!part || part->phystype != PART_PHYS_BOIDS) return OPERATOR_CANCELLED; - boids = psys->part->boids; + boids = part->boids; for (state = boids->states.first; state; state=state->next) { if (state->flag & BOIDSTATE_CURRENT && state->next) { BLI_remlink(&boids->states, state); BLI_insertlink(&boids->states, state->next, state); - DAG_id_tag_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); + DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); break; } } diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 8fa3c6f992f..b1776894959 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -452,10 +452,12 @@ static void render_drawlock(void *UNUSED(rjv), int lock) } /* catch esc */ -static int screen_render_modal(bContext *C, wmOperator *UNUSED(op), wmEvent *event) +static int screen_render_modal(bContext *C, wmOperator *op, wmEvent *event) { + Scene *scene = (Scene *) op->customdata; + /* no running blender, remove handler and pass through */ - if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C))) { + if (0 == WM_jobs_test(CTX_wm_manager(C), scene)) { return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH; } @@ -584,6 +586,12 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) rj->re = re; G.afbreek = 0; + /* store actual owner of job, so modal operator could check for it, + * the reason of this is that active scene could change when rendering + * several layers from composistor [#31800] + */ + op->customdata = scene; + WM_jobs_start(CTX_wm_manager(C), steve); WM_cursor_wait(0); diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 538b4b3884a..12f1e09f5be 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -476,6 +476,7 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op) int ok = 0; const short view_context = (oglrender->v3d != NULL); Object *camera = NULL; + int is_movie; /* go to next frame */ if (CFRA < oglrender->nfra) @@ -490,6 +491,21 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op) CFRA++; } + is_movie = BKE_imtype_is_movie(scene->r.im_format.imtype); + + if (!is_movie) { + BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra, scene->r.im_format.imtype, scene->r.scemode & R_EXTENSION, TRUE); + + if ((scene->r.mode & R_NO_OVERWRITE) && BLI_exists(name)) { + printf("skipping existing frame \"%s\"\n", name); + + /* go to next frame */ + oglrender->nfra += scene->r.frame_step; + + return 1; + } + } + /* update animated image textures for gpu, etc, * call before BKE_scene_update_for_newframe so modifiers with textures don't lag 1 frame */ ED_image_update_frame(bmain, CFRA); @@ -538,7 +554,7 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op) ibuf = ibuf_cpy; } - if (BKE_imtype_is_movie(scene->r.im_format.imtype)) { + if (is_movie) { ok = oglrender->mh->append_movie(&scene->r, SFRA, CFRA, (int *)ibuf->rect, oglrender->sizex, oglrender->sizey, oglrender->reports); if (ok) { @@ -547,7 +563,6 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op) } } else { - BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra, scene->r.im_format.imtype, scene->r.scemode & R_EXTENSION, TRUE); ok = BKE_imbuf_write_stamp(scene, camera, ibuf, name, &scene->r.im_format); if (ok == 0) { diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 6357cb48a3d..29ebc51df3e 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -705,7 +705,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs } else { /* validate owner */ - //if (ri->rect==NULL) + //if (ri->rect == NULL) // ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "BIF_previewrender"); //RE_ResultGet32(re, ri->rect); } diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 21cd02c96f2..8bdd4e544e8 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -750,7 +750,8 @@ void TEXTURE_OT_envmap_save(wmOperatorType *ot) prop = RNA_def_float_array(ot->srna, "layout", 12, default_envmap_layout, 0.0f, 0.0f, "File layout", "Flat array describing the X,Y position of each cube face in the output image, where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] (use -1 to skip a face)", 0.0f, 0.0f); RNA_def_property_flag(prop, PROP_HIDDEN); - WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_SAVE, + WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); } static int envmap_clear_exec(bContext *C, wmOperator *UNUSED(op)) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index f8ca150e28e..b4f1f4b3022 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -107,7 +107,7 @@ void ED_region_pixelspace(ARegion *ar) int width = ar->winrct.xmax - ar->winrct.xmin + 1; int height = ar->winrct.ymax - ar->winrct.ymin + 1; - wmOrtho2(-0.375f, (float)width - 0.375f, -0.375f, (float)height - 0.375f); + wmOrtho2(-GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS); glLoadIdentity(); } @@ -1297,7 +1297,7 @@ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space) if (swap_space == 1) { SWAP(ListBase, sa1->spacedata, sa2->spacedata); /* exception: ensure preview is reset */ -// if (sa1->spacetype==SPACE_VIEW3D) +// if (sa1->spacetype == SPACE_VIEW3D) // XXX BIF_view3d_previewrender_free(sa1->spacedata.first); } else if (swap_space == 2) { diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index 0f1ffb856e7..a534124d2c0 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -624,8 +624,8 @@ void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int fo * covers the entire screen). */ glGetFloatv(GL_SCISSOR_BOX, scissor); - draw_w = MIN2(img_w - off_x, ceil((scissor[2] - rast_x) / xzoom)); - draw_h = MIN2(img_h - off_y, ceil((scissor[3] - rast_y) / yzoom)); + draw_w = mini(img_w - off_x, ceil((scissor[2] - rast_x) / xzoom)); + draw_h = mini(img_h - off_y, ceil((scissor[3] - rast_y) / yzoom)); if (draw_w > 0 && draw_h > 0) { int old_row_length = glaGetOneInteger(GL_UNPACK_ROW_LENGTH); @@ -674,7 +674,7 @@ void glaDefine2DArea(rcti *screen_rect) glViewport(screen_rect->xmin, screen_rect->ymin, sc_w, sc_h); glScissor(screen_rect->xmin, screen_rect->ymin, sc_w, sc_h); - /* The 0.375 magic number is to shift the matrix so that + /* The GLA_PIXEL_OFS magic number is to shift the matrix so that * both raster and vertex integer coordinates fall at pixel * centers properly. For a longer discussion see the OpenGL * Programming Guide, Appendix H, Correctness Tips. @@ -683,7 +683,7 @@ void glaDefine2DArea(rcti *screen_rect) glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, sc_w, 0.0, sc_h, -1, 1); - glTranslatef(0.375, 0.375, 0.0); + glTranslatef(GLA_PIXEL_OFS, GLA_PIXEL_OFS, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 48532c83e4c..dda4bfede9c 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1483,7 +1483,7 @@ void ED_screen_set_scene(bContext *C, bScreen *screen, Scene *scene) if (!v3d->camera || !BKE_scene_base_find(scene, v3d->camera)) { v3d->camera = BKE_scene_camera_find(sc->scene); - // XXX if (sc==curscreen) handle_view3d_lock(); + // XXX if (sc == curscreen) handle_view3d_lock(); if (!v3d->camera) { ARegion *ar; for (ar = v3d->regionbase.first; ar; ar = ar->next) { diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 2391d6c909e..36353c43cbd 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -65,15 +65,16 @@ #include "WM_api.h" #include "WM_types.h" -#include "ED_util.h" +#include "ED_armature.h" +#include "ED_clip.h" #include "ED_image.h" -#include "ED_screen.h" +#include "ED_keyframes_draw.h" #include "ED_object.h" -#include "ED_armature.h" +#include "ED_screen.h" #include "ED_screen_types.h" -#include "ED_keyframes_draw.h" +#include "ED_sequencer.h" +#include "ED_util.h" #include "ED_view3d.h" -#include "ED_clip.h" #include "RNA_access.h" #include "RNA_define.h" @@ -458,9 +459,30 @@ int ED_operator_editmball(bContext *C) int ED_operator_mask(bContext *C) { - SpaceClip *sc = CTX_wm_space_clip(C); + ScrArea *sa = CTX_wm_area(C); + if (sa && sa->spacedata.first) { + switch (sa->spacetype) { + case SPACE_CLIP: + { + SpaceClip *sc = sa->spacedata.first; + return ED_space_clip_check_show_maskedit(sc); + } + case SPACE_SEQ: + { + SpaceSeq *sseq = sa->spacedata.first; + Scene *scene = CTX_data_scene(C); + return ED_space_sequencer_check_show_maskedit(sseq, scene); + } + case SPACE_IMAGE: + { + SpaceImage *sima = sa->spacedata.first; + Scene *scene = CTX_data_scene(C); + return ED_space_image_check_show_maskedit(scene, sima); + } + } + } - return ED_space_clip_check_show_maskedit(sc); + return FALSE; } /* *************************** action zone operator ************************** */ @@ -1949,12 +1971,10 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) ob_to_keylist(&ads, ob, &keys, NULL); { - SpaceClip *sc = CTX_wm_space_clip(C); - if (sc) { - if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask) { - MaskLayer *masklay = BKE_mask_layer_active(sc->mask); - mask_to_keylist(&ads, masklay, &keys); - } + Mask *mask = CTX_data_edit_mask(C); + if (mask) { + MaskLayer *masklay = BKE_mask_layer_active(mask); + mask_to_keylist(&ads, masklay, &keys); } } diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c index 77289360f98..79ff516b362 100644 --- a/source/blender/editors/screen/screendump.c +++ b/source/blender/editors/screen/screendump.c @@ -266,7 +266,8 @@ void SCREEN_OT_screenshot(wmOperatorType *ot) ot->flag = 0; - WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE, FILE_SPECIAL, FILE_SAVE, + WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, "full", 1, "Full Screen", "Screenshot the whole Blender window"); } diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 073e60ca87c..05cc958aa43 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -801,7 +801,7 @@ static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float if (rgba_fp) { if (ibuf->rect_float) { - copy_v4_v4(rgba_fp, ((float *)ibuf->rect_float + ((xi + yi * ibuf->x) * 4))); + copy_v4_v4(rgba_fp, (ibuf->rect_float + ((xi + yi * ibuf->x) * 4))); } else { char *tmp_ch = ((char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4); @@ -1461,7 +1461,7 @@ static float project_paint_uvpixel_mask( /* This only works when the opacity dosnt change while painting, stylus pressure messes with this * so don't use it. */ - // if (ps->is_airbrush==0) mask *= BKE_brush_alpha_get(ps->brush); + // if (ps->is_airbrush == 0) mask *= BKE_brush_alpha_get(ps->brush); return mask; } @@ -1503,7 +1503,7 @@ static ProjPixel *project_paint_uvpixel_init( //memset(projPixel, 0, size); if (ibuf->rect_float) { - projPixel->pixel.f_pt = (float *)ibuf->rect_float + ((x_px + y_px * ibuf->x) * 4); + projPixel->pixel.f_pt = ibuf->rect_float + ((x_px + y_px * ibuf->x) * 4); projPixel->origColor.f[0] = projPixel->newColor.f[0] = projPixel->pixel.f_pt[0]; projPixel->origColor.f[1] = projPixel->newColor.f[1] = projPixel->pixel.f_pt[1]; projPixel->origColor.f[2] = projPixel->newColor.f[2] = projPixel->pixel.f_pt[2]; @@ -4667,8 +4667,9 @@ static int image_paint_poll(bContext *C) if (sima) { ARegion *ar = CTX_wm_region(C); - if ((sima->flag & SI_DRAWTOOL) && ar->regiontype == RGN_TYPE_WINDOW) + if ((sima->mode == SI_MODE_PAINT) && ar->regiontype == RGN_TYPE_WINDOW) { return 1; + } } } @@ -5200,7 +5201,7 @@ int get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy) SpaceImage *sima = CTX_wm_space_image(C); ARegion *ar = CTX_wm_region(C); - ED_space_image_zoom(sima, ar, zoomx, zoomy); + ED_space_image_get_zoom(sima, ar, zoomx, zoomy); return 1; } @@ -5235,7 +5236,7 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata) !(ts->use_uv_sculpt && (scene->basact->object->mode == OB_MODE_EDIT)); if (use_zoom) { - pixel_size = MAX2(size * zoomx, size * zoomy); + pixel_size = size * maxf(zoomx, zoomy); } else { pixel_size = size; @@ -5311,7 +5312,7 @@ void ED_space_image_uv_sculpt_update(wmWindowManager *wm, ToolSettings *settings settings->uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN; } - paint_init(&settings->uvsculpt->paint, PAINT_CURSOR_SCULPT); + BKE_paint_init(&settings->uvsculpt->paint, PAINT_CURSOR_SCULPT); WM_paint_cursor_activate(wm, uv_sculpt_brush_poll, brush_drawcursor, NULL); @@ -5601,7 +5602,7 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op) me->mtface = CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface); - paint_init(&scene->toolsettings->imapaint.paint, PAINT_CURSOR_TEXTURE_PAINT); + BKE_paint_init(&scene->toolsettings->imapaint.paint, PAINT_CURSOR_TEXTURE_PAINT); if (U.glreslimit != 0) GPU_free_images(); diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 3f9e0051d2e..99bc192042c 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -13,7 +13,7 @@ * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * 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. @@ -177,15 +177,10 @@ float paint_calc_object_space_radius(ViewContext *vc, const float center[3], float paint_get_tex_pixel(Brush *br, float u, float v) { - TexResult texres; - float co[3]; + TexResult texres = {0}; + float co[3] = {u, v, 0.0f}; int hasrgb; - co[0] = u; - co[1] = v; - co[2] = 0; - - memset(&texres, 0, sizeof(TexResult)); hasrgb = multitex_ext(br->mtex.tex, co, NULL, NULL, 0, &texres); if (hasrgb & TEX_RGB) diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 1b62ba8a7e0..3c389f97b34 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -1997,7 +1997,7 @@ static int set_wpaint(bContext *C, wmOperator *UNUSED(op)) /* toggle */ if (wp == NULL) wp = scene->toolsettings->wpaint = new_vpaint(1); - paint_init(&wp->paint, PAINT_CURSOR_WEIGHT_PAINT); + BKE_paint_init(&wp->paint, PAINT_CURSOR_WEIGHT_PAINT); paint_cursor_start(C, weight_paint_poll); mesh_octree_table(ob, NULL, NULL, 's'); @@ -2574,7 +2574,7 @@ static int set_vpaint(bContext *C, wmOperator *op) /* toggle */ paint_cursor_start(C, vertex_paint_poll); - paint_init(&vp->paint, PAINT_CURSOR_VERTEX_PAINT); + BKE_paint_init(&vp->paint, PAINT_CURSOR_VERTEX_PAINT); } if (me) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 35d508c5a1f..e2289bc9cfc 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -3064,12 +3064,19 @@ static void sculpt_update_tex(const Scene *scene, Sculpt *sd, SculptSession *ss) void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, int need_pmap) { - DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + DerivedMesh *dm; SculptSession *ss = ob->sculpt; + Mesh *me = ob->data; MultiresModifierData *mmd = sculpt_multires_active(scene, ob); ss->modifiers_active = sculpt_modifiers_active(scene, sd, ob); + /* BMESH ONLY --- at some point we should move sculpt code to use polygons only - but for now it needs tessfaces */ + BKE_mesh_tessface_ensure(me); + + /* needs to be called after we ensure tessface */ + dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + if (!mmd) ss->kb = ob_get_keyblock(ob); else ss->kb = NULL; @@ -3083,7 +3090,6 @@ void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, int need_ ss->face_normals = NULL; } else { - Mesh *me = BKE_mesh_from_object(ob); ss->totvert = me->totvert; ss->totpoly = me->totpoly; ss->mvert = me->mvert; @@ -3094,9 +3100,6 @@ void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, int need_ ss->vmask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK); } - /* BMESH ONLY --- at some point we should move sculpt code to use polygons only - but for now it needs tessfaces */ - BKE_mesh_tessface_ensure(ob->data); - ss->pbvh = dm->getPBVH(ob, dm); ss->pmap = (need_pmap && dm->getPolyMap) ? dm->getPolyMap(ob, dm) : NULL; @@ -3106,14 +3109,14 @@ void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, int need_ free_sculptsession_deformMats(ss); - if (ss->kb) ss->orig_cos = key_to_vertcos(ob, ss->kb); - else ss->orig_cos = mesh_getVertexCos(ob->data, NULL); + ss->orig_cos = (ss->kb) ? key_to_vertcos(ob, ss->kb) : mesh_getVertexCos(me, NULL); crazyspace_build_sculpt(scene, ob, &ss->deform_imats, &ss->deform_cos); BLI_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos); - for (a = 0; a < ((Mesh *)ob->data)->totvert; ++a) + for (a = 0; a < me->totvert; ++a) { invert_m3(ss->deform_imats[a]); + } } } else free_sculptsession_deformMats(ss); @@ -3254,9 +3257,9 @@ static void sculpt_omp_start(Sculpt *sd, SculptSession *ss) if (ss->multires) { int i, gridsize, array_mem_size; BLI_pbvh_node_get_grids(ss->pbvh, NULL, NULL, NULL, NULL, - &gridsize, NULL, NULL); + &gridsize, NULL, NULL); - array_mem_size = cache->num_threads * sizeof(void*); + array_mem_size = cache->num_threads * sizeof(void *); cache->tmpgrid_co = MEM_mallocN(array_mem_size, "tmpgrid_co array"); cache->tmprow_co = MEM_mallocN(array_mem_size, "tmprow_co array"); @@ -4194,7 +4197,7 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op)) if (flush_recalc) DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - + /* Create persistent sculpt mode data */ if (!ts->sculpt) { ts->sculpt = MEM_callocN(sizeof(Sculpt), "sculpt mode data"); @@ -4212,7 +4215,7 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op)) /* Mask layer is required */ ED_sculpt_mask_layers_ensure(ob, mmd); - paint_init(&ts->sculpt->paint, PAINT_CURSOR_SCULPT); + BKE_paint_init(&ts->sculpt->paint, PAINT_CURSOR_SCULPT); paint_cursor_start(C, sculpt_poll); } diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c index 95441600d77..fdce8ec04a4 100644 --- a/source/blender/editors/sculpt_paint/sculpt_uv.c +++ b/source/blender/editors/sculpt_paint/sculpt_uv.c @@ -315,8 +315,8 @@ static void uv_sculpt_stroke_apply(bContext *C, wmOperator *op, wmEvent *event, UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]); sima = CTX_wm_space_image(C); - ED_space_image_size(sima, &width, &height); - ED_space_image_zoom(sima, ar, &zoomx, &zoomy); + ED_space_image_get_size(sima, &width, &height); + ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy); radius = BKE_brush_size_get(scene, brush) / (width * zoomx); aspectRatio = width / (float)height; @@ -683,8 +683,8 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, wmEvent radius = BKE_brush_size_get(scene, brush); sima = CTX_wm_space_image(C); - ED_space_image_size(sima, &width, &height); - ED_space_image_zoom(sima, ar, &zoomx, &zoomy); + ED_space_image_get_size(sima, &width, &height); + ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy); aspectRatio = width / (float)height; radius /= (width * zoomx); diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 9827ffdc324..aaa1328f9f6 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -186,7 +186,8 @@ static void SOUND_OT_open(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory"); RNA_def_boolean(ot->srna, "mono", FALSE, "Mono", "Mixdown the sound to mono"); } @@ -207,7 +208,8 @@ static void SOUND_OT_open_mono(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory"); RNA_def_boolean(ot->srna, "mono", TRUE, "Mono", "Mixdown the sound to mono"); } @@ -659,7 +661,8 @@ static void SOUND_OT_mixdown(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE, FILE_SPECIAL, FILE_SAVE, + WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); #ifdef WITH_AUDASPACE RNA_def_int(ot->srna, "accuracy", 1024, 1, 16777216, "Accuracy", "Sample accuracy, important for animation data (the lower the value, the more accurate)", 1, 16777216); RNA_def_enum(ot->srna, "container", container_items, AUD_CONTAINER_FLAC, "Container", "File format"); @@ -698,7 +701,7 @@ static int sound_pack_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; sound->packedfile = newPackedFile(op->reports, sound->name, ID_BLEND_PATH(bmain, &sound->id)); - sound_load(CTX_data_main(C), sound); + sound_load(bmain, sound); return OPERATOR_FINISHED; } @@ -722,6 +725,7 @@ static void SOUND_OT_pack(wmOperatorType *ot) static int sound_unpack_exec(bContext *C, wmOperator *op) { + Main *bmain = CTX_data_main(C); int method = RNA_enum_get(op->ptr, "method"); bSound *sound = NULL; @@ -729,7 +733,7 @@ static int sound_unpack_exec(bContext *C, wmOperator *op) if (RNA_struct_property_is_set(op->ptr, "id")) { char sndname[MAX_ID_NAME - 2]; RNA_string_get(op->ptr, "id", sndname); - sound = BLI_findstring(&CTX_data_main(C)->sound, sndname, offsetof(ID, name) + 2); + sound = BLI_findstring(&bmain->sound, sndname, offsetof(ID, name) + 2); } if (!sound || !sound->packedfile) @@ -738,7 +742,7 @@ static int sound_unpack_exec(bContext *C, wmOperator *op) if (G.fileflags & G_AUTOPACK) BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save"); - unpackSound(CTX_data_main(C), op->reports, sound, method); + unpackSound(bmain, op->reports, sound, method); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index db1d4ed1155..1f641829e7e 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -129,8 +129,7 @@ static SpaceLink *action_new(const bContext *C) /* not spacelink itself */ static void action_free(SpaceLink *UNUSED(sl)) { -// SpaceAction *saction= (SpaceAction*) sl; - +// SpaceAction *saction= (SpaceAction *) sl; } diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 6154a1cc5ce..c41d2521ee8 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -683,7 +683,7 @@ const char *buttons_context_dir[] = { "world", "object", "mesh", "armature", "lattice", "curve", "meta_ball", "lamp", "speaker", "camera", "material", "material_slot", "texture", "texture_slot", "texture_user", "bone", "edit_bone", - "pose_bone", "particle_system", "particle_system_editable", + "pose_bone", "particle_system", "particle_system_editable", "particle_settings", "cloth", "soft_body", "fluid", "smoke", "collision", "brush", "dynamic_paint", NULL }; @@ -890,6 +890,27 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r CTX_data_pointer_set(result, NULL, &RNA_ParticleSystem, NULL); return 1; } + else if (CTX_data_equals(member, "particle_settings")) { + /* only available when pinned */ + PointerRNA *ptr = get_pointer_type(path, &RNA_ParticleSettings); + + if (ptr && ptr->data) { + CTX_data_pointer_set(result, ptr->id.data, &RNA_ParticleSettings, ptr->data); + return 1; + } + else { + /* get settings from active particle system instead */ + PointerRNA *ptr = get_pointer_type(path, &RNA_ParticleSystem); + + if (ptr && ptr->data) { + ParticleSettings *part = ((ParticleSystem *)ptr->data)->part; + CTX_data_pointer_set(result, ptr->id.data, &RNA_ParticleSettings, part); + return 1; + } + } + set_pointer_type(path, result, &RNA_ParticleSettings); + return 1; + } else if (CTX_data_equals(member, "cloth")) { PointerRNA *ptr = get_pointer_type(path, &RNA_Object); diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index c29a8c3934e..c8cf69e3e17 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -230,7 +230,8 @@ void BUTTONS_OT_file_browse(wmOperatorType *ot) ot->cancel = file_browse_cancel; /* properties */ - WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); } /* second operator, only difference from BUTTONS_OT_file_browse is WM_FILESEL_DIRECTORY */ @@ -247,5 +248,6 @@ void BUTTONS_OT_directory_browse(wmOperatorType *ot) ot->cancel = file_browse_cancel; /* properties */ - WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); } diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 37da40e11b3..c24cdab29e5 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -53,6 +53,7 @@ #include "ED_screen.h" #include "ED_clip.h" +#include "ED_mask.h" #include "ED_gpencil.h" #include "BIF_gl.h" @@ -73,7 +74,7 @@ /*********************** main area drawing *************************/ -void clip_draw_curfra_label(SpaceClip *sc, float x, float y) +void clip_draw_curfra_label(const int framenr, const float x, const float y) { uiStyle *style = UI_GetStyle(); int fontid = style->widget.uifont_id; @@ -82,7 +83,7 @@ void clip_draw_curfra_label(SpaceClip *sc, float x, float y) /* frame number */ BLF_size(fontid, 11.0f, U.dpi); - BLI_snprintf(numstr, sizeof(numstr), "%d", sc->user.framenr); + BLI_snprintf(numstr, sizeof(numstr), "%d", framenr); BLF_width_and_height(fontid, numstr, &font_dims[0], &font_dims[1]); @@ -93,13 +94,30 @@ void clip_draw_curfra_label(SpaceClip *sc, float x, float y) BLF_draw(fontid, numstr, sizeof(numstr)); } +static void draw_keyframe(int frame, int cfra, int sfra, float framelen, int width) +{ + int height = (frame == cfra) ? 22 : 10; + int x = (frame - sfra) * framelen; + + if (width == 1) { + glBegin(GL_LINES); + glVertex2i(x, 0); + glVertex2i(x, height); + glEnd(); + } + else { + glRecti(x, 0, x + width, height); + } +} + static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Scene *scene) { float x; int *points, totseg, i, a; float sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1); + MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking); - MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(&clip->tracking); + MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking); glEnable(GL_BLEND); @@ -195,32 +213,16 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc UI_ThemeColor(TH_CFRAME); glRecti(x, 0, x + framelen, 8); - clip_draw_curfra_label(sc, x, 8.0f); + clip_draw_curfra_label(sc->user.framenr, x, 8.0f); - /* movie clip animation */ - if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask) { - MaskLayer *masklay = BKE_mask_layer_active(sc->mask); - if (masklay) { - MaskLayerShape *masklay_shape; + /* solver keyframes */ + glColor4ub(175, 255, 0, 255); + draw_keyframe(tracking->settings.keyframe1 + clip->start_frame - 1, CFRA, sfra, framelen, 2); + draw_keyframe(tracking->settings.keyframe2 + clip->start_frame - 1, CFRA, sfra, framelen, 2); - glColor4ub(255, 175, 0, 255); - glBegin(GL_LINES); - - for (masklay_shape = masklay->splines_shapes.first; - masklay_shape; - masklay_shape = masklay_shape->next) - { - i = masklay_shape->frame; - - /* glRecti((i - sfra) * framelen, 0, (i - sfra + 1) * framelen, 4); */ - - /* use a line so we always see the keyframes */ - glVertex2i((i - sfra) * framelen, 0); - glVertex2i((i - sfra) * framelen, (i == CFRA) ? 22 : 10); - } - - glEnd(); - } + /* movie clip animation */ + if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask_info.mask) { + ED_mask_draw_frames(sc->mask_info.mask, ar, CFRA, sfra, efra); } } @@ -714,7 +716,7 @@ static float get_shortest_pattern_side(MovieTrackingMarker *marker) cur_len = len_v2v2(marker->pattern_corners[i], marker->pattern_corners[next]); - len = MIN2(cur_len, len); + len = minf(cur_len, len); } return len; @@ -786,11 +788,11 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo dy = 6.0f / height / sc->zoom; side = get_shortest_pattern_side(marker); - patdx = MIN2(dx * 2.0f / 3.0f, side / 6.0f); - patdy = MIN2(dy * 2.0f / 3.0f, side * width / height / 6.0f); + patdx = minf(dx * 2.0f / 3.0f, side / 6.0f); + patdy = minf(dy * 2.0f / 3.0f, side * width / height / 6.0f); - searchdx = MIN2(dx, (marker->search_max[0] - marker->search_min[0]) / 6.0f); - searchdy = MIN2(dy, (marker->search_max[1] - marker->search_min[1]) / 6.0f); + searchdx = minf(dx, (marker->search_max[0] - marker->search_min[0]) / 6.0f); + searchdy = minf(dy, (marker->search_max[1] - marker->search_min[1]) / 6.0f); px[0] = 1.0f / sc->zoom / width / sc->scale; px[1] = 1.0f / sc->zoom / height / sc->scale; @@ -1408,17 +1410,16 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, glPopMatrix(); } -void clip_draw_main(const bContext *C, ARegion *ar) +void clip_draw_main(const bContext *C, SpaceClip *sc, ARegion *ar) { - SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); Scene *scene = CTX_data_scene(C); ImBuf *ibuf; int width, height; float zoomx, zoomy; - ED_space_clip_get_size(C, &width, &height); - ED_space_clip_get_zoom(C, &zoomx, &zoomy); + ED_space_clip_get_size(sc, &width, &height); + ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy); /* if no clip, nothing to do */ if (!clip) { diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 224a250fe4c..5e4ef1aa24a 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -115,7 +115,7 @@ int ED_space_clip_maskedit_mask_poll(bContext *C) if (clip) { SpaceClip *sc = CTX_wm_space_clip(C); - return sc->mask != NULL; + return sc->mask_info.mask != NULL; } } @@ -124,24 +124,29 @@ int ED_space_clip_maskedit_mask_poll(bContext *C) /* ******** common editing functions ******** */ -void ED_space_clip_get_size(const bContext *C, int *width, int *height) +void ED_space_clip_get_size(SpaceClip *sc, int *width, int *height) { - SpaceClip *sc = CTX_wm_space_clip(C); - - if (!sc->clip) { - *width = *height = 0; + if (sc->clip) { + BKE_movieclip_get_size(sc->clip, &sc->user, width, height); } else { - BKE_movieclip_get_size(sc->clip, &sc->user, width, height); + *width = *height = IMG_SIZE_FALLBACK; } } -void ED_space_clip_get_zoom(const bContext *C, float *zoomx, float *zoomy) +void ED_space_clip_get_size_fl(SpaceClip *sc, float size[2]) +{ + int size_i[2]; + ED_space_clip_get_size(sc, &size_i[0], &size_i[1]); + size[0] = size_i[0]; + size[1] = size_i[1]; +} + +void ED_space_clip_get_zoom(SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy) { - ARegion *ar = CTX_wm_region(C); int width, height; - ED_space_clip_get_size(C, &width, &height); + ED_space_clip_get_size(sc, &width, &height); *zoomx = (float)(ar->winrct.xmax - ar->winrct.xmin + 1) / (float)((ar->v2d.cur.xmax - ar->v2d.cur.xmin) * width); *zoomy = (float)(ar->winrct.ymax - ar->winrct.ymin + 1) / (float)((ar->v2d.cur.ymax - ar->v2d.cur.ymin) * height); @@ -265,9 +270,8 @@ void ED_clip_update_frame(const Main *mainp, int cfra) } } -static int selected_boundbox(const bContext *C, float min[2], float max[2]) +static int selected_boundbox(SpaceClip *sc, float min[2], float max[2]) { - SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTrackingTrack *track; int width, height, ok = FALSE; @@ -276,7 +280,7 @@ static int selected_boundbox(const bContext *C, float min[2], float max[2]) INIT_MINMAX2(min, max); - ED_space_clip_get_size(C, &width, &height); + ED_space_clip_get_size(sc, &width, &height); track = tracksbase->first; while (track) { @@ -319,17 +323,17 @@ int ED_clip_view_selection(const bContext *C, ARegion *ar, int fit) int w, h, frame_width, frame_height; float min[2], max[2]; - ED_space_clip_get_size(C, &frame_width, &frame_height); + ED_space_clip_get_size(sc, &frame_width, &frame_height); if (frame_width == 0 || frame_height == 0) return FALSE; - if (!selected_boundbox(C, min, max)) + if (!selected_boundbox(sc, min, max)) return FALSE; /* center view */ - clip_view_center_to_point(C, (max[0] + min[0]) / (2 * frame_width), - (max[1] + min[1]) / (2 * frame_height)); + clip_view_center_to_point(sc, (max[0] + min[0]) / (2 * frame_width), + (max[1] + min[1]) / (2 * frame_height)); w = max[0] - min[0]; h = max[1] - min[1]; @@ -347,7 +351,7 @@ int ED_clip_view_selection(const bContext *C, ARegion *ar, int fit) zoomx = (float)width / w / aspx; zoomy = (float)height / h / aspy; - newzoom = 1.0f / power_of_2(1.0f / MIN2(zoomx, zoomy)); + newzoom = 1.0f / power_of_2(1.0f / minf(zoomx, zoomy)); if (fit || sc->zoom > newzoom) sc->zoom = newzoom; @@ -377,15 +381,13 @@ void ED_clip_point_undistorted_pos(SpaceClip *sc, const float co[2], float r_co[ } } -void ED_clip_point_stable_pos(const bContext *C, float x, float y, float *xr, float *yr) +void ED_clip_point_stable_pos(SpaceClip *sc, ARegion *ar, float x, float y, float *xr, float *yr) { - ARegion *ar = CTX_wm_region(C); - SpaceClip *sc = CTX_wm_space_clip(C); int sx, sy, width, height; float zoomx, zoomy, pos[3], imat[4][4]; - ED_space_clip_get_zoom(C, &zoomx, &zoomy); - ED_space_clip_get_size(C, &width, &height); + ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy); + ED_space_clip_get_size(sc, &width, &height); UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &sx, &sy); @@ -416,18 +418,16 @@ void ED_clip_point_stable_pos(const bContext *C, float x, float y, float *xr, fl * \brief the reverse of ED_clip_point_stable_pos(), gets the marker region coords. * better name here? view_to_track / track_to_view or so? */ -void ED_clip_point_stable_pos__reverse(const bContext *C, const float co[2], float r_co[2]) +void ED_clip_point_stable_pos__reverse(SpaceClip *sc, ARegion *ar, const float co[2], float r_co[2]) { - SpaceClip *sc = CTX_wm_space_clip(C); - ARegion *ar = CTX_wm_region(C); float zoomx, zoomy; float pos[3]; int width, height; int sx, sy; UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &sx, &sy); - ED_space_clip_get_size(C, &width, &height); - ED_space_clip_get_zoom(C, &zoomx, &zoomy); + ED_space_clip_get_size(sc, &width, &height); + ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy); ED_clip_point_undistorted_pos(sc, co, pos); pos[2] = 0.0f; @@ -439,9 +439,10 @@ void ED_clip_point_stable_pos__reverse(const bContext *C, const float co[2], flo r_co[1] = (pos[1] * height * zoomy) + (float)sy; } -void ED_clip_mouse_pos(const bContext *C, wmEvent *event, float co[2]) +/* takes event->mval */ +void ED_clip_mouse_pos(SpaceClip *sc, ARegion *ar, const int mval[2], float co[2]) { - ED_clip_point_stable_pos(C, event->mval[0], event->mval[1], &co[0], &co[1]); + ED_clip_point_stable_pos(sc, ar, mval[0], mval[1], &co[0], &co[1]); } int ED_space_clip_check_show_trackedit(SpaceClip *sc) @@ -509,15 +510,15 @@ void ED_space_clip_set_clip(bContext *C, bScreen *screen, SpaceClip *sc, MovieCl Mask *ED_space_clip_get_mask(SpaceClip *sc) { - return sc->mask; + return sc->mask_info.mask; } void ED_space_clip_set_mask(bContext *C, SpaceClip *sc, Mask *mask) { - sc->mask = mask; + sc->mask_info.mask = mask; - if (sc->mask && sc->mask->id.us == 0) { - sc->clip->id.us = 1; + if (sc->mask_info.mask && sc->mask_info.mask->id.us == 0) { + sc->mask_info.mask->id.us = 1; } if (C) { diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c index abf7f416b9c..c0b11dda5c7 100644 --- a/source/blender/editors/space_clip/clip_graph_ops.c +++ b/source/blender/editors/space_clip/clip_graph_ops.c @@ -345,6 +345,7 @@ static int border_select_graph_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); + MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h index c61a0baa82e..392367f9071 100644 --- a/source/blender/editors/space_clip/clip_intern.h +++ b/source/blender/editors/space_clip/clip_intern.h @@ -69,9 +69,9 @@ void clip_draw_dopesheet_channels(const struct bContext *C, struct ARegion *ar); void CLIP_OT_dopesheet_select_channel(struct wmOperatorType *ot); /* clip_draw.c */ -void clip_draw_main(const struct bContext *C, struct ARegion *ar); +void clip_draw_main(const struct bContext *C, struct SpaceClip *sc, struct ARegion *ar); void clip_draw_grease_pencil(struct bContext *C, int onlyv2d); -void clip_draw_curfra_label(struct SpaceClip *sc, float x, float y); +void clip_draw_curfra_label(const int framenr, const float x, const float y); /* clip_graph_draw.c */ void clip_draw_graph(struct SpaceClip *sc, struct ARegion *ar, struct Scene *scene); @@ -125,7 +125,7 @@ void clip_graph_tracking_iterate(struct SpaceClip *sc, int selected_only, int in void clip_delete_track(struct bContext *C, struct MovieClip *clip, struct ListBase *tracksbase, struct MovieTrackingTrack *track); void clip_delete_marker(struct bContext *C, struct MovieClip *clip, struct ListBase *tracksbase, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker); -void clip_view_center_to_point(const struct bContext *C, float x, float y); +void clip_view_center_to_point(SpaceClip *sc, float x, float y); void clip_draw_cfra(struct SpaceClip *sc, struct ARegion *ar, struct Scene *scene); void clip_draw_sfra_efra(struct View2D *v2d, struct Scene *scene); @@ -150,6 +150,8 @@ void CLIP_OT_hide_tracks(struct wmOperatorType *ot); void CLIP_OT_hide_tracks_clear(struct wmOperatorType *ot); void CLIP_OT_lock_tracks(struct wmOperatorType *ot); +void CLIP_OT_set_solver_keyframe(struct wmOperatorType *ot); + void CLIP_OT_set_origin(struct wmOperatorType *ot); void CLIP_OT_set_plane(struct wmOperatorType *ot); void CLIP_OT_set_axis(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index 86d74ef4c78..e211b61aede 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -74,6 +74,7 @@ static void sclip_zoom_set(const bContext *C, float zoom, float location[2]) { SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); + float oldzoom = sc->zoom; int width, height; @@ -81,7 +82,7 @@ static void sclip_zoom_set(const bContext *C, float zoom, float location[2]) if (sc->zoom < 0.1f || sc->zoom > 4.0f) { /* check zoom limits */ - ED_space_clip_get_size(C, &width, &height); + ED_space_clip_get_size(sc, &width, &height); width *= sc->zoom; height *= sc->zoom; @@ -95,7 +96,7 @@ static void sclip_zoom_set(const bContext *C, float zoom, float location[2]) } if ((U.uiflag & USER_ZOOM_TO_MOUSEPOS) && location) { - ED_space_clip_get_size(C, &width, &height); + ED_space_clip_get_size(sc, &width, &height); sc->xof += ((location[0] - 0.5f) * width - sc->xof) * (sc->zoom - oldzoom) / sc->zoom; sc->yof += ((location[1] - 0.5f) * height - sc->yof) * (sc->zoom - oldzoom) / sc->zoom; @@ -111,16 +112,20 @@ static void sclip_zoom_set_factor(const bContext *C, float zoomfac, float locati static void sclip_zoom_set_factor_exec(bContext *C, wmEvent *event, float factor) { + ARegion *ar = CTX_wm_region(C); + float location[2], *mpos = NULL; if (event) { - ED_clip_mouse_pos(C, event, location); + SpaceClip *sc = CTX_wm_space_clip(C); + + ED_clip_mouse_pos(sc, ar, event->mval, location); mpos = location; } sclip_zoom_set_factor(C, factor, mpos); - ED_region_tag_redraw(CTX_wm_region(C)); + ED_region_tag_redraw(ar); } /******************** open clip operator ********************/ @@ -270,8 +275,7 @@ void CLIP_OT_open(wmOperatorType *ot) /* properties */ WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, - WM_FILESEL_RELPATH | WM_FILESEL_FILES | WM_FILESEL_DIRECTORY, - FILE_DEFAULTDISPLAY); + WM_FILESEL_RELPATH | WM_FILESEL_FILES | WM_FILESEL_DIRECTORY, FILE_DEFAULTDISPLAY); } /******************* reload clip operator *********************/ @@ -466,6 +470,8 @@ typedef struct ViewZoomData { static void view_zoom_init(bContext *C, wmOperator *op, wmEvent *event) { SpaceClip *sc = CTX_wm_space_clip(C); + ARegion *ar = CTX_wm_region(C); + ViewZoomData *vpd; op->customdata = vpd = MEM_callocN(sizeof(ViewZoomData), "ClipViewZoomData"); @@ -476,7 +482,7 @@ static void view_zoom_init(bContext *C, wmOperator *op, wmEvent *event) vpd->zoom = sc->zoom; vpd->event_type = event->type; - ED_clip_mouse_pos(C, event, vpd->location); + ED_clip_mouse_pos(sc, ar, event->mval, vpd->location); WM_event_add_modal_handler(C, op); } @@ -593,9 +599,12 @@ static int view_zoom_in_exec(bContext *C, wmOperator *op) static int view_zoom_in_invoke(bContext *C, wmOperator *op, wmEvent *event) { + SpaceClip *sc = CTX_wm_space_clip(C); + ARegion *ar = CTX_wm_region(C); + float location[2]; - ED_clip_mouse_pos(C, event, location); + ED_clip_mouse_pos(sc, ar, event->mval, location); RNA_float_set_array(op->ptr, "location", location); return view_zoom_in_exec(C, op); @@ -633,9 +642,12 @@ static int view_zoom_out_exec(bContext *C, wmOperator *op) static int view_zoom_out_invoke(bContext *C, wmOperator *op, wmEvent *event) { + SpaceClip *sc = CTX_wm_space_clip(C); + ARegion *ar = CTX_wm_region(C); + float location[2]; - ED_clip_mouse_pos(C, event, location); + ED_clip_mouse_pos(sc, ar, event->mval, location); RNA_float_set_array(op->ptr, "location", location); return view_zoom_out_exec(C, op); @@ -706,7 +718,7 @@ static int view_all_exec(bContext *C, wmOperator *op) sc = CTX_wm_space_clip(C); ar = CTX_wm_region(C); - ED_space_clip_get_size(C, &w, &h); + ED_space_clip_get_size(sc, &w, &h); ED_space_clip_get_aspect(sc, &aspx, &aspy); w = w * aspx; @@ -722,7 +734,7 @@ static int view_all_exec(bContext *C, wmOperator *op) zoomx = (float) width / (w + 2 * margin); zoomy = (float) height / (h + 2 * margin); - sclip_zoom_set(C, MIN2(zoomx, zoomy), NULL); + sclip_zoom_set(C, minf(zoomx, zoomy), NULL); } else { if ((w >= width || h >= height) && (width > 0 && height > 0)) { @@ -730,7 +742,7 @@ static int view_all_exec(bContext *C, wmOperator *op) zoomy = (float) height / h; /* find the zoom value that will fit the image in the image space */ - sclip_zoom_set(C, 1.0f / power_of_2(1.0f / MIN2(zoomx, zoomy)), NULL); + sclip_zoom_set(C, 1.0f / power_of_2(1.0f / minf(zoomx, zoomy)), NULL); } else sclip_zoom_set(C, 1.0f, NULL); @@ -992,7 +1004,7 @@ static void proxy_startjob(void *pjv, short *stop, short *do_update, float *prog break; *do_update = TRUE; - *progress = ((float) cfra) / (efra - sfra); + *progress = ((float) cfra - sfra) / (efra - sfra); } if (distortion) diff --git a/source/blender/editors/space_clip/clip_toolbar.c b/source/blender/editors/space_clip/clip_toolbar.c index 3ffba75f2ef..d8c7bf3f809 100644 --- a/source/blender/editors/space_clip/clip_toolbar.c +++ b/source/blender/editors/space_clip/clip_toolbar.c @@ -224,7 +224,7 @@ static void clip_panel_operator_redo(const bContext *C, Panel *pa) if (op == NULL) return; - if (WM_operator_poll((bContext*)C, op->type) == 0) + if (WM_operator_poll((bContext *)C, op->type) == 0) return; block = uiLayoutGetBlock(pa->layout); diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index d9c9f63e4a3..ddc624b4cdf 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -223,13 +223,12 @@ void clip_delete_marker(bContext *C, MovieClip *clip, ListBase *tracksbase, } } -void clip_view_center_to_point(const bContext *C, float x, float y) +void clip_view_center_to_point(SpaceClip *sc, float x, float y) { - SpaceClip *sc = CTX_wm_space_clip(C); int width, height; float aspx, aspy; - ED_space_clip_get_size(C, &width, &height); + ED_space_clip_get_size(sc, &width, &height); ED_space_clip_get_aspect(sc, &aspx, &aspy); sc->xof = (x - 0.5f) * width * aspx; @@ -264,7 +263,7 @@ void clip_draw_cfra(SpaceClip *sc, ARegion *ar, Scene *scene) UI_view2d_getscale(v2d, &xscale, &yscale); glScalef(1.0f / xscale, 1.0f, 1.0f); - clip_draw_curfra_label(sc, (float)sc->user.framenr * xscale, 18); + clip_draw_curfra_label(sc->user.framenr, (float)sc->user.framenr * xscale, 18); /* restore view transform */ glScalef(xscale, 1.0, 1.0); diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 3623cd1d58b..3428c47ff43 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -389,7 +389,6 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn) } switch (wmn->action) { case NA_SELECTED: - clip_scopes_tag_refresh(sa); ED_area_tag_redraw(sa); break; case NA_EDITED: @@ -478,6 +477,8 @@ static void clip_operatortypes(void) WM_operatortype_append(CLIP_OT_hide_tracks_clear); WM_operatortype_append(CLIP_OT_lock_tracks); + WM_operatortype_append(CLIP_OT_set_solver_keyframe); + /* orientation */ WM_operatortype_append(CLIP_OT_set_origin); WM_operatortype_append(CLIP_OT_set_plane); @@ -563,6 +564,12 @@ static void clip_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "CLIP_OT_solve_camera", SKEY, KM_PRESS, KM_SHIFT, 0); + kmi = WM_keymap_add_item(keymap, "CLIP_OT_set_solver_keyframe", QKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "keyframe", 0); + + kmi = WM_keymap_add_item(keymap, "CLIP_OT_set_solver_keyframe", EKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "keyframe", 1); + /* ******** Hotkeys avalaible for main region only ******** */ keymap = WM_keymap_find(keyconf, "Clip Editor", SPACE_CLIP, 0); @@ -766,8 +773,8 @@ static int clip_context(const bContext *C, const char *member, bContextDataResul return TRUE; } else if (CTX_data_equals(member, "edit_mask")) { - if (sc->mask) - CTX_data_id_pointer_set(result, &sc->mask->id); + if (sc->mask_info.mask) + CTX_data_id_pointer_set(result, &sc->mask_info.mask->id); return TRUE; } @@ -1017,7 +1024,7 @@ static void movieclip_main_area_set_view2d(const bContext *C, ARegion *ar) float x1, y1, w, h; int width, height, winx, winy; - ED_space_clip_get_size(C, &width, &height); + ED_space_clip_get_size(sc, &width, &height); w = width; h = height; @@ -1066,10 +1073,11 @@ static void clip_main_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy); - /* own keymap */ + /* mask polls mode */ keymap = WM_keymap_find(wm->defaultconf, "Mask Editing", 0, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); + /* own keymap */ keymap = WM_keymap_find(wm->defaultconf, "Clip", SPACE_CLIP, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); @@ -1077,50 +1085,6 @@ static void clip_main_area_init(wmWindowManager *wm, ARegion *ar) WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } -static void clip_main_area_draw_mask(const bContext *C, ARegion *ar) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - int x, y; - int width, height; - float zoomx, zoomy; - - /* frame image */ - float maxdim; - float xofs, yofs; - - /* find window pixel coordinates of origin */ - UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y); - - ED_space_clip_get_size(C, &width, &height); - ED_space_clip_get_zoom(C, &zoomx, &zoomy); - - /* frame the image */ - maxdim = maxf(width, height); - if (width == height) { - xofs = yofs = 0; - } - else if (width < height) { - xofs = ((height - width) / -2.0f) * zoomx; - yofs = 0.0f; - } - else { /* (width > height) */ - xofs = 0.0f; - yofs = ((width - height) / -2.0f) * zoomy; - } - - /* apply transformation so mask editing tools will assume drawing from the origin in normalized space */ - glPushMatrix(); - glTranslatef(x + xofs, y + yofs, 0); - glScalef(maxdim * zoomx, maxdim * zoomy, 0); - glMultMatrixf(sc->stabmat); - - ED_mask_draw(C, sc->mask_draw_flag, sc->mask_draw_type); - - ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); - - glPopMatrix(); -} - static void clip_main_area_draw(const bContext *C, ARegion *ar) { /* draw entirely, view changes should be handled here */ @@ -1155,10 +1119,23 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar) /* data... */ movieclip_main_area_set_view2d(C, ar); - clip_draw_main(C, ar); + clip_draw_main(C, sc, ar); if (sc->mode == SC_MODE_MASKEDIT) { - clip_main_area_draw_mask(C, ar); + + Mask *mask = CTX_data_edit_mask(C); + if (mask) { + ScrArea *sa = CTX_wm_area(C); + int width, height; + ED_mask_get_size(sa, &width, &height); + ED_mask_draw_region(mask, ar, + sc->mask_info.draw_flag, sc->mask_info.draw_type, + width, height, + TRUE, TRUE, + sc->stabmat, C); + } + + } /* Grease Pencil */ diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 2e4ba844646..153287eecdd 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -91,7 +91,7 @@ static void add_marker(const bContext *C, float x, float y) int width, height; int framenr = ED_space_clip_get_clip_frame_number(sc); - ED_space_clip_get_size(C, &width, &height); + ED_space_clip_get_size(sc, &width, &height); track = BKE_tracking_track_add(tracking, tracksbase, x, y, framenr, width, height); @@ -107,7 +107,7 @@ static int add_marker_exec(bContext *C, wmOperator *op) float pos[2]; int width, height; - ED_space_clip_get_size(C, &width, &height); + ED_space_clip_get_size(sc, &width, &height); if (!width || !height) return OPERATOR_CANCELLED; @@ -127,9 +127,12 @@ static int add_marker_exec(bContext *C, wmOperator *op) static int add_marker_invoke(bContext *C, wmOperator *op, wmEvent *event) { + SpaceClip *sc = CTX_wm_space_clip(C); + ARegion *ar = CTX_wm_region(C); + float co[2]; - ED_clip_mouse_pos(C, event, co); + ED_clip_mouse_pos(sc, ar, event->mval, co); RNA_float_set_array(op->ptr, "location", co); @@ -370,8 +373,8 @@ static int mouse_on_slide_zone(SpaceClip *sc, MovieTrackingMarker *marker, dx = size / width / sc->zoom; dy = size / height / sc->zoom; - dx = MIN2(dx, (max[0] - min[0]) / 6.0f); - dy = MIN2(dy, (max[1] - min[1]) / 6.0f); + dx = minf(dx, (max[0] - min[0]) / 6.0f); + dy = minf(dy, (max[1] - min[1]) / 6.0f); return IN_RANGE_INCL(co[0], slide_zone[0] - dx, slide_zone[0] + dx) && IN_RANGE_INCL(co[1], slide_zone[1] - dy, slide_zone[1] + dy); @@ -422,14 +425,14 @@ static int get_mouse_pattern_corner(SpaceClip *sc, MovieTrackingMarker *marker, cur_len = len_v2v2(marker->pattern_corners[i], marker->pattern_corners[next]); - len = MIN2(cur_len, len); + len = minf(cur_len, len); } dx = 12.0f / width / sc->zoom; dy = 12.0f / height / sc->zoom; - dx = MIN2(dx, len * 2.0f / 3.0f); - dy = MIN2(dy, len * width / height * 2.0f / 3.0f); + dx = minf(dx, len * 2.0f / 3.0f); + dy = minf(dy, len * width / height * 2.0f / 3.0f); for (i = 0; i < 4; i++) { float crn[2]; @@ -460,8 +463,8 @@ static int mouse_on_offset(SpaceClip *sc, MovieTrackingTrack *track, MovieTracki dx = 12.0f / width / sc->zoom; dy = 12.0f / height / sc->zoom; - dx = MIN2(dx, (pat_max[0] - pat_min[0]) / 2.0f); - dy = MIN2(dy, (pat_max[1] - pat_min[1]) / 2.0f); + dx = minf(dx, (pat_max[0] - pat_min[0]) / 2.0f); + dy = minf(dy, (pat_max[1] - pat_min[1]) / 2.0f); return co[0] >= pos[0] - dx && co[0] <= pos[0] + dx && co[1] >= pos[1] - dy && co[1] <= pos[1] + dy; } @@ -525,6 +528,8 @@ static void show_cursor(bContext *C) MovieTrackingTrack *tracking_marker_check_slide(bContext *C, wmEvent *event, int *area_r, int *action_r, int *corner_r) { SpaceClip *sc = CTX_wm_space_clip(C); + ARegion *ar = CTX_wm_region(C); + MovieClip *clip = ED_space_clip_get_clip(sc); MovieTrackingTrack *track; int width, height; @@ -533,12 +538,12 @@ MovieTrackingTrack *tracking_marker_check_slide(bContext *C, wmEvent *event, int int framenr = ED_space_clip_get_clip_frame_number(sc); int action = -1, area = 0, corner = -1; - ED_space_clip_get_size(C, &width, &height); + ED_space_clip_get_size(sc, &width, &height); if (width == 0 || height == 0) return NULL; - ED_clip_mouse_pos(C, event, co); + ED_clip_mouse_pos(sc, ar, event->mval, co); track = tracksbase->first; while (track) { @@ -622,6 +627,8 @@ MovieTrackingTrack *tracking_marker_check_slide(bContext *C, wmEvent *event, int static void *slide_marker_customdata(bContext *C, wmEvent *event) { SpaceClip *sc = CTX_wm_space_clip(C); + ARegion *ar = CTX_wm_region(C); + MovieTrackingTrack *track; int width, height; float co[2]; @@ -629,12 +636,12 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event) int framenr = ED_space_clip_get_clip_frame_number(sc); int area, action, corner; - ED_space_clip_get_size(C, &width, &height); + ED_space_clip_get_size(sc, &width, &height); if (width == 0 || height == 0) return NULL; - ED_clip_mouse_pos(C, event, co); + ED_clip_mouse_pos(sc, ar, event->mval, co); track = tracking_marker_check_slide(C, event, &area, &action, &corner); if (track) { @@ -700,6 +707,8 @@ static void free_slide_data(SlideMarkerData *data) static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) { SpaceClip *sc = CTX_wm_space_clip(C); + ARegion *ar = CTX_wm_region(C); + SlideMarkerData *data = (SlideMarkerData *)op->customdata; float dx, dy, mdelta[2]; @@ -751,7 +760,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) float start[2], end[2]; float scale; - ED_clip_point_stable_pos(C, data->mval[0], data->mval[1], &start[0], &start[1]); + ED_clip_point_stable_pos(sc, ar, data->mval[0], data->mval[1], &start[0], &start[1]); sub_v2_v2(start, data->old_pos); @@ -767,7 +776,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) mval[1] = event->mval[1]; } - ED_clip_point_stable_pos(C, mval[0], mval[1], &end[0], &end[1]); + ED_clip_point_stable_pos(sc, ar, mval[0], mval[1], &end[0], &end[1]); sub_v2_v2(end, data->old_pos); @@ -825,7 +834,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) sub_v2_v2v2(start, data->spos, data->old_pos); - ED_clip_point_stable_pos(C, mval[0], mval[1], &end[0], &end[1]); + ED_clip_point_stable_pos(sc, ar, mval[0], mval[1], &end[0], &end[1]); sub_v2_v2(end, data->old_pos); if (len_v2(start) > 0.0f) { @@ -2842,6 +2851,51 @@ void CLIP_OT_lock_tracks(wmOperatorType *ot) RNA_def_enum(ot->srna, "action", actions_items, 0, "Action", "Lock action to execute"); } +/********************** set keyframe operator *********************/ + +static int set_solver_keyframe_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + MovieClip *clip = ED_space_clip_get_clip(sc); + MovieTracking *tracking = &clip->tracking; + MovieTrackingSettings *settings = &tracking->settings; + int keyframe = RNA_enum_get(op->ptr, "keyframe"); + int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, sc->user.framenr); + + if (keyframe == 0) + settings->keyframe1 = framenr; + else + settings->keyframe2 = framenr; + + WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, clip); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_set_solver_keyframe(wmOperatorType *ot) +{ + static EnumPropertyItem keyframe_items[] = { + {0, "KEYFRAME_A", 0, "Keyframe A", ""}, + {1, "KEYFRAME_B", 0, "Keyframe B", ""}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name = "Set Solver Keyframe"; + ot->description = "Set keyframe used by solver"; + ot->idname = "CLIP_OT_set_solver_keyframe"; + + /* api callbacks */ + ot->exec = set_solver_keyframe_exec; + ot->poll = ED_space_clip_tracking_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "keyframe", keyframe_items, 0, "Keyframe", "keyframe to set"); +} + /********************** track copy color operator *********************/ static int track_copy_color_exec(bContext *C, wmOperator *UNUSED(op)) diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c index 0d933c1dff3..559fe8c840d 100644 --- a/source/blender/editors/space_clip/tracking_select.c +++ b/source/blender/editors/space_clip/tracking_select.c @@ -107,7 +107,7 @@ static int mouse_on_crns(float co[2], float pos[2], float crns[4][2], float epsx { float dist = dist_to_crns(co, pos, crns); - return dist < MAX2(epsx, epsy); + return dist < maxf(epsx, epsy); } static int track_mouse_area(const bContext *C, float co[2], MovieTrackingTrack *track) @@ -119,7 +119,7 @@ static int track_mouse_area(const bContext *C, float co[2], MovieTrackingTrack * float epsx, epsy; int width, height; - ED_space_clip_get_size(C, &width, &height); + ED_space_clip_get_size(sc, &width, &height); BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); @@ -128,8 +128,8 @@ static int track_mouse_area(const bContext *C, float co[2], MovieTrackingTrack * epsy = MIN4(pat_min[1] - marker->search_min[1], marker->search_max[1] - pat_max[1], fabsf(pat_min[1]), fabsf(pat_max[1])) / 2; - epsx = MAX2(epsx, 2.0f / width); - epsy = MAX2(epsy, 2.0f / height); + epsx = maxf(epsx, 2.0f / width); + epsy = maxf(epsy, 2.0f / height); if (sc->flag & SC_SHOW_MARKER_SEARCH) { if (mouse_on_rect(co, marker->pos, marker->search_min, marker->search_max, epsx, epsy)) @@ -281,6 +281,9 @@ static int select_exec(bContext *C, wmOperator *op) static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) { + SpaceClip *sc = CTX_wm_space_clip(C); + ARegion *ar = CTX_wm_region(C); + float co[2]; int extend = RNA_boolean_get(op->ptr, "extend"); @@ -299,7 +302,7 @@ static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) } } - ED_clip_mouse_pos(C, event, co); + ED_clip_mouse_pos(sc, ar, event->mval, co); RNA_float_set_array(op->ptr, "location", co); return select_exec(C, op); @@ -333,6 +336,8 @@ void CLIP_OT_select(wmOperatorType *ot) static int border_select_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); + ARegion *ar = CTX_wm_region(C); + MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *track; @@ -348,8 +353,8 @@ static int border_select_exec(bContext *C, wmOperator *op) rect.xmax = RNA_int_get(op->ptr, "xmax"); rect.ymax = RNA_int_get(op->ptr, "ymax"); - ED_clip_point_stable_pos(C, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin); - ED_clip_point_stable_pos(C, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax); + ED_clip_point_stable_pos(sc, ar, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin); + ED_clip_point_stable_pos(sc, ar, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax); mode = RNA_int_get(op->ptr, "gesture_mode"); extend = RNA_boolean_get(op->ptr, "extend"); @@ -414,6 +419,8 @@ void CLIP_OT_select_border(wmOperatorType *ot) static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, short select) { SpaceClip *sc = CTX_wm_space_clip(C); + ARegion *ar = CTX_wm_region(C); + MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *track; @@ -435,7 +442,7 @@ static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, sho float screen_co[2]; /* marker in screen coords */ - ED_clip_point_stable_pos__reverse(C, marker->pos, screen_co); + ED_clip_point_stable_pos__reverse(sc, ar, marker->pos, screen_co); if (BLI_in_rcti(&rect, screen_co[0], screen_co[1]) && BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], V2D_IS_CLIPPED)) @@ -519,6 +526,8 @@ static int marker_inside_ellipse(MovieTrackingMarker *marker, float offset[2], f static int circle_select_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); + ARegion *ar = CTX_wm_region(C); + MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *track; @@ -535,13 +544,13 @@ static int circle_select_exec(bContext *C, wmOperator *op) mode = RNA_int_get(op->ptr, "gesture_mode"); /* compute ellipse and position in unified coordinates */ - ED_space_clip_get_size(C, &width, &height); - ED_space_clip_get_zoom(C, &zoomx, &zoomy); + ED_space_clip_get_size(sc, &width, &height); + ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy); ellipse[0] = width * zoomx / radius; ellipse[1] = height * zoomy / radius; - ED_clip_point_stable_pos(C, x, y, &offset[0], &offset[1]); + ED_clip_point_stable_pos(sc, ar, x, y, &offset[0], &offset[1]); /* do selection */ track = tracksbase->first; diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c index 2897c5d7d67..4c2f0ac73d4 100644 --- a/source/blender/editors/space_console/console_draw.c +++ b/source/blender/editors/space_console/console_draw.c @@ -191,7 +191,7 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha } -static int console_textview_main__internal(struct SpaceConsole *sc, struct ARegion *ar, int draw, int mval[2], void **mouse_pick, int *pos_pick) +static int console_textview_main__internal(struct SpaceConsole *sc, ARegion *ar, int draw, int mval[2], void **mouse_pick, int *pos_pick) { ConsoleLine cl_dummy = {NULL}; int ret = 0; @@ -226,19 +226,19 @@ static int console_textview_main__internal(struct SpaceConsole *sc, struct ARegi } -void console_textview_main(struct SpaceConsole *sc, struct ARegion *ar) +void console_textview_main(struct SpaceConsole *sc, ARegion *ar) { int mval[2] = {INT_MAX, INT_MAX}; console_textview_main__internal(sc, ar, 1, mval, NULL, NULL); } -int console_textview_height(struct SpaceConsole *sc, struct ARegion *ar) +int console_textview_height(struct SpaceConsole *sc, ARegion *ar) { int mval[2] = {INT_MAX, INT_MAX}; return console_textview_main__internal(sc, ar, 0, mval, NULL, NULL); } -int console_char_pick(struct SpaceConsole *sc, struct ARegion *ar, int mval[2]) +int console_char_pick(struct SpaceConsole *sc, ARegion *ar, int mval[2]) { int pos_pick = 0; void *mouse_pick = NULL; diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 6856ce996e7..7630143acd1 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -70,7 +70,7 @@ #define INACTIVATE 2 /* ---------- FILE SELECTION ------------ */ -static FileSelection find_file_mouse_rect(SpaceFile *sfile, struct ARegion *ar, const rcti *rect) +static FileSelection find_file_mouse_rect(SpaceFile *sfile, ARegion *ar, const rcti *rect) { FileSelection sel; float fxmin, fymin, fxmax, fymax; @@ -1277,7 +1277,7 @@ void FILE_OT_hidedot(struct wmOperatorType *ot) ot->poll = ED_operator_file_active; /* <- important, handler is on window level */ } -struct ARegion *file_buttons_region(struct ScrArea *sa) +ARegion *file_buttons_region(ScrArea *sa) { ARegion *ar, *arnew; diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index ef3e150b034..34f16c11537 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -265,7 +265,7 @@ void ED_fileselect_reset_params(SpaceFile *sfile) sfile->params->title[0] = '\0'; } -int ED_fileselect_layout_numfiles(FileLayout *layout, struct ARegion *ar) +int ED_fileselect_layout_numfiles(FileLayout *layout, ARegion *ar) { int numfiles; @@ -472,7 +472,7 @@ static void column_widths(struct FileList *files, struct FileLayout *layout) } } -void ED_fileselect_init_layout(struct SpaceFile *sfile, struct ARegion *ar) +void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *ar) { FileSelectParams *params = ED_fileselect_get_params(sfile); FileLayout *layout = NULL; @@ -559,7 +559,7 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, struct ARegion *ar) layout->dirty = FALSE; } -FileLayout *ED_fileselect_get_layout(struct SpaceFile *sfile, struct ARegion *ar) +FileLayout *ED_fileselect_get_layout(struct SpaceFile *sfile, ARegion *ar) { if (!sfile->layout) { ED_fileselect_init_layout(sfile, ar); diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index b1e1b6e411a..55dca725131 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1214,7 +1214,8 @@ void GRAPH_OT_sound_bake(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); RNA_def_float(ot->srna, "low", 0.0f, 0.0, 100000.0, "Lowest frequency", "", 0.1, 1000.00); RNA_def_float(ot->srna, "high", 100000.0, 0.0, 100000.0, "Highest frequency", "", 0.1, 1000.00); RNA_def_float(ot->srna, "attack", 0.005, 0.0, 2.0, "Attack time", "", 0.01, 0.1); diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index f4cb4ec3d05..a4611cf1453 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -488,7 +488,7 @@ static void graph_listener(ScrArea *sa, wmNotifier *wmn) // XXX: restore the case below if not enough updates occur... //default: - // if (wmn->data==ND_KEYS) + // if (wmn->data == ND_KEYS) // ED_area_tag_redraw(sa); } } diff --git a/source/blender/editors/space_image/CMakeLists.txt b/source/blender/editors/space_image/CMakeLists.txt index f397f2387d7..3e3c6adcf8c 100644 --- a/source/blender/editors/space_image/CMakeLists.txt +++ b/source/blender/editors/space_image/CMakeLists.txt @@ -40,6 +40,7 @@ set(INC_SYS set(SRC image_buttons.c image_draw.c + image_edit.c image_ops.c space_image.c diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 7d358bcfb8b..a736cc4cb73 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -27,8 +27,6 @@ * \ingroup spimage */ - - #include <string.h> #include <stdio.h> @@ -260,7 +258,7 @@ void image_preview_event(int event) /* nothing drawn here, we use it to store values */ -static void preview_cb(struct ScrArea *sa, struct uiBlock *block) +static void preview_cb(ScrArea *sa, struct uiBlock *block) { SpaceImage *sima = sa->spacedata.first; rctf dispf; diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index cf78eaabd88..52ed7fd1d0b 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -710,7 +710,7 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene) what_image(sima); if (sima->image) { - ED_image_aspect(sima->image, &xuser_asp, &yuser_asp); + ED_image_get_aspect(sima->image, &xuser_asp, &yuser_asp); /* UGLY hack? until now iusers worked fine... but for flipbook viewer we need this */ if (sima->image->type == IMA_TYPE_COMPOSITE) { @@ -727,7 +727,7 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene) /* retrieve the image and information about it */ ima = ED_space_image(sima); - ED_space_image_zoom(sima, ar, &zoomx, &zoomy); + ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy); show_viewer = (ima && ima->source == IMA_SRC_VIEWER); show_render = (show_viewer && ima->type == IMA_TYPE_R_RESULT); @@ -754,7 +754,7 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene) draw_image_buffer(sima, ar, scene, ima, ibuf, 0.0f, 0.0f, zoomx, zoomy); /* paint helpers */ - if (sima->flag & SI_DRAWTOOL) + if (sima->mode == SI_MODE_PAINT) draw_image_paint_helpers(ar, scene, zoomx, zoomy); diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c new file mode 100644 index 00000000000..58e6a1aa94a --- /dev/null +++ b/source/blender/editors/space_image/image_edit.c @@ -0,0 +1,408 @@ +/* + * ***** 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 blender/editors/space_image/image_editor.c + * \ingroup spimage + */ + +#include "DNA_mask_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_main.h" +#include "BKE_tessmesh.h" + +#include "IMB_imbuf_types.h" + +#include "ED_image.h" /* own include */ +#include "ED_mesh.h" +#include "ED_screen.h" +#include "ED_uvedit.h" + +#include "UI_view2d.h" + +#include "WM_api.h" +#include "WM_types.h" + +/* note; image_panel_properties() uses pointer to sima->image directly */ +Image *ED_space_image(SpaceImage *sima) +{ + return sima->image; +} + +/* called to assign images to UV faces */ +void ED_space_image_set(SpaceImage *sima, Scene *scene, Object *obedit, Image *ima) +{ + /* context may be NULL, so use global */ + ED_uvedit_assign_image(G.main, scene, obedit, ima, sima->image); + + /* change the space ima after because uvedit_face_visible_test uses the space ima + * to check if the face is displayed in UV-localview */ + sima->image = ima; + + if (ima == NULL || ima->type == IMA_TYPE_R_RESULT || ima->type == IMA_TYPE_COMPOSITE) { + if (sima->mode == SI_MODE_PAINT) { + sima->mode = SI_MODE_VIEW; + } + } + + if (sima->image) + BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE); + + if (sima->image && sima->image->id.us == 0) + sima->image->id.us = 1; + + if (obedit) + WM_main_add_notifier(NC_GEOM | ND_DATA, obedit->data); + + WM_main_add_notifier(NC_SPACE | ND_SPACE_IMAGE, NULL); +} + +Mask *ED_space_image_get_mask(SpaceImage *sima) +{ + return sima->mask_info.mask; +} + +void ED_space_image_set_mask(bContext *C, SpaceImage *sima, Mask *mask) +{ + sima->mask_info.mask = mask; + + /* weak, but same as image/space */ + if (sima->mask_info.mask && sima->mask_info.mask->id.us == 0) + sima->mask_info.mask->id.us = 1; + + if (C) { + WM_event_add_notifier(C, NC_MASK | NA_SELECTED, mask); + } +} + +ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **lock_r) +{ + ImBuf *ibuf; + + if (sima && sima->image) { +#if 0 + if (sima->image->type == IMA_TYPE_R_RESULT && BIF_show_render_spare()) + return BIF_render_spare_imbuf(); + else +#endif + ibuf = BKE_image_acquire_ibuf(sima->image, &sima->iuser, lock_r); + + if (ibuf && (ibuf->rect || ibuf->rect_float)) + return ibuf; + } + + return NULL; +} + +void ED_space_image_release_buffer(SpaceImage *sima, void *lock) +{ + if (sima && sima->image) + BKE_image_release_ibuf(sima->image, lock); +} + +int ED_space_image_has_buffer(SpaceImage *sima) +{ + ImBuf *ibuf; + void *lock; + int has_buffer; + + ibuf = ED_space_image_acquire_buffer(sima, &lock); + has_buffer = (ibuf != NULL); + ED_space_image_release_buffer(sima, lock); + + return has_buffer; +} + +void ED_image_get_size(Image *ima, int *width, int *height) +{ + ImBuf *ibuf = NULL; + void *lock; + + if (ima) + ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); + + if (ibuf && ibuf->x > 0 && ibuf->y > 0) { + *width = ibuf->x; + *height = ibuf->y; + } + else { + *width = IMG_SIZE_FALLBACK; + *height = IMG_SIZE_FALLBACK; + } + + if (ima) + BKE_image_release_ibuf(ima, lock); +} + +void ED_space_image_get_size(SpaceImage *sima, int *width, int *height) +{ + Scene *scene = sima->iuser.scene; + ImBuf *ibuf; + void *lock; + + ibuf = ED_space_image_acquire_buffer(sima, &lock); + + if (ibuf && ibuf->x > 0 && ibuf->y > 0) { + *width = ibuf->x; + *height = ibuf->y; + } + else if (sima->image && sima->image->type == IMA_TYPE_R_RESULT && scene) { + /* not very important, just nice */ + *width = (scene->r.xsch * scene->r.size) / 100; + *height = (scene->r.ysch * scene->r.size) / 100; + + if ((scene->r.mode & R_BORDER) && (scene->r.mode & R_CROP)) { + *width *= (scene->r.border.xmax - scene->r.border.xmin); + *height *= (scene->r.border.ymax - scene->r.border.ymin); + } + + } + /* I know a bit weak... but preview uses not actual image size */ + // XXX else if (image_preview_active(sima, width, height)); + else { + *width = IMG_SIZE_FALLBACK; + *height = IMG_SIZE_FALLBACK; + } + + ED_space_image_release_buffer(sima, lock); +} + +void ED_space_image_get_size_fl(SpaceImage *sima, float size[2]) +{ + int size_i[2]; + ED_space_image_get_size(sima, &size_i[0], &size_i[1]); + size[0] = size_i[0]; + size[1] = size_i[1]; +} + +void ED_image_get_aspect(Image *ima, float *aspx, float *aspy) +{ + *aspx = *aspy = 1.0; + + if ((ima == NULL) || (ima->type == IMA_TYPE_R_RESULT) || (ima->type == IMA_TYPE_COMPOSITE) || + (ima->aspx == 0.0f || ima->aspy == 0.0f)) + { + return; + } + + /* x is always 1 */ + *aspy = ima->aspy / ima->aspx; +} + +void ED_space_image_get_aspect(SpaceImage *sima, float *aspx, float *aspy) +{ + ED_image_get_aspect(ED_space_image(sima), aspx, aspy); +} + +void ED_space_image_get_zoom(SpaceImage *sima, ARegion *ar, float *zoomx, float *zoomy) +{ + int width, height; + + ED_space_image_get_size(sima, &width, &height); + + *zoomx = (float)(ar->winrct.xmax - ar->winrct.xmin + 1) / (float)((ar->v2d.cur.xmax - ar->v2d.cur.xmin) * width); + *zoomy = (float)(ar->winrct.ymax - ar->winrct.ymin + 1) / (float)((ar->v2d.cur.ymax - ar->v2d.cur.ymin) * height); +} + +void ED_space_image_get_uv_aspect(SpaceImage *sima, float *aspx, float *aspy) +{ + int w, h; + + ED_space_image_get_aspect(sima, aspx, aspy); + ED_space_image_get_size(sima, &w, &h); + + *aspx *= (float)w; + *aspy *= (float)h; + + if (*aspx < *aspy) { + *aspy = *aspy / *aspx; + *aspx = 1.0f; + } + else { + *aspx = *aspx / *aspy; + *aspy = 1.0f; + } +} + +void ED_image_get_uv_aspect(Image *ima, float *aspx, float *aspy) +{ + int w, h; + + ED_image_get_aspect(ima, aspx, aspy); + ED_image_get_size(ima, &w, &h); + + *aspx *= (float)w; + *aspy *= (float)h; +} + +/* takes event->mval */ +void ED_image_mouse_pos(SpaceImage *sima, ARegion *ar, const int mval[2], float co[2]) +{ + int sx, sy, width, height; + float zoomx, zoomy; + + ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy); + ED_space_image_get_size(sima, &width, &height); + + UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &sx, &sy); + + co[0] = ((mval[0] - sx) / zoomx) / width; + co[1] = ((mval[1] - sy) / zoomy) / height; +} + +void ED_image_point_pos(SpaceImage *sima, ARegion *ar, float x, float y, float *xr, float *yr) +{ + int sx, sy, width, height; + float zoomx, zoomy; + + ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy); + ED_space_image_get_size(sima, &width, &height); + + UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &sx, &sy); + + *xr = ((x - sx) / zoomx) / width; + *yr = ((y - sy) / zoomy) / height; +} + +void ED_image_point_pos__reverse(SpaceImage *sima, ARegion *ar, const float co[2], float r_co[2]) +{ + float zoomx, zoomy; + int width, height; + int sx, sy; + + UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &sx, &sy); + ED_space_image_get_size(sima, &width, &height); + ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy); + + r_co[0] = (co[0] * width * zoomx) + (float)sx; + r_co[1] = (co[1] * height * zoomy) + (float)sy; +} + +int ED_space_image_show_render(SpaceImage *sima) +{ + return (sima->image && ELEM(sima->image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)); +} + +int ED_space_image_show_paint(SpaceImage *sima) +{ + if (ED_space_image_show_render(sima)) + return 0; + + return (sima->mode == SI_MODE_PAINT); +} + +int ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit) +{ + if (sima && (ED_space_image_show_render(sima) || ED_space_image_show_paint(sima))) + return 0; + + if (obedit && obedit->type == OB_MESH) { + struct BMEditMesh *em = BMEdit_FromObject(obedit); + int ret; + + ret = EDBM_mtexpoly_check(em); + + return ret; + } + + return 0; +} + +int ED_space_image_show_uvshadow(SpaceImage *sima, Object *obedit) +{ + if (ED_space_image_show_render(sima)) + return 0; + + if (ED_space_image_show_paint(sima)) + if (obedit && obedit->type == OB_MESH) { + struct BMEditMesh *em = BMEdit_FromObject(obedit); + int ret; + + ret = EDBM_mtexpoly_check(em); + + return ret; + } + + return 0; +} + +/* matches clip function */ +int ED_space_image_check_show_maskedit(Scene *scene, SpaceImage *sima) +{ + /* check editmode - this is reserved for UV editing */ + Object *ob = OBACT; + if (ob && ob->mode & OB_MODE_EDIT && ED_space_image_show_uvedit(sima, ob)) { + return FALSE; + } + + return (sima->mode == SI_MODE_MASK); +} + +int ED_space_image_maskedit_poll(bContext *C) +{ + SpaceImage *sima = CTX_wm_space_image(C); + + if (sima) { + Scene *scene = CTX_data_scene(C); + return ED_space_image_check_show_maskedit(scene, sima); + } + + return FALSE; +} + +int ED_space_image_maskedit_mask_poll(bContext *C) +{ + if (ED_space_image_maskedit_poll(C)) { + SpaceImage *sima = CTX_wm_space_image(C); + return sima->mask_info.mask != NULL; + } + + return FALSE; +} + +/******************** TODO ********************/ + +/* XXX notifier? */ + +/* goes over all ImageUsers, and sets frame numbers if auto-refresh is set */ + +static void image_update_frame(struct Image *UNUSED(ima), struct ImageUser *iuser, void *customdata) +{ + int cfra = *(int *)customdata; + + BKE_image_user_check_frame_calc(iuser, cfra, 0); +} + +void ED_image_update_frame(const Main *mainp, int cfra) +{ + BKE_image_walk_all_users(mainp, &cfra, image_update_frame); +} diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index ca16558f3a6..38a2e9725ff 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -91,7 +91,7 @@ static void sima_zoom_set(SpaceImage *sima, ARegion *ar, float zoom, float locat if (sima->zoom < 0.1f || sima->zoom > 4.0f) { /* check zoom limits */ - ED_space_image_size(sima, &width, &height); + ED_space_image_get_size(sima, &width, &height); width *= sima->zoom; height *= sima->zoom; @@ -107,8 +107,8 @@ static void sima_zoom_set(SpaceImage *sima, ARegion *ar, float zoom, float locat if ((U.uiflag & USER_ZOOM_TO_MOUSEPOS) && location) { float aspx, aspy, w, h; - ED_space_image_size(sima, &width, &height); - ED_space_image_aspect(sima, &aspx, &aspy); + ED_space_image_get_size(sima, &width, &height); + ED_space_image_get_aspect(sima, &aspx, &aspy); w = width * aspx; h = height * aspy; @@ -203,17 +203,27 @@ int space_image_main_area_not_uv_brush_poll(bContext *C) return 0; } -static int space_image_image_sample_poll(bContext *C) +static int image_sample_poll(bContext *C) { SpaceImage *sima = CTX_wm_space_image(C); - Object *obedit = CTX_data_edit_object(C); - ToolSettings *toolsettings = CTX_data_scene(C)->toolsettings; + if (sima) { + Scene *scene = CTX_data_scene(C); + Object *obedit = CTX_data_edit_object(C); + ToolSettings *toolsettings = scene->toolsettings; - if (obedit) { - if (ED_space_image_show_uvedit(sima, obedit) && (toolsettings->use_uv_sculpt)) - return 0; + if (obedit) { + if (ED_space_image_show_uvedit(sima, obedit) && (toolsettings->use_uv_sculpt)) + return FALSE; + } + else if (sima->mode != SI_MODE_VIEW) { + return FALSE; + } + + return space_image_main_area_poll(C); + } + else { + return FALSE; } - return space_image_main_area_poll(C); } /********************** view pan operator *********************/ @@ -564,8 +574,8 @@ static int image_view_all_exec(bContext *C, wmOperator *UNUSED(op)) sima = CTX_wm_space_image(C); ar = CTX_wm_region(C); - ED_space_image_size(sima, &width, &height); - ED_space_image_aspect(sima, &aspx, &aspy); + ED_space_image_get_size(sima, &width, &height); + ED_space_image_get_aspect(sima, &aspx, &aspy); w = width * aspx; h = height * aspy; @@ -578,7 +588,7 @@ static int image_view_all_exec(bContext *C, wmOperator *UNUSED(op)) /* find the zoom value that will fit the image in the image space */ zoomx = width / w; zoomy = height / h; - sima_zoom_set(sima, ar, 1.0f / power_of_2(1 / MIN2(zoomx, zoomy)), NULL); + sima_zoom_set(sima, ar, 1.0f / power_of_2(1.0f / minf(zoomx, zoomy)), NULL); } else sima_zoom_set(sima, ar, 1.0f, NULL); @@ -621,8 +631,8 @@ static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op)) obedit = CTX_data_edit_object(C); ima = ED_space_image(sima); - ED_space_image_size(sima, &width, &height); - ED_image_aspect(ima, &aspx, &aspy); + ED_space_image_get_size(sima, &width, &height); + ED_image_get_aspect(ima, &aspx, &aspy); width = width * aspx; height = height * aspy; @@ -901,6 +911,26 @@ static int image_open_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event) ima = tex->ima; } + if (ima == NULL) { + PointerRNA ptr; + PropertyRNA *prop; + + /* hook into UI */ + uiIDContextProperty(C, &ptr, &prop); + + if (prop) { + PointerRNA oldptr; + Image *oldima; + + oldptr = RNA_property_pointer_get(&ptr, prop); + oldima = (Image *)oldptr.id.data; + /* unlikely to fail but better avoid strange crash */ + if (oldima && GS(oldima->id.name) == ID_IM) { + ima = oldima; + } + } + } + if (ima) path = ima->name; @@ -931,7 +961,8 @@ void IMAGE_OT_open(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); } /******************** Match movie length operator ********************/ @@ -1043,7 +1074,8 @@ void IMAGE_OT_replace(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); } /******************** save image as operator ********************/ @@ -1387,7 +1419,8 @@ void IMAGE_OT_save_as(wmOperatorType *ot) /* properties */ RNA_def_boolean(ot->srna, "copy", 0, "Copy", "Create a new image file without modifying the current image in blender"); - WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_SAVE, + WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); } /******************** save image operator ********************/ @@ -2089,7 +2122,7 @@ void IMAGE_OT_sample(wmOperatorType *ot) ot->invoke = image_sample_invoke; ot->modal = image_sample_modal; ot->cancel = image_sample_cancel; - ot->poll = space_image_image_sample_poll; + ot->poll = image_sample_poll; /* flags */ ot->flag = OPTYPE_BLOCKING; @@ -2133,6 +2166,9 @@ static int image_sample_line_exec(bContext *C, wmOperator *op) BKE_histogram_update_sample_line(hist, ibuf, (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) != 0); + /* reset y zoom */ + hist->ymax = 1.0f; + ED_space_image_release_buffer(sima, lock); ED_area_tag_redraw(CTX_wm_area(C)); @@ -2403,22 +2439,3 @@ void IMAGE_OT_cycle_render_slot(wmOperatorType *ot) RNA_def_boolean(ot->srna, "reverse", 0, "Cycle in Reverse", ""); } - -/******************** TODO ********************/ - -/* XXX notifier? */ - -/* goes over all ImageUsers, and sets frame numbers if auto-refresh is set */ - -static void image_update_frame(struct Image *UNUSED(ima), struct ImageUser *iuser, void *customdata) -{ - int cfra = *(int*)customdata; - - BKE_image_user_check_frame_calc(iuser, cfra, 0); -} - -void ED_image_update_frame(const Main *mainp, int cfra) -{ - BKE_image_walk_all_users(mainp, &cfra, image_update_frame); -} - diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 59e47363a22..31fa1f805f9 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -28,11 +28,8 @@ * \ingroup spimage */ - -#include <string.h> -#include <stdio.h> - #include "DNA_mesh_types.h" +#include "DNA_mask_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -41,23 +38,22 @@ #include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLI_rand.h" -#include "BLI_utildefines.h" #include "BKE_colortools.h" #include "BKE_context.h" #include "BKE_image.h" -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_mesh.h" #include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_tessmesh.h" +#include "BKE_sequencer.h" +#include "BKE_node.h" #include "IMB_imbuf_types.h" #include "ED_image.h" +#include "ED_mask.h" #include "ED_mesh.h" +#include "ED_node.h" #include "ED_space_api.h" #include "ED_screen.h" #include "ED_uvedit.h" @@ -76,238 +72,6 @@ /**************************** common state *****************************/ -/* note; image_panel_properties() uses pointer to sima->image directly */ -Image *ED_space_image(SpaceImage *sima) -{ - return sima->image; -} - -/* called to assign images to UV faces */ -void ED_space_image_set(SpaceImage *sima, Scene *scene, Object *obedit, Image *ima) -{ - /* context may be NULL, so use global */ - ED_uvedit_assign_image(G.main, scene, obedit, ima, sima->image); - - /* change the space ima after because uvedit_face_visible_test uses the space ima - * to check if the face is displayed in UV-localview */ - sima->image = ima; - - if (ima == NULL || ima->type == IMA_TYPE_R_RESULT || ima->type == IMA_TYPE_COMPOSITE) - sima->flag &= ~SI_DRAWTOOL; - - if (sima->image) - BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE); - - if (sima->image && sima->image->id.us == 0) - sima->image->id.us = 1; - - if (obedit) - WM_main_add_notifier(NC_GEOM | ND_DATA, obedit->data); - - WM_main_add_notifier(NC_SPACE | ND_SPACE_IMAGE, NULL); -} - -ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **lock_r) -{ - ImBuf *ibuf; - - if (sima && sima->image) { -#if 0 - if (sima->image->type == IMA_TYPE_R_RESULT && BIF_show_render_spare()) - return BIF_render_spare_imbuf(); - else -#endif - ibuf = BKE_image_acquire_ibuf(sima->image, &sima->iuser, lock_r); - - if (ibuf && (ibuf->rect || ibuf->rect_float)) - return ibuf; - } - - return NULL; -} - -void ED_space_image_release_buffer(SpaceImage *sima, void *lock) -{ - if (sima && sima->image) - BKE_image_release_ibuf(sima->image, lock); -} - -int ED_space_image_has_buffer(SpaceImage *sima) -{ - ImBuf *ibuf; - void *lock; - int has_buffer; - - ibuf = ED_space_image_acquire_buffer(sima, &lock); - has_buffer = (ibuf != NULL); - ED_space_image_release_buffer(sima, lock); - - return has_buffer; -} - -void ED_image_size(Image *ima, int *width, int *height) -{ - ImBuf *ibuf = NULL; - void *lock; - - if (ima) - ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); - - if (ibuf && ibuf->x > 0 && ibuf->y > 0) { - *width = ibuf->x; - *height = ibuf->y; - } - else { - *width = 256; - *height = 256; - } - - if (ima) - BKE_image_release_ibuf(ima, lock); -} - -void ED_space_image_size(SpaceImage *sima, int *width, int *height) -{ - Scene *scene = sima->iuser.scene; - ImBuf *ibuf; - void *lock; - - ibuf = ED_space_image_acquire_buffer(sima, &lock); - - if (ibuf && ibuf->x > 0 && ibuf->y > 0) { - *width = ibuf->x; - *height = ibuf->y; - } - else if (sima->image && sima->image->type == IMA_TYPE_R_RESULT && scene) { - /* not very important, just nice */ - *width = (scene->r.xsch * scene->r.size) / 100; - *height = (scene->r.ysch * scene->r.size) / 100; - - if ((scene->r.mode & R_BORDER) && (scene->r.mode & R_CROP)) { - *width *= (scene->r.border.xmax - scene->r.border.xmin); - *height *= (scene->r.border.ymax - scene->r.border.ymin); - } - - } - /* I know a bit weak... but preview uses not actual image size */ - // XXX else if (image_preview_active(sima, width, height)); - else { - *width = 256; - *height = 256; - } - - ED_space_image_release_buffer(sima, lock); -} - -void ED_image_aspect(Image *ima, float *aspx, float *aspy) -{ - *aspx = *aspy = 1.0; - - if ((ima == NULL) || (ima->type == IMA_TYPE_R_RESULT) || (ima->type == IMA_TYPE_COMPOSITE) || - (ima->aspx == 0.0f || ima->aspy == 0.0f)) - { - return; - } - - /* x is always 1 */ - *aspy = ima->aspy / ima->aspx; -} - -void ED_space_image_aspect(SpaceImage *sima, float *aspx, float *aspy) -{ - ED_image_aspect(ED_space_image(sima), aspx, aspy); -} - -void ED_space_image_zoom(SpaceImage *sima, ARegion *ar, float *zoomx, float *zoomy) -{ - int width, height; - - ED_space_image_size(sima, &width, &height); - - *zoomx = (float)(ar->winrct.xmax - ar->winrct.xmin + 1) / (float)((ar->v2d.cur.xmax - ar->v2d.cur.xmin) * width); - *zoomy = (float)(ar->winrct.ymax - ar->winrct.ymin + 1) / (float)((ar->v2d.cur.ymax - ar->v2d.cur.ymin) * height); -} - -void ED_space_image_uv_aspect(SpaceImage *sima, float *aspx, float *aspy) -{ - int w, h; - - ED_space_image_aspect(sima, aspx, aspy); - ED_space_image_size(sima, &w, &h); - - *aspx *= (float)w; - *aspy *= (float)h; - - if (*aspx < *aspy) { - *aspy = *aspy / *aspx; - *aspx = 1.0f; - } - else { - *aspx = *aspx / *aspy; - *aspy = 1.0f; - } -} - -void ED_image_uv_aspect(Image *ima, float *aspx, float *aspy) -{ - int w, h; - - ED_image_aspect(ima, aspx, aspy); - ED_image_size(ima, &w, &h); - - *aspx *= (float)w; - *aspy *= (float)h; -} - -int ED_space_image_show_render(SpaceImage *sima) -{ - return (sima->image && ELEM(sima->image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)); -} - -int ED_space_image_show_paint(SpaceImage *sima) -{ - if (ED_space_image_show_render(sima)) - return 0; - - return (sima->flag & SI_DRAWTOOL); -} - -int ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit) -{ - if (sima && (ED_space_image_show_render(sima) || ED_space_image_show_paint(sima))) - return 0; - - if (obedit && obedit->type == OB_MESH) { - struct BMEditMesh *em = BMEdit_FromObject(obedit); - int ret; - - ret = EDBM_mtexpoly_check(em); - - return ret; - } - - return 0; -} - -int ED_space_image_show_uvshadow(SpaceImage *sima, Object *obedit) -{ - if (ED_space_image_show_render(sima)) - return 0; - - if (ED_space_image_show_paint(sima)) - if (obedit && obedit->type == OB_MESH) { - struct BMEditMesh *em = BMEdit_FromObject(obedit); - int ret; - - ret = EDBM_mtexpoly_check(em); - - return ret; - } - - return 0; -} - - static void image_scopes_tag_refresh(ScrArea *sa) { SpaceImage *sima = (SpaceImage *)sa->spacedata.first; @@ -384,10 +148,10 @@ static SpaceLink *image_new(const bContext *UNUSED(C)) simage = MEM_callocN(sizeof(SpaceImage), "initimage"); simage->spacetype = SPACE_IMAGE; - simage->zoom = 1; - simage->lock = 1; + simage->zoom = 1.0f; + simage->lock = TRUE; - simage->iuser.ok = 1; + simage->iuser.ok = TRUE; simage->iuser.fie_ima = 2; simage->iuser.frames = 100; @@ -579,12 +343,14 @@ static void image_dropboxes(void) WM_dropbox_add(lb, "IMAGE_OT_open", image_drop_poll, image_drop_copy); } - - -static void image_refresh(const bContext *C, ScrArea *UNUSED(sa)) +/** + * \note take care not to get into feedback loop here, + * calling composite job causes viewer to refresh. + */ +static void image_refresh(const bContext *C, ScrArea *sa) { Scene *scene = CTX_data_scene(C); - SpaceImage *sima = CTX_wm_space_image(C); + SpaceImage *sima = sa->spacedata.first; Object *obedit = CTX_data_edit_object(C); Image *ima; @@ -593,7 +359,17 @@ static void image_refresh(const bContext *C, ScrArea *UNUSED(sa)) BKE_image_user_check_frame_calc(&sima->iuser, scene->r.cfra, 0); /* check if we have to set the image from the editmesh */ - if (ima && (ima->source == IMA_SRC_VIEWER || sima->pin)) ; + if (ima && (ima->source == IMA_SRC_VIEWER && sima->mode == SI_MODE_MASK)) { + if (sima->lock) { + Mask *mask = ED_space_image_get_mask(sima); + if (mask) { + ED_node_composite_job(C, scene->nodetree, scene); + } + } + } + else if (ima && (ima->source == IMA_SRC_VIEWER || sima->pin)) { + /* pass */ + } else if (obedit && obedit->type == OB_MESH) { Mesh *me = (Mesh *)obedit->data; struct BMEditMesh *em = me->edit_btmesh; @@ -643,15 +419,14 @@ static void image_listener(ScrArea *sa, wmNotifier *wmn) case ND_FRAME: image_scopes_tag_refresh(sa); ED_area_tag_refresh(sa); - ED_area_tag_redraw(sa); + ED_area_tag_redraw(sa); break; case ND_MODE: case ND_RENDER_RESULT: case ND_COMPO_RESULT: if (ED_space_image_show_render(sima)) image_scopes_tag_refresh(sa); - ED_area_tag_refresh(sa); - ED_area_tag_redraw(sa); + ED_area_tag_redraw(sa); break; } break; @@ -668,6 +443,35 @@ static void image_listener(ScrArea *sa, wmNotifier *wmn) ED_area_tag_redraw(sa); } break; + case NC_MASK: + { + // Scene *scene = wmn->window->screen->scene; + /* ideally would check for: ED_space_image_check_show_maskedit(scene, sima) but we cant get the scene */ + if (sima->mode == SI_MODE_MASK) { + switch (wmn->data) { + case ND_SELECT: + ED_area_tag_redraw(sa); + break; + case ND_DATA: + case ND_DRAW: + /* causes node-recalc */ + ED_area_tag_redraw(sa); + ED_area_tag_refresh(sa); + break; + } + switch (wmn->action) { + case NA_SELECTED: + ED_area_tag_redraw(sa); + break; + case NA_EDITED: + /* causes node-recalc */ + ED_area_tag_redraw(sa); + ED_area_tag_refresh(sa); + break; + } + } + break; + } case NC_GEOM: switch (wmn->data) { case ND_DATA: @@ -693,7 +497,7 @@ static void image_listener(ScrArea *sa, wmNotifier *wmn) } } -const char *image_context_dir[] = {"edit_image", NULL}; +const char *image_context_dir[] = {"edit_image", "edit_mask", NULL}; static int image_context(const bContext *C, const char *member, bContextDataResult *result) { @@ -706,7 +510,13 @@ static int image_context(const bContext *C, const char *member, bContextDataResu CTX_data_id_pointer_set(result, (ID *)ED_space_image(sima)); return 1; } - + else if (CTX_data_equals(member, "edit_mask")) { + Mask *mask = ED_space_image_get_mask(sima); + if (mask) { + CTX_data_id_pointer_set(result, &mask->id); + } + return TRUE; + } return 0; } @@ -723,7 +533,7 @@ static void image_main_area_set_view2d(SpaceImage *sima, ARegion *ar) if (image_preview_active(curarea, &width, &height)) ; else #endif - ED_space_image_size(sima, &width, &height); + ED_space_image_get_size(sima, &width, &height); w = width; h = height; @@ -773,6 +583,10 @@ static void image_main_area_init(wmWindowManager *wm, ARegion *ar) // image space manages own v2d // UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy); + /* mask polls mode */ + keymap = WM_keymap_find(wm->defaultconf, "Mask Editing", 0, 0); + WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); + /* image paint polls for mode */ keymap = WM_keymap_find(wm->defaultconf, "Image Paint", 0, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); @@ -797,6 +611,7 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) SpaceImage *sima = CTX_wm_space_image(C); Object *obact = CTX_data_active_object(C); Object *obedit = CTX_data_edit_object(C); + Mask *mask = NULL; Scene *scene = CTX_data_scene(C); View2D *v2d = &ar->v2d; //View2DScrollers *scrollers; @@ -815,7 +630,7 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) /* we set view2d from own zoom and offset each time */ image_main_area_set_view2d(sima, ar); - + /* we draw image in pixelspace */ draw_image_main(sima, ar, scene); @@ -823,6 +638,15 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) UI_view2d_view_ortho(v2d); draw_uvedit_main(sima, ar, scene, obedit, obact); + /* check for mask (delay draw) */ + if (ED_space_image_show_uvedit(sima, obedit)) { + /* pass */ + } + else if (sima->mode == SI_MODE_MASK) { + mask = ED_space_image_get_mask(sima); + draw_image_cursor(sima, ar); + } + ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); /* Grease Pencil too (in addition to UV's) */ @@ -836,6 +660,20 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) /* draw Grease Pencil - screen space only */ draw_image_grease_pencil((bContext *)C, 0); + if (mask) { + int width, height; + ED_space_image_get_size(sima, &width, &height); + ED_mask_draw_region(mask, ar, + sima->mask_info.draw_flag, sima->mask_info.draw_type, + width, height, + TRUE, FALSE, + NULL, C); + + ED_mask_draw_frames(mask, ar, CFRA, mask->sfra, mask->efra); + + draw_image_cursor(sima, ar); + } + /* scrollers? */ #if 0 scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_UNIT_VALUES, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY); diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c index 329917a9f7e..35e19bcce38 100644 --- a/source/blender/editors/space_info/info_draw.c +++ b/source/blender/editors/space_info/info_draw.c @@ -249,7 +249,7 @@ static int report_textview_line_color(struct TextViewContext *tvc, unsigned char #undef USE_INFO_NEWLINE -static int info_textview_main__internal(struct SpaceInfo *sinfo, struct ARegion *ar, ReportList *reports, int draw, int mval[2], void **mouse_pick, int *pos_pick) +static int info_textview_main__internal(struct SpaceInfo *sinfo, ARegion *ar, ReportList *reports, int draw, int mval[2], void **mouse_pick, int *pos_pick) { int ret = 0; @@ -279,7 +279,7 @@ static int info_textview_main__internal(struct SpaceInfo *sinfo, struct ARegion return ret; } -void *info_text_pick(struct SpaceInfo *sinfo, struct ARegion *ar, ReportList *reports, int mouse_y) +void *info_text_pick(struct SpaceInfo *sinfo, ARegion *ar, ReportList *reports, int mouse_y) { void *mouse_pick = NULL; int mval[2]; @@ -292,13 +292,13 @@ void *info_text_pick(struct SpaceInfo *sinfo, struct ARegion *ar, ReportList *re } -int info_textview_height(struct SpaceInfo *sinfo, struct ARegion *ar, ReportList *reports) +int info_textview_height(struct SpaceInfo *sinfo, ARegion *ar, ReportList *reports) { int mval[2] = {INT_MAX, INT_MAX}; return info_textview_main__internal(sinfo, ar, reports, 0, mval, NULL, NULL); } -void info_textview_main(struct SpaceInfo *sinfo, struct ARegion *ar, ReportList *reports) +void info_textview_main(struct SpaceInfo *sinfo, ARegion *ar, ReportList *reports) { int mval[2] = {INT_MAX, INT_MAX}; info_textview_main__internal(sinfo, ar, reports, 1, mval, NULL, NULL); diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index 33a2d5c18c5..805ff1794c9 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -315,7 +315,8 @@ void FILE_OT_find_missing_files(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); } /********************* report box operator *********************/ diff --git a/source/blender/editors/space_logic/logic_ops.c b/source/blender/editors/space_logic/logic_ops.c index 1e976cebafd..f2013e405e2 100644 --- a/source/blender/editors/space_logic/logic_ops.c +++ b/source/blender/editors/space_logic/logic_ops.c @@ -64,25 +64,25 @@ /* ************* Generic Operator Helpers ************* */ static int edit_sensor_poll(bContext *C) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "sensor", &RNA_Sensor); + PointerRNA ptr = CTX_data_pointer_get_type(C, "sensor", &RNA_Sensor); - if (ptr.data && ((ID*)ptr.id.data)->lib) return 0; + if (ptr.data && ((ID *)ptr.id.data)->lib) return 0; return 1; } static int edit_controller_poll(bContext *C) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "controller", &RNA_Controller); + PointerRNA ptr = CTX_data_pointer_get_type(C, "controller", &RNA_Controller); - if (ptr.data && ((ID*)ptr.id.data)->lib) return 0; + if (ptr.data && ((ID *)ptr.id.data)->lib) return 0; return 1; } static int edit_actuator_poll(bContext *C) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "actuator", &RNA_Actuator); + PointerRNA ptr = CTX_data_pointer_get_type(C, "actuator", &RNA_Actuator); - if (ptr.data && ((ID*)ptr.id.data)->lib) return 0; + if (ptr.data && ((ID *)ptr.id.data)->lib) return 0; return 1; } @@ -94,7 +94,7 @@ static void edit_sensor_properties(wmOperatorType *ot) static int edit_sensor_invoke_properties(bContext *C, wmOperator *op) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "sensor", &RNA_Sensor); + PointerRNA ptr = CTX_data_pointer_get_type(C, "sensor", &RNA_Sensor); if (RNA_struct_property_is_set(op->ptr, "sensor") && RNA_struct_property_is_set(op->ptr, "object") ) return 1; @@ -104,7 +104,7 @@ static int edit_sensor_invoke_properties(bContext *C, wmOperator *op) Object *ob = ptr.id.data; RNA_string_set(op->ptr, "sensor", sens->name); - RNA_string_set(op->ptr, "object", ob->id.name+2); + RNA_string_set(op->ptr, "object", ob->id.name + 2); return 1; } @@ -123,7 +123,7 @@ static Object *edit_object_property_get(bContext *C, wmOperator *op) if (BLI_strnlen(ob_name, MAX_NAME) > 0) ob = BLI_findstring(&(CTX_data_main(C)->object), ob_name, offsetof(ID, name) + 2); else - ob= ED_object_active_context(C); + ob = ED_object_active_context(C); return ob; } @@ -135,7 +135,7 @@ static bSensor *edit_sensor_property_get(bContext *C, wmOperator *op, Object **o RNA_string_get(op->ptr, "sensor", sensor_name); - *ob= edit_object_property_get(C, op); + *ob = edit_object_property_get(C, op); if (!*ob) return NULL; sens = BLI_findstring(&((*ob)->sensors), sensor_name, offsetof(bSensor, name)); @@ -150,7 +150,7 @@ static void edit_controller_properties(wmOperatorType *ot) static int edit_controller_invoke_properties(bContext *C, wmOperator *op) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "controller", &RNA_Controller); + PointerRNA ptr = CTX_data_pointer_get_type(C, "controller", &RNA_Controller); if (RNA_struct_property_is_set(op->ptr, "controller") && RNA_struct_property_is_set(op->ptr, "object") ) return 1; @@ -160,7 +160,7 @@ static int edit_controller_invoke_properties(bContext *C, wmOperator *op) Object *ob = ptr.id.data; RNA_string_set(op->ptr, "controller", cont->name); - RNA_string_set(op->ptr, "object", ob->id.name+2); + RNA_string_set(op->ptr, "object", ob->id.name + 2); return 1; } @@ -174,7 +174,7 @@ static bController *edit_controller_property_get(bContext *C, wmOperator *op, Ob RNA_string_get(op->ptr, "controller", controller_name); - *ob= edit_object_property_get(C, op); + *ob = edit_object_property_get(C, op); if (!*ob) return NULL; cont = BLI_findstring(&((*ob)->controllers), controller_name, offsetof(bController, name)); @@ -189,7 +189,7 @@ static void edit_actuator_properties(wmOperatorType *ot) static int edit_actuator_invoke_properties(bContext *C, wmOperator *op) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "actuator", &RNA_Actuator); + PointerRNA ptr = CTX_data_pointer_get_type(C, "actuator", &RNA_Actuator); if (RNA_struct_property_is_set(op->ptr, "actuator") && RNA_struct_property_is_set(op->ptr, "object") ) return 1; @@ -199,7 +199,7 @@ static int edit_actuator_invoke_properties(bContext *C, wmOperator *op) Object *ob = ptr.id.data; RNA_string_set(op->ptr, "actuator", act->name); - RNA_string_set(op->ptr, "object", ob->id.name+2); + RNA_string_set(op->ptr, "object", ob->id.name + 2); return 1; } @@ -213,7 +213,7 @@ static bActuator *edit_actuator_property_get(bContext *C, wmOperator *op, Object RNA_string_get(op->ptr, "actuator", actuator_name); - *ob= edit_object_property_get(C, op); + *ob = edit_object_property_get(C, op); if (!*ob) return NULL; act = BLI_findstring(&((*ob)->actuators), actuator_name, offsetof(bActuator, name)); @@ -234,7 +234,7 @@ static int logicbricks_move_property_get(wmOperator *op) static int sensor_remove_exec(bContext *C, wmOperator *op) { - Object *ob=NULL; + Object *ob = NULL; bSensor *sens = edit_sensor_property_get(C, op, &ob); if (!sens) @@ -248,7 +248,7 @@ static int sensor_remove_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } - static int sensor_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +static int sensor_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { if (edit_sensor_invoke_properties(C, op)) return sensor_remove_exec(C, op); @@ -267,7 +267,7 @@ static void LOGIC_OT_sensor_remove(wmOperatorType *ot) ot->poll = edit_sensor_poll; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; edit_sensor_properties(ot); } @@ -279,13 +279,13 @@ static int sensor_add_exec(bContext *C, wmOperator *op) PropertyRNA *prop; const char *sens_name; char name[MAX_NAME]; - int type= RNA_enum_get(op->ptr, "type"); + int type = RNA_enum_get(op->ptr, "type"); - ob= edit_object_property_get(C, op); + ob = edit_object_property_get(C, op); if (!ob) return OPERATOR_CANCELLED; - sens= new_sensor(type); + sens = new_sensor(type); BLI_addtail(&(ob->sensors), sens); /* set the sensor name based on rna type enum */ @@ -323,10 +323,10 @@ static void LOGIC_OT_sensor_add(wmOperatorType *ot) ot->poll = ED_operator_object_active_editable; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - ot->prop = prop= RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, SENS_ALWAYS, "Type", "Type of sensor to add"); + ot->prop = prop = RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, SENS_ALWAYS, "Type", "Type of sensor to add"); RNA_def_enum_funcs(prop, rna_Sensor_type_itemf); RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Name of the Sensor to add"); RNA_def_string(ot->srna, "object", "", MAX_NAME, "Object", "Name of the Object to add the Sensor to"); @@ -351,7 +351,7 @@ static int controller_remove_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } - static int controller_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +static int controller_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { if (edit_controller_invoke_properties(C, op)) return controller_remove_exec(C, op); @@ -370,7 +370,7 @@ static void LOGIC_OT_controller_remove(wmOperatorType *ot) ot->poll = edit_controller_poll; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; edit_controller_properties(ot); } @@ -383,13 +383,13 @@ static int controller_add_exec(bContext *C, wmOperator *op) const char *cont_name; int bit; char name[MAX_NAME]; - int type= RNA_enum_get(op->ptr, "type"); + int type = RNA_enum_get(op->ptr, "type"); - ob= edit_object_property_get(C, op); + ob = edit_object_property_get(C, op); if (!ob) return OPERATOR_CANCELLED; - cont= new_controller(type); + cont = new_controller(type); BLI_addtail(&(ob->controllers), cont); /* set the controller name based on rna type enum */ @@ -408,11 +408,11 @@ static int controller_add_exec(bContext *C, wmOperator *op) /* set the controller state mask from the current object state. * A controller is always in a single state, so select the lowest bit set * from the object state */ - for (bit=0; bit<OB_MAX_STATES; bit++) { - if (ob->state & (1<<bit)) + for (bit = 0; bit < OB_MAX_STATES; bit++) { + if (ob->state & (1 << bit)) break; } - cont->state_mask = (1<<bit); + cont->state_mask = (1 << bit); if (cont->state_mask == 0) { /* shouldn't happen, object state is never 0 */ cont->state_mask = 1; @@ -438,7 +438,7 @@ static void LOGIC_OT_controller_add(wmOperatorType *ot) ot->poll = ED_operator_object_active_editable; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ ot->prop = RNA_def_enum(ot->srna, "type", controller_type_items, CONT_LOGIC_AND, "Type", "Type of controller to add"); @@ -450,7 +450,7 @@ static void LOGIC_OT_controller_add(wmOperatorType *ot) static int actuator_remove_exec(bContext *C, wmOperator *op) { - Object *ob=NULL; + Object *ob = NULL; bActuator *act = edit_actuator_property_get(C, op, &ob); if (!act) @@ -484,7 +484,7 @@ static void LOGIC_OT_actuator_remove(wmOperatorType *ot) ot->poll = edit_actuator_poll; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; edit_actuator_properties(ot); } @@ -495,14 +495,14 @@ static int actuator_add_exec(bContext *C, wmOperator *op) PointerRNA act_ptr; PropertyRNA *prop; const char *act_name; - char name[MAX_NAME]; - int type= RNA_enum_get(op->ptr, "type"); + char name[MAX_NAME]; + int type = RNA_enum_get(op->ptr, "type"); - ob= edit_object_property_get(C, op); + ob = edit_object_property_get(C, op); if (!ob) return OPERATOR_CANCELLED; - act= new_actuator(type); + act = new_actuator(type); BLI_addtail(&(ob->actuators), act); /* set the actuator name based on rna type enum */ @@ -540,27 +540,28 @@ static void LOGIC_OT_actuator_add(wmOperatorType *ot) ot->poll = ED_operator_object_active_editable; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - ot->prop = prop= RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, CONT_LOGIC_AND, "Type", "Type of actuator to add"); + ot->prop = prop = RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, CONT_LOGIC_AND, "Type", "Type of actuator to add"); RNA_def_enum_funcs(prop, rna_Actuator_type_itemf); RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Name of the Actuator to add"); RNA_def_string(ot->srna, "object", "", MAX_NAME, "Object", "Name of the Object to add the Actuator to"); } /* ************* Move Logic Bricks Operator ************* */ -static EnumPropertyItem logicbricks_move_direction[] ={ - {1, "UP", 0, "Move Up", ""}, - {2, "DOWN", 0, "Move Down", ""}, - {0, NULL, 0, NULL, NULL}}; +static EnumPropertyItem logicbricks_move_direction[] = { + {1, "UP", 0, "Move Up", ""}, + {2, "DOWN", 0, "Move Down", ""}, + {0, NULL, 0, NULL, NULL} +}; static int sensor_move_exec(bContext *C, wmOperator *op) { - Object *ob=NULL; - bSensor *sens= edit_sensor_property_get(C, op, &ob); - int move_up= logicbricks_move_property_get(op); + Object *ob = NULL; + bSensor *sens = edit_sensor_property_get(C, op, &ob); + int move_up = logicbricks_move_property_get(op); if (!sens) return OPERATOR_CANCELLED; @@ -594,7 +595,7 @@ static void LOGIC_OT_sensor_move(wmOperatorType *ot) ot->poll = edit_sensor_poll; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ edit_sensor_properties(ot); @@ -603,9 +604,9 @@ static void LOGIC_OT_sensor_move(wmOperatorType *ot) static int controller_move_exec(bContext *C, wmOperator *op) { - Object *ob=NULL; - bController *cont= edit_controller_property_get(C, op, &ob); - int move_up= logicbricks_move_property_get(op); + Object *ob = NULL; + bController *cont = edit_controller_property_get(C, op, &ob); + int move_up = logicbricks_move_property_get(op); if (!cont) return OPERATOR_CANCELLED; @@ -639,7 +640,7 @@ static void LOGIC_OT_controller_move(wmOperatorType *ot) ot->poll = edit_controller_poll; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ edit_controller_properties(ot); @@ -648,9 +649,9 @@ static void LOGIC_OT_controller_move(wmOperatorType *ot) static int actuator_move_exec(bContext *C, wmOperator *op) { - Object *ob=NULL; + Object *ob = NULL; bActuator *act = edit_actuator_property_get(C, op, &ob); - int move_up= logicbricks_move_property_get(op); + int move_up = logicbricks_move_property_get(op); if (!act) return OPERATOR_CANCELLED; @@ -684,7 +685,7 @@ static void LOGIC_OT_actuator_move(wmOperatorType *ot) ot->poll = edit_actuator_poll; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ edit_actuator_properties(ot); @@ -694,7 +695,7 @@ static void LOGIC_OT_actuator_move(wmOperatorType *ot) /* ************* TexFace Converter Operator ************* */ static int texface_convert_exec(bContext *C, wmOperator *UNUSED(op)) { - Main *bmain= CTX_data_main(C); + Main *bmain = CTX_data_main(C); do_version_tface(bmain, 0); return OPERATOR_FINISHED; @@ -705,7 +706,7 @@ static int texface_convert_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(e return texface_convert_exec(C, op); } - static void LOGIC_OT_texface_convert(wmOperatorType *ot) +static void LOGIC_OT_texface_convert(wmOperatorType *ot) { /* identifiers */ ot->name = "TexFace to Material Converter"; @@ -718,7 +719,7 @@ static int texface_convert_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(e // ot->poll = texface_convert_poll; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index 5c9994e46d3..a3e9ca1c4a2 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -266,8 +266,8 @@ static void get_nlastrip_extents(bAnimContext *ac, float *min, float *max, const /* only consider selected strips? */ if ((onlySel == 0) || (strip->flag & NLASTRIP_FLAG_SELECT)) { /* extend range if appropriate */ - *min = MIN2(*min, strip->start); - *max = MAX2(*max, strip->end); + *min = minf(*min, strip->start); + *max = maxf(*max, strip->end); } } } diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt index 2d926a50f98..996c6fb530f 100644 --- a/source/blender/editors/space_node/CMakeLists.txt +++ b/source/blender/editors/space_node/CMakeLists.txt @@ -42,14 +42,17 @@ set(INC_SYS set(SRC drawnode.c + node_add.c node_buttons.c node_draw.c node_edit.c + node_group.c node_header.c node_ops.c + node_relationships.c node_select.c - node_state.c node_templates.c + node_view.c space_node.c node_intern.h diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 134b2d6fd99..de882bd3635 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -30,26 +30,17 @@ * \brief lower level node drawing for nodes (boarders, headers etc), also node layout. */ -#include <math.h> -#include <stdio.h> -#include <string.h> - #include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLI_utildefines.h" #include "DNA_node_types.h" -#include "DNA_material_types.h" #include "DNA_object_types.h" -#include "DNA_scene_types.h" #include "DNA_space_types.h" #include "DNA_screen_types.h" #include "BKE_context.h" #include "BKE_curve.h" -#include "BKE_global.h" #include "BKE_image.h" -#include "BKE_library.h" #include "BKE_main.h" #include "BKE_node.h" #include "BKE_tracking.h" @@ -57,17 +48,12 @@ #include "BLF_api.h" #include "BLF_translation.h" -#include "NOD_composite.h" -#include "NOD_shader.h" #include "BIF_gl.h" #include "BIF_glutil.h" -#include "BLF_api.h" - #include "MEM_guardedalloc.h" - #include "RNA_access.h" #include "ED_node.h" @@ -75,13 +61,12 @@ #include "WM_api.h" #include "WM_types.h" -#include "UI_interface.h" #include "UI_resources.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -#include "node_intern.h" +#include "node_intern.h" /* own include */ /* XXX interface.h */ extern void ui_dropshadow(rctf *rct, float radius, float aspect, float alpha, int select); @@ -217,16 +202,20 @@ static void node_draw_output_default(const bContext *C, uiBlock *block, float slen; int ofs = 0; const char *ui_name = IFACE_(name); + int len = strlen(ui_name); UI_ThemeColor(TH_TEXT); slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt; - while (slen > node->width) { + while (slen > node->width && ofs < len) { ofs++; slen = (UI_GetStringWidth(ui_name + ofs) + NODE_MARGIN_X) * snode->aspect_sqrt; } - uiDefBut(block, LABEL, 0, ui_name + ofs, - (int)(sock->locx - slen), (int)(sock->locy - 9.0f), - (short)(node->width - NODE_DY), (short)NODE_DY, - NULL, 0, 0, 0, 0, ""); + + if (ofs < len) { + uiDefBut(block, LABEL, 0, ui_name + ofs, + (int)(sock->locx - slen), (int)(sock->locy - 9.0f), + (short)(node->width - NODE_DY), (short)NODE_DY, + NULL, 0, 0, 0, 0, ""); + } (void)snode; } @@ -848,7 +837,7 @@ static void node_draw_group(const bContext *C, ARegion *ar, SpaceNode *snode, bN layout = uiBlockLayout(gnode->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, (int)(rect.xmin + NODE_MARGIN_X), (int)(rect.ymax + (group_header - (2.5f * dpi_fac))), - MIN2((int)(rect.xmax - rect.xmin - 18.0f), node_group_frame + 20), group_header, UI_GetStyle()); + mini((int)(rect.xmax - rect.xmin - 18.0f), node_group_frame + 20), group_header, UI_GetStyle()); RNA_pointer_create(&ntree->id, &RNA_Node, gnode, &ptr); uiTemplateIDBrowse(layout, (bContext *)C, &ptr, "node_tree", NULL, NULL, NULL); uiBlockLayoutResolve(gnode->block, NULL, NULL); @@ -1007,9 +996,7 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode, bN float alpha; /* skip if out of view */ - if (node->totr.xmax < ar->v2d.cur.xmin || node->totr.xmin > ar->v2d.cur.xmax || - node->totr.ymax < ar->v2d.cur.ymin || node->totr.ymin > ar->v2d.cur.ymax) { - + if (BLI_rctf_isect(&node->totr, &ar->v2d.cur, NULL) == FALSE) { uiEndBlock(C, node->block); node->block = NULL; return; @@ -1032,7 +1019,7 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode, bN glDisable(GL_BLEND); /* outline active and selected emphasis */ - if (node->flag & (NODE_ACTIVE | SELECT)) { + if (node->flag & SELECT) { glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); @@ -1146,7 +1133,7 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED( glDisable(GL_BLEND); /* outline active and selected emphasis */ - if (node->flag & (NODE_ACTIVE | SELECT)) { + if (node->flag & SELECT) { glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); /* using different shades of TH_TEXT_HI for the empasis, like triangle */ @@ -2490,10 +2477,24 @@ static void node_composit_buts_viewer_but(uiLayout *layout, bContext *UNUSED(C), static void node_composit_buts_mask(uiLayout *layout, bContext *C, PointerRNA *ptr) { + bNode *node = ptr->data; + uiTemplateID(layout, C, ptr, "mask", NULL, NULL, NULL); uiItemR(layout, ptr, "use_antialiasing", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "use_feather", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "size_source", 0, "", ICON_NONE); + + if (node->custom1 & (CMP_NODEFLAG_MASK_FIXED | CMP_NODEFLAG_MASK_FIXED_SCENE)) { + uiItemR(layout, ptr, "size_x", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "size_y", 0, NULL, ICON_NONE); + } + + uiItemR(layout, ptr, "use_motion_blur", 0, NULL, ICON_NONE); + if (node->custom1 & CMP_NODEFLAG_MASK_MOTION_BLUR) { + uiItemR(layout, ptr, "motion_blur_samples", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "motion_blur_shutter", 0, NULL, ICON_NONE); + } } static void node_composit_buts_keyingscreen(uiLayout *layout, bContext *C, PointerRNA *ptr) @@ -2534,7 +2535,7 @@ static void node_composit_buts_keying(uiLayout *layout, bContext *UNUSED(C), Poi static void node_composit_buts_trackpos(uiLayout *layout, bContext *C, PointerRNA *ptr) { - bNode *node= ptr->data; + bNode *node = ptr->data; uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL); @@ -2563,7 +2564,11 @@ static void node_composit_buts_trackpos(uiLayout *layout, bContext *C, PointerRN uiItemR(layout, ptr, "track_name", 0, "", ICON_ANIM_DATA); } - uiItemR(layout, ptr, "use_relative", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "position", 0, NULL, ICON_NONE); + + if (node->custom1 == 2) { + uiItemR(layout, ptr, "relative_frame", 0, NULL, ICON_NONE); + } } } @@ -2928,7 +2933,7 @@ static void node_texture_set_butfunc(bNodeType *ntype) /* ******* init draw callbacks for all tree types, only called in usiblender.c, once ************* */ -void ED_init_node_butfuncs(void) +void ED_node_init_butfuncs(void) { bNodeTreeType *treetype; bNodeType *ntype; @@ -3018,7 +3023,7 @@ void draw_nodespace_back_pix(ARegion *ar, SpaceNode *snode, int color_manage) glaDefine2DArea(&ar->winrct); /* ortho at pixel level curarea */ - wmOrtho2(-0.375, ar->winx - 0.375, -0.375, ar->winy - 0.375); + wmOrtho2(-GLA_PIXEL_OFS, ar->winx - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, ar->winy - GLA_PIXEL_OFS); x = (ar->winx - snode->zoom * ibuf->x) / 2 + snode->xof; y = (ar->winy - snode->zoom * ibuf->y) / 2 + snode->yof; @@ -3133,7 +3138,7 @@ static void draw_nodespace_back_tex(ScrArea *sa, SpaceNode *snode) float zoomx, zoomy; zoomx = (float)sa->winx / ibuf->x; zoomy = (float)sa->winy / ibuf->y; - zoom = MIN2(zoomx, zoomy); + zoom = minf(zoomx, zoomy); } x = (sa->winx - zoom * ibuf->x) / 2 + snode->xof; @@ -3476,7 +3481,7 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link) // node_draw_link_straight(v2d, snode, link, th_col1, do_shaded, th_col2, do_triple, th_col3); } -void drawnodesnap(View2D *v2d, const float cent[2], float size, NodeBorder border) +void ED_node_draw_snap(View2D *v2d, const float cent[2], float size, NodeBorder border) { glBegin(GL_LINES); diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c new file mode 100644 index 00000000000..221a0b14698 --- /dev/null +++ b/source/blender/editors/space_node/node_add.c @@ -0,0 +1,392 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): David Millan Escriva, Juho Vepsäläinen, Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_node/node_relationships.c + * \ingroup spnode + */ + +#include <errno.h> + +#include "DNA_node_types.h" + +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_image.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_node.h" +#include "BKE_report.h" + +#include "ED_node.h" /* own include */ +#include "ED_screen.h" +#include "ED_render.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "UI_view2d.h" + +#include "node_intern.h" /* own include */ + +/* can be called from menus too, but they should do own undopush and redraws */ +bNode *node_add_node(SpaceNode *snode, Main *bmain, Scene *scene, + bNodeTemplate *ntemp, float locx, float locy) +{ + bNode *node = NULL, *gnode; + + node_deselect_all(snode); + + node = nodeAddNode(snode->edittree, ntemp); + + /* generics */ + if (node) { + node_select(node); + + gnode = node_tree_get_editgroup(snode->nodetree); + // arbitrary y offset of 60 so its visible + if (gnode) { + nodeFromView(gnode, locx, locy + 60.0f, &node->locx, &node->locy); + } + else { + node->locx = locx; + node->locy = locy + 60.0f; + } + + ntreeUpdateTree(snode->edittree); + ED_node_set_active(bmain, snode->edittree, node); + + if (snode->nodetree->type == NTREE_COMPOSIT) { + if (ELEM4(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS, CMP_NODE_OUTPUT_FILE)) { + node->id = &scene->id; + } + else if (ELEM3(node->type, CMP_NODE_MOVIECLIP, CMP_NODE_MOVIEDISTORTION, CMP_NODE_STABILIZE2D)) { + node->id = (ID *)scene->clip; + } + + ntreeCompositForceHidden(snode->edittree, scene); + } + + if (node->id) + id_us_plus(node->id); + + + if (snode->flag & SNODE_USE_HIDDEN_PREVIEW) + node->flag &= ~NODE_PREVIEW; + + snode_update(snode, node); + } + + if (snode->nodetree->type == NTREE_TEXTURE) { + ntreeTexCheckCyclics(snode->edittree); + } + + return node; +} + +/* ********************** Add reroute operator ***************** */ +static int add_reroute_intersect_check(bNodeLink *link, float mcoords[][2], int tot, float result[2]) +{ + float coord_array[NODE_LINK_RESOL + 1][2]; + int i, b; + + if (node_link_bezier_points(NULL, NULL, link, coord_array, NODE_LINK_RESOL)) { + + for (i = 0; i < tot - 1; i++) + for (b = 0; b < NODE_LINK_RESOL; b++) + if (isect_line_line_v2(mcoords[i], mcoords[i + 1], coord_array[b], coord_array[b + 1]) > 0) { + result[0] = (mcoords[i][0] + mcoords[i + 1][0]) / 2.0f; + result[1] = (mcoords[i][1] + mcoords[i + 1][1]) / 2.0f; + return 1; + } + } + return 0; +} + +static int add_reroute_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + ARegion *ar = CTX_wm_region(C); + bNode *gnode = node_tree_get_editgroup(snode->nodetree); + float mcoords[256][2]; + int i = 0; + + RNA_BEGIN(op->ptr, itemptr, "path") + { + float loc[2]; + + RNA_float_get_array(&itemptr, "loc", loc); + UI_view2d_region_to_view(&ar->v2d, (short)loc[0], (short)loc[1], + &mcoords[i][0], &mcoords[i][1]); + i++; + if (i >= 256) break; + } + RNA_END; + + if (i > 1) { + bNodeLink *link; + float insertPoint[2]; + + for (link = snode->edittree->links.first; link; link = link->next) { + if (add_reroute_intersect_check(link, mcoords, i, insertPoint)) { + bNodeTemplate ntemp; + bNode *rerouteNode; + + /* always first */ + ED_preview_kill_jobs(C); + + node_deselect_all(snode); + + ntemp.type = NODE_REROUTE; + rerouteNode = nodeAddNode(snode->edittree, &ntemp); + if (gnode) { + nodeFromView(gnode, insertPoint[0], insertPoint[1], &rerouteNode->locx, &rerouteNode->locy); + } + else { + rerouteNode->locx = insertPoint[0]; + rerouteNode->locy = insertPoint[1]; + } + + nodeAddLink(snode->edittree, link->fromnode, link->fromsock, rerouteNode, rerouteNode->inputs.first); + link->fromnode = rerouteNode; + link->fromsock = rerouteNode->outputs.first; + + /* always last */ + ntreeUpdateTree(snode->edittree); + snode_notify(C, snode); + snode_dag_update(C, snode); + + return OPERATOR_FINISHED; // add one reroute at the time. + } + } + + return OPERATOR_CANCELLED; + + } + + return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; +} + +void NODE_OT_add_reroute(wmOperatorType *ot) +{ + PropertyRNA *prop; + + ot->name = "Add reroute"; + ot->idname = "NODE_OT_add_reroute"; + + ot->invoke = WM_gesture_lines_invoke; + ot->modal = WM_gesture_lines_modal; + ot->exec = add_reroute_exec; + ot->cancel = WM_gesture_lines_cancel; + + ot->poll = ED_operator_node_active; + + /* flags */ + 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); + /* internal */ + RNA_def_int(ot->srna, "cursor", BC_CROSSCURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX); +} + + +/* ****************** Add File Node Operator ******************* */ + +static int node_add_file_exec(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + SpaceNode *snode = CTX_wm_space_node(C); + bNode *node; + Image *ima = NULL; + bNodeTemplate ntemp; + + /* check input variables */ + if (RNA_struct_property_is_set(op->ptr, "filepath")) { + char path[FILE_MAX]; + RNA_string_get(op->ptr, "filepath", path); + + errno = 0; + + ima = BKE_image_load_exists(path); + + if (!ima) { + BKE_reportf(op->reports, RPT_ERROR, "Can't read image: \"%s\", %s", path, errno ? strerror(errno) : "Unsupported format"); + return OPERATOR_CANCELLED; + } + } + else if (RNA_struct_property_is_set(op->ptr, "name")) { + char name[MAX_ID_NAME - 2]; + RNA_string_get(op->ptr, "name", name); + ima = (Image *)BKE_libblock_find_name(ID_IM, name); + + if (!ima) { + BKE_reportf(op->reports, RPT_ERROR, "Image named \"%s\", not found", name); + return OPERATOR_CANCELLED; + } + } + + node_deselect_all(snode); + + switch (snode->nodetree->type) { + case NTREE_SHADER: + ntemp.type = SH_NODE_TEX_IMAGE; + break; + case NTREE_TEXTURE: + ntemp.type = TEX_NODE_IMAGE; + break; + case NTREE_COMPOSIT: + ntemp.type = CMP_NODE_IMAGE; + break; + default: + return OPERATOR_CANCELLED; + } + + ED_preview_kill_jobs(C); + + node = node_add_node(snode, bmain, scene, &ntemp, snode->mx, snode->my); + + if (!node) { + BKE_report(op->reports, RPT_WARNING, "Could not add an image node"); + return OPERATOR_CANCELLED; + } + + node->id = (ID *)ima; + id_us_plus(node->id); + + snode_notify(C, snode); + snode_dag_update(C, snode); + + return OPERATOR_FINISHED; +} + +static int node_add_file_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + ARegion *ar = CTX_wm_region(C); + SpaceNode *snode = CTX_wm_space_node(C); + + /* convert mouse coordinates to v2d space */ + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], + &snode->mx, &snode->my); + + if (RNA_struct_property_is_set(op->ptr, "filepath") || RNA_struct_property_is_set(op->ptr, "name")) + return node_add_file_exec(C, op); + else + return WM_operator_filesel(C, op, event); +} + +void NODE_OT_add_file(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add File Node"; + ot->description = "Add a file node to the current node editor"; + ot->idname = "NODE_OT_add_file"; + + /* callbacks */ + ot->exec = node_add_file_exec; + ot->invoke = node_add_file_invoke; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); //XXX TODO, relative_path + RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Datablock name to assign"); +} + + +/********************** New node tree operator *********************/ + +static int new_node_tree_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode; + bNodeTree *ntree; + PointerRNA ptr, idptr; + PropertyRNA *prop; + int treetype; + char treename[MAX_ID_NAME - 2] = "NodeTree"; + + /* retrieve state */ + snode = CTX_wm_space_node(C); + + if (RNA_struct_property_is_set(op->ptr, "type")) + treetype = RNA_enum_get(op->ptr, "type"); + else + treetype = snode->treetype; + + if (RNA_struct_property_is_set(op->ptr, "name")) + RNA_string_get(op->ptr, "name", treename); + + ntree = ntreeAddTree(treename, treetype, 0); + if (!ntree) + return OPERATOR_CANCELLED; + + /* hook into UI */ + uiIDContextProperty(C, &ptr, &prop); + + if (prop) { + RNA_id_pointer_create(&ntree->id, &idptr); + RNA_property_pointer_set(&ptr, prop, idptr); + /* RNA_property_pointer_set increases the user count, + * fixed here as the editor is the initial user. + */ + --ntree->id.us; + RNA_property_update(C, &ptr, prop); + } + else if (snode) { + Scene *scene = CTX_data_scene(C); + snode->nodetree = ntree; + + ED_node_tree_update(snode, scene); + } + + return OPERATOR_FINISHED; +} + +void NODE_OT_new_node_tree(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "New Node Tree"; + ot->idname = "NODE_OT_new_node_tree"; + ot->description = "Create a new node tree"; + + /* api callbacks */ + ot->exec = new_node_tree_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", nodetree_type_items, NTREE_COMPOSIT, "Tree Type", ""); + RNA_def_string(ot->srna, "name", "NodeTree", MAX_ID_NAME - 2, "Name", ""); +} diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c index bc4c391720a..3297b785765 100644 --- a/source/blender/editors/space_node/node_buttons.c +++ b/source/blender/editors/space_node/node_buttons.c @@ -28,21 +28,12 @@ * \ingroup spnode */ - -#include <string.h> -#include <stdio.h> -#include <math.h> -#include <float.h> - #include "MEM_guardedalloc.h" #include "DNA_node_types.h" -#include "DNA_scene_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" -#include "BLI_rand.h" -#include "BLI_utildefines.h" #include "BLF_translation.h" @@ -59,10 +50,9 @@ #include "ED_gpencil.h" #include "ED_screen.h" -#include "UI_interface.h" #include "UI_resources.h" -#include "node_intern.h" // own include +#include "node_intern.h" /* own include */ /* ******************* node space & buttons ************** */ @@ -70,7 +60,7 @@ /* poll for active nodetree */ static int active_nodetree_poll(const bContext *C, PanelType *UNUSED(pt)) { - SpaceNode *snode= CTX_wm_space_node(C); + SpaceNode *snode = CTX_wm_space_node(C); return (snode && snode->nodetree); } @@ -78,7 +68,7 @@ static int active_nodetree_poll(const bContext *C, PanelType *UNUSED(pt)) /* poll callback for active node */ static int active_node_poll(const bContext *C, PanelType *UNUSED(pt)) { - SpaceNode *snode= CTX_wm_space_node(C); + SpaceNode *snode = CTX_wm_space_node(C); return (snode && snode->edittree && nodeGetActive(snode->edittree)); } @@ -86,8 +76,8 @@ static int active_node_poll(const bContext *C, PanelType *UNUSED(pt)) /* active node */ static void active_node_panel(const bContext *C, Panel *pa) { - SpaceNode *snode= CTX_wm_space_node(C); - bNodeTree *ntree= (snode) ? snode->edittree : NULL; + SpaceNode *snode = CTX_wm_space_node(C); + bNodeTree *ntree = (snode) ? snode->edittree : NULL; bNode *node = (ntree) ? nodeGetActive(ntree) : NULL; // xxx... for editing group nodes uiLayout *layout, *row, *col, *sub; PointerRNA ptr, opptr; @@ -98,7 +88,7 @@ static void active_node_panel(const bContext *C, Panel *pa) //if (node->id) /* for group nodes */ // RNA_pointer_create(node->id, &RNA_Node, node, &ptr); //else - RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); + RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); layout = uiLayoutColumn(pa->layout, FALSE); uiLayoutSetContextPointer(layout, "node", &ptr); @@ -144,24 +134,24 @@ static void active_node_panel(const bContext *C, Panel *pa) static int node_sockets_poll(const bContext *C, PanelType *UNUSED(pt)) { - SpaceNode *snode= CTX_wm_space_node(C); + SpaceNode *snode = CTX_wm_space_node(C); return (snode && snode->nodetree && G.rt == 777); } static void node_sockets_panel(const bContext *C, Panel *pa) { - SpaceNode *snode= CTX_wm_space_node(C); - bNodeTree *ntree= (snode) ? snode->edittree : NULL; + SpaceNode *snode = CTX_wm_space_node(C); + bNodeTree *ntree = (snode) ? snode->edittree : NULL; bNode *node = (ntree) ? nodeGetActive(ntree) : NULL; bNodeSocket *sock; - uiLayout *layout= pa->layout, *split; + uiLayout *layout = pa->layout, *split; char name[UI_MAX_NAME_STR]; if (ELEM(NULL, ntree, node)) return; - for (sock=node->inputs.first; sock; sock=sock->next) { + for (sock = node->inputs.first; sock; sock = sock->next) { BLI_snprintf(name, sizeof(name), "%s:", sock->name); split = uiLayoutSplit(layout, 0.35f, FALSE); @@ -176,33 +166,33 @@ void node_buttons_register(ARegionType *art) { PanelType *pt; - pt= MEM_callocN(sizeof(PanelType), "spacetype node panel active node"); + pt = MEM_callocN(sizeof(PanelType), "spacetype node panel active node"); strcpy(pt->idname, "NODE_PT_item"); strcpy(pt->label, IFACE_("Active Node")); - pt->draw= active_node_panel; - pt->poll= active_node_poll; + pt->draw = active_node_panel; + pt->poll = active_node_poll; BLI_addtail(&art->paneltypes, pt); - pt= MEM_callocN(sizeof(PanelType), "spacetype node panel node sockets"); + pt = MEM_callocN(sizeof(PanelType), "spacetype node panel node sockets"); strcpy(pt->idname, "NODE_PT_sockets"); strcpy(pt->label, "Sockets"); - pt->draw= node_sockets_panel; - pt->poll= node_sockets_poll; + pt->draw = node_sockets_panel; + pt->poll = node_sockets_poll; pt->flag |= PNL_DEFAULT_CLOSED; BLI_addtail(&art->paneltypes, pt); - pt= MEM_callocN(sizeof(PanelType), "spacetype node panel gpencil"); + pt = MEM_callocN(sizeof(PanelType), "spacetype node panel gpencil"); strcpy(pt->idname, "NODE_PT_gpencil"); strcpy(pt->label, "Grease Pencil"); - pt->draw= gpencil_panel_standard; - pt->poll= active_nodetree_poll; + pt->draw = gpencil_panel_standard; + pt->poll = active_nodetree_poll; BLI_addtail(&art->paneltypes, pt); } static int node_properties(bContext *C, wmOperator *UNUSED(op)) { - ScrArea *sa= CTX_wm_area(C); - ARegion *ar= node_has_buttons_region(sa); + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = node_has_buttons_region(sa); if (ar) ED_region_toggle_hidden(C, ar); @@ -213,7 +203,7 @@ static int node_properties(bContext *C, wmOperator *UNUSED(op)) /* non-standard poll operator which doesn't care if there are any nodes */ static int node_properties_poll(bContext *C) { - ScrArea *sa= CTX_wm_area(C); + ScrArea *sa = CTX_wm_area(C); return (sa && (sa->spacetype == SPACE_NODE)); } diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 8c9f057efc1..ed52a14ec98 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -29,26 +29,13 @@ * \brief higher level node drawing for the node editor. */ -#include <math.h> -#include <stdio.h> -#include <string.h> - -#include "MEM_guardedalloc.h" - #include "DNA_node_types.h" -#include "DNA_lamp_types.h" -#include "DNA_material_types.h" #include "DNA_object_types.h" -#include "DNA_scene_types.h" #include "DNA_space_types.h" #include "DNA_screen_types.h" -#include "DNA_world_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" -#include "BLI_rect.h" -#include "BLI_threads.h" -#include "BLI_utildefines.h" #include "BLF_translation.h" @@ -67,19 +54,12 @@ #include "ED_gpencil.h" #include "ED_space_api.h" -#include "UI_interface.h" -#include "UI_interface_icons.h" #include "UI_resources.h" #include "UI_view2d.h" #include "RNA_access.h" -#include "NOD_composite.h" -#include "NOD_shader.h" - -#include "intern/node_util.h" - -#include "node_intern.h" +#include "node_intern.h" /* own include */ #include "COM_compositor.h" /* width of socket columns in group display */ @@ -413,7 +393,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) node->totr.xmin = locx; node->totr.xmax = locx + node->width; node->totr.ymax = locy; - node->totr.ymin = MIN2(dy, locy - 2 * NODE_DY); + node->totr.ymin = minf(dy, locy - 2 * NODE_DY); /* Set the block bounds to clip mouse events from underlying nodes. * Add a margin for sockets on each side. @@ -701,9 +681,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN nodeShaderSynchronizeID(node, 0); /* skip if out of view */ - if (node->totr.xmax < ar->v2d.cur.xmin || node->totr.xmin > ar->v2d.cur.xmax || - node->totr.ymax < ar->v2d.cur.ymin || node->totr.ymin > ar->v2d.cur.ymax) - { + if (BLI_rctf_isect(&node->totr, &ar->v2d.cur, NULL) == FALSE) { uiEndBlock(C, node->block); node->block = NULL; return; @@ -813,7 +791,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN glDisable(GL_BLEND); /* outline active and selected emphasis */ - if (node->flag & (NODE_ACTIVE | SELECT)) { + if (node->flag & SELECT) { glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); @@ -901,7 +879,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad); /* outline active and selected emphasis */ - if (node->flag & (NODE_ACTIVE | SELECT)) { + if (node->flag & SELECT) { glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index a0df2aefab1..68806a802ac 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -29,82 +29,48 @@ * \ingroup spnode */ - -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <string.h> -#include <errno.h> - #include "MEM_guardedalloc.h" -#include "DNA_ID.h" #include "DNA_lamp_types.h" #include "DNA_material_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" -#include "DNA_particle_types.h" -#include "DNA_scene_types.h" #include "DNA_world_types.h" -#include "DNA_action_types.h" -#include "DNA_anim_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" -#include "BLI_utildefines.h" -#include "BKE_action.h" -#include "BKE_animsys.h" #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_image.h" #include "BKE_library.h" #include "BKE_main.h" -#include "BKE_node.h" #include "BKE_material.h" -#include "BKE_modifier.h" +#include "BKE_node.h" #include "BKE_paint.h" +#include "BKE_report.h" #include "BKE_scene.h" -#include "BKE_screen.h" #include "BKE_texture.h" -#include "BKE_report.h" #include "RE_pipeline.h" -#include "IMB_imbuf_types.h" -#include "ED_node.h" -#include "ED_image.h" +#include "ED_node.h" /* own include */ #include "ED_screen.h" -#include "ED_space_api.h" #include "ED_render.h" #include "RNA_access.h" #include "RNA_define.h" -#include "RNA_enum_types.h" #include "WM_api.h" #include "WM_types.h" -#include "UI_interface.h" -#include "UI_resources.h" #include "UI_view2d.h" -#include "IMB_imbuf.h" - -#include "RNA_enum_types.h" - #include "GPU_material.h" -#include "node_intern.h" -#include "NOD_socket.h" - -static EnumPropertyItem socket_in_out_items[] = { - { SOCK_IN, "SOCK_IN", 0, "Input", "" }, - { SOCK_OUT, "SOCK_OUT", 0, "Output", "" }, - { 0, NULL, 0, NULL, NULL }, -}; +#include "node_intern.h" /* own include */ /* ***************** composite job manager ********************** */ @@ -198,32 +164,37 @@ static void compo_startjob(void *cjv, short *stop, short *do_update, float *prog } -void snode_composite_job(const bContext *C, ScrArea *sa) +/** + * \param sa_owner is the owner of the job, + * we don't use it for anything else currently so could also be a void pointer, + * but for now keep it an 'Scene' for consistency. + * + * \note only call from spaces `refresh` callbacks, not direct! - use with care. + */ +void ED_node_composite_job(const bContext *C, struct bNodeTree *nodetree, Scene *scene_owner) { - SpaceNode *snode = sa->spacedata.first; wmJob *steve; CompoJob *cj; - steve = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Compositing", WM_JOB_EXCL_RENDER | WM_JOB_PROGRESS); + steve = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene_owner, "Compositing", WM_JOB_EXCL_RENDER | WM_JOB_PROGRESS); cj = MEM_callocN(sizeof(CompoJob), "compo job"); - + /* customdata for preview thread */ cj->scene = CTX_data_scene(C); - cj->ntree = snode->nodetree; - + cj->ntree = nodetree; + /* setup job */ WM_jobs_customdata(steve, cj, compo_freejob); WM_jobs_timer(steve, 0.1, NC_SCENE, NC_SCENE | ND_COMPO_RESULT); WM_jobs_callbacks(steve, compo_startjob, compo_initjob, compo_updatejob, NULL); - + WM_jobs_start(CTX_wm_manager(C), steve); - } /* ***************************************** */ /* operator poll callback */ -static int composite_node_active(bContext *C) +int composite_node_active(bContext *C) { if (ED_operator_node_active(C)) { SpaceNode *snode = CTX_wm_space_node(C); @@ -234,7 +205,7 @@ static int composite_node_active(bContext *C) } /* also checks for edited groups */ -static bNode *editnode_get_active(bNodeTree *ntree) +bNode *editnode_get_active(bNodeTree *ntree) { bNode *node; @@ -610,7 +581,7 @@ void snode_set_context(SpaceNode *snode, Scene *scene) node_tree_from_ID(snode->id, &snode->nodetree, &snode->edittree, NULL); } -static void snode_update(SpaceNode *snode, bNode *node) +void snode_update(SpaceNode *snode, bNode *node) { bNode *gnode; @@ -789,734 +760,10 @@ static void edit_node_properties_get(wmOperator *op, bNodeTree *ntree, bNode **r } #endif -/* ***************** Edit Group operator ************* */ - -void snode_make_group_editable(SpaceNode *snode, bNode *gnode) -{ - bNode *node; - - /* make sure nothing has group editing on */ - for (node = snode->nodetree->nodes.first; node; node = node->next) - nodeGroupEditClear(node); - - if (gnode == NULL) { - /* with NULL argument we do a toggle */ - if (snode->edittree == snode->nodetree) - gnode = nodeGetActive(snode->nodetree); - } - - if (gnode) { - snode->edittree = nodeGroupEditSet(gnode, 1); - - /* deselect all other nodes, so we can also do grabbing of entire subtree */ - for (node = snode->nodetree->nodes.first; node; node = node->next) - node_deselect(node); - node_select(gnode); - } - else - snode->edittree = snode->nodetree; -} - -static int node_group_edit_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceNode *snode = CTX_wm_space_node(C); - - ED_preview_kill_jobs(C); - - if (snode->nodetree == snode->edittree) { - bNode *gnode = nodeGetActive(snode->edittree); - snode_make_group_editable(snode, gnode); - } - else - snode_make_group_editable(snode, NULL); - - WM_event_add_notifier(C, NC_SCENE | ND_NODES, NULL); - - return OPERATOR_FINISHED; -} - -static int node_group_edit_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) -{ - SpaceNode *snode = CTX_wm_space_node(C); - bNode *gnode; - - /* XXX callback? */ - if (snode->nodetree == snode->edittree) { - gnode = nodeGetActive(snode->edittree); - if (gnode && gnode->id && GS(gnode->id->name) == ID_NT && gnode->id->lib) { - uiPupMenuOkee(C, op->type->idname, "Make group local?"); - return OPERATOR_CANCELLED; - } - } - - return node_group_edit_exec(C, op); -} - -void NODE_OT_group_edit(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Edit Group"; - ot->description = "Edit node group"; - ot->idname = "NODE_OT_group_edit"; - - /* api callbacks */ - ot->invoke = node_group_edit_invoke; - ot->exec = node_group_edit_exec; - ot->poll = ED_operator_node_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/* ***************** Add Group Socket operator ************* */ - -static int node_group_socket_add_exec(bContext *C, wmOperator *op) -{ - SpaceNode *snode = CTX_wm_space_node(C); - int in_out = -1; - char name[MAX_NAME] = ""; - int type = SOCK_FLOAT; - bNodeTree *ngroup = snode->edittree; - /* bNodeSocket *sock; */ /* UNUSED */ - - ED_preview_kill_jobs(C); - - if (RNA_struct_property_is_set(op->ptr, "name")) - RNA_string_get(op->ptr, "name", name); - - if (RNA_struct_property_is_set(op->ptr, "type")) - type = RNA_enum_get(op->ptr, "type"); - - if (RNA_struct_property_is_set(op->ptr, "in_out")) - in_out = RNA_enum_get(op->ptr, "in_out"); - else - return OPERATOR_CANCELLED; - - /* using placeholder subtype first */ - /* sock = */ /* UNUSED */ node_group_add_socket(ngroup, name, type, in_out); - - ntreeUpdateTree(ngroup); - - snode_notify(C, snode); - - return OPERATOR_FINISHED; -} - -void NODE_OT_group_socket_add(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Add Group Socket"; - ot->description = "Add node group socket"; - ot->idname = "NODE_OT_group_socket_add"; - - /* api callbacks */ - ot->exec = node_group_socket_add_exec; - ot->poll = ED_operator_node_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Type", "Input or Output"); - RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Group socket name"); - RNA_def_enum(ot->srna, "type", node_socket_type_items, SOCK_FLOAT, "Type", "Type of the group socket"); -} - -/* ***************** Remove Group Socket operator ************* */ - -static int node_group_socket_remove_exec(bContext *C, wmOperator *op) -{ - SpaceNode *snode = CTX_wm_space_node(C); - int index = -1; - int in_out = -1; - bNodeTree *ngroup = snode->edittree; - bNodeSocket *sock; - - ED_preview_kill_jobs(C); - - if (RNA_struct_property_is_set(op->ptr, "index")) - index = RNA_int_get(op->ptr, "index"); - else - return OPERATOR_CANCELLED; - - if (RNA_struct_property_is_set(op->ptr, "in_out")) - in_out = RNA_enum_get(op->ptr, "in_out"); - else - return OPERATOR_CANCELLED; - - sock = (bNodeSocket *)BLI_findlink(in_out == SOCK_IN ? &ngroup->inputs : &ngroup->outputs, index); - if (sock) { - node_group_remove_socket(ngroup, sock, in_out); - ntreeUpdateTree(ngroup); - - snode_notify(C, snode); - } - - return OPERATOR_FINISHED; -} - -void NODE_OT_group_socket_remove(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Remove Group Socket"; - ot->description = "Remove a node group socket"; - ot->idname = "NODE_OT_group_socket_remove"; - - /* api callbacks */ - ot->exec = node_group_socket_remove_exec; - ot->poll = ED_operator_node_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, INT_MAX); - RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Type", "Input or Output"); -} - -/* ***************** Move Group Socket Up operator ************* */ - -static int node_group_socket_move_up_exec(bContext *C, wmOperator *op) -{ - SpaceNode *snode = CTX_wm_space_node(C); - int index = -1; - int in_out = -1; - bNodeTree *ngroup = snode->edittree; - bNodeSocket *sock, *prev; - - ED_preview_kill_jobs(C); - - if (RNA_struct_property_is_set(op->ptr, "index")) - index = RNA_int_get(op->ptr, "index"); - else - return OPERATOR_CANCELLED; - - if (RNA_struct_property_is_set(op->ptr, "in_out")) - in_out = RNA_enum_get(op->ptr, "in_out"); - else - return OPERATOR_CANCELLED; - - /* swap */ - if (in_out == SOCK_IN) { - sock = (bNodeSocket *)BLI_findlink(&ngroup->inputs, index); - prev = sock->prev; - /* can't move up the first socket */ - if (!prev) - return OPERATOR_CANCELLED; - BLI_remlink(&ngroup->inputs, sock); - BLI_insertlinkbefore(&ngroup->inputs, prev, sock); - - ngroup->update |= NTREE_UPDATE_GROUP_IN; - } - else if (in_out == SOCK_OUT) { - sock = (bNodeSocket *)BLI_findlink(&ngroup->outputs, index); - prev = sock->prev; - /* can't move up the first socket */ - if (!prev) - return OPERATOR_CANCELLED; - BLI_remlink(&ngroup->outputs, sock); - BLI_insertlinkbefore(&ngroup->outputs, prev, sock); - - ngroup->update |= NTREE_UPDATE_GROUP_OUT; - } - ntreeUpdateTree(ngroup); - - snode_notify(C, snode); - - return OPERATOR_FINISHED; -} - -void NODE_OT_group_socket_move_up(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Move Group Socket Up"; - ot->description = "Move up node group socket"; - ot->idname = "NODE_OT_group_socket_move_up"; - - /* api callbacks */ - ot->exec = node_group_socket_move_up_exec; - ot->poll = ED_operator_node_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, INT_MAX); - RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Type", "Input or Output"); -} - -/* ***************** Move Group Socket Up operator ************* */ - -static int node_group_socket_move_down_exec(bContext *C, wmOperator *op) -{ - SpaceNode *snode = CTX_wm_space_node(C); - int index = -1; - int in_out = -1; - bNodeTree *ngroup = snode->edittree; - bNodeSocket *sock, *next; - - ED_preview_kill_jobs(C); - - if (RNA_struct_property_is_set(op->ptr, "index")) - index = RNA_int_get(op->ptr, "index"); - else - return OPERATOR_CANCELLED; - - if (RNA_struct_property_is_set(op->ptr, "in_out")) - in_out = RNA_enum_get(op->ptr, "in_out"); - else - return OPERATOR_CANCELLED; - - /* swap */ - if (in_out == SOCK_IN) { - sock = (bNodeSocket *)BLI_findlink(&ngroup->inputs, index); - next = sock->next; - /* can't move down the last socket */ - if (!next) - return OPERATOR_CANCELLED; - BLI_remlink(&ngroup->inputs, sock); - BLI_insertlinkafter(&ngroup->inputs, next, sock); - - ngroup->update |= NTREE_UPDATE_GROUP_IN; - } - else if (in_out == SOCK_OUT) { - sock = (bNodeSocket *)BLI_findlink(&ngroup->outputs, index); - next = sock->next; - /* can't move down the last socket */ - if (!next) - return OPERATOR_CANCELLED; - BLI_remlink(&ngroup->outputs, sock); - BLI_insertlinkafter(&ngroup->outputs, next, sock); - - ngroup->update |= NTREE_UPDATE_GROUP_OUT; - } - ntreeUpdateTree(ngroup); - - snode_notify(C, snode); - - return OPERATOR_FINISHED; -} - -void NODE_OT_group_socket_move_down(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Move Group Socket Down"; - ot->description = "Move down node group socket"; - ot->idname = "NODE_OT_group_socket_move_down"; - - /* api callbacks */ - ot->exec = node_group_socket_move_down_exec; - ot->poll = ED_operator_node_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, INT_MAX); - RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Type", "Input or Output"); -} - -/* ******************** Ungroup operator ********************** */ - -/* returns 1 if its OK */ -static int node_group_ungroup(bNodeTree *ntree, bNode *gnode) -{ - bNodeLink *link, *linkn; - bNode *node, *nextn; - bNodeTree *ngroup, *wgroup; - ListBase anim_basepaths = {NULL, NULL}; - - ngroup = (bNodeTree *)gnode->id; - if (ngroup == NULL) return 0; - - /* clear new pointers, set in copytree */ - for (node = ntree->nodes.first; node; node = node->next) - node->new_node = NULL; - - /* wgroup is a temporary copy of the NodeTree we're merging in - * - all of wgroup's nodes are transferred across to their new home - * - ngroup (i.e. the source NodeTree) is left unscathed - */ - wgroup = ntreeCopyTree(ngroup); - - /* add the nodes into the ntree */ - for (node = wgroup->nodes.first; node; node = nextn) { - nextn = node->next; - - /* keep track of this node's RNA "base" path (the part of the path identifying the node) - * if the old nodetree has animation data which potentially covers this node - */ - if (wgroup->adt) { - PointerRNA ptr; - char *path; - - RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr); - path = RNA_path_from_ID_to_struct(&ptr); - - if (path) - BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); - } - - /* migrate node */ - BLI_remlink(&wgroup->nodes, node); - BLI_addtail(&ntree->nodes, node); - - /* ensure unique node name in the nodee tree */ - nodeUniqueName(ntree, node); - - node->locx += gnode->locx; - node->locy += gnode->locy; - - node->flag |= NODE_SELECT; - } - - /* restore external links to and from the gnode */ - for (link = ntree->links.first; link; link = link->next) { - if (link->fromnode == gnode) { - if (link->fromsock->groupsock) { - bNodeSocket *gsock = link->fromsock->groupsock; - if (gsock->link) { - if (gsock->link->fromnode) { - /* NB: using the new internal copies here! the groupsock pointer still maps to the old tree */ - link->fromnode = (gsock->link->fromnode ? gsock->link->fromnode->new_node : NULL); - link->fromsock = gsock->link->fromsock->new_sock; - } - else { - /* group output directly maps to group input */ - bNodeSocket *insock = node_group_find_input(gnode, gsock->link->fromsock); - if (insock->link) { - link->fromnode = insock->link->fromnode; - link->fromsock = insock->link->fromsock; - } - } - } - else { - /* copy the default input value from the group socket default to the external socket */ - node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, gsock->type, gsock->default_value); - } - } - } - } - /* remove internal output links, these are not used anymore */ - for (link = wgroup->links.first; link; link = linkn) { - linkn = link->next; - if (!link->tonode) - nodeRemLink(wgroup, link); - } - /* restore links from internal nodes */ - for (link = wgroup->links.first; link; link = linkn) { - linkn = link->next; - /* indicates link to group input */ - if (!link->fromnode) { - /* NB: can't use find_group_node_input here, - * because gnode sockets still point to the old tree! - */ - bNodeSocket *insock; - for (insock = gnode->inputs.first; insock; insock = insock->next) - if (insock->groupsock->new_sock == link->fromsock) - break; - if (insock->link) { - link->fromnode = insock->link->fromnode; - link->fromsock = insock->link->fromsock; - } - else { - /* copy the default input value from the group node socket default to the internal socket */ - node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, insock->type, insock->default_value); - nodeRemLink(wgroup, link); - } - } - } - - /* add internal links to the ntree */ - for (link = wgroup->links.first; link; link = linkn) { - linkn = link->next; - BLI_remlink(&wgroup->links, link); - BLI_addtail(&ntree->links, link); - } - - /* and copy across the animation, - * note that the animation data's action can be NULL here */ - if (wgroup->adt) { - LinkData *ld, *ldn = NULL; - bAction *waction; - - /* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */ - waction = wgroup->adt->action = BKE_action_copy(wgroup->adt->action); - - /* now perform the moving */ - BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths); - - /* paths + their wrappers need to be freed */ - for (ld = anim_basepaths.first; ld; ld = ldn) { - ldn = ld->next; - - MEM_freeN(ld->data); - BLI_freelinkN(&anim_basepaths, ld); - } - - /* free temp action too */ - if (waction) { - BKE_libblock_free(&G.main->action, waction); - } - } - - /* delete the group instance. this also removes old input links! */ - nodeFreeNode(ntree, gnode); - - /* free the group tree (takes care of user count) */ - BKE_libblock_free(&G.main->nodetree, wgroup); - - ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS; - - return 1; -} - -static int node_group_ungroup_exec(bContext *C, wmOperator *op) -{ - SpaceNode *snode = CTX_wm_space_node(C); - bNode *gnode; - - ED_preview_kill_jobs(C); - - /* are we inside of a group? */ - gnode = node_tree_get_editgroup(snode->nodetree); - if (gnode) - snode_make_group_editable(snode, NULL); - - gnode = nodeGetActive(snode->edittree); - if (gnode == NULL) - return OPERATOR_CANCELLED; - - if (gnode->type != NODE_GROUP) { - BKE_report(op->reports, RPT_WARNING, "Not a group"); - return OPERATOR_CANCELLED; - } - else if (node_group_ungroup(snode->nodetree, gnode)) { - ntreeUpdateTree(snode->nodetree); - } - else { - BKE_report(op->reports, RPT_WARNING, "Can't ungroup"); - return OPERATOR_CANCELLED; - } - - snode_notify(C, snode); - snode_dag_update(C, snode); - - return OPERATOR_FINISHED; -} - -void NODE_OT_group_ungroup(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Ungroup"; - ot->description = "Ungroup selected nodes"; - ot->idname = "NODE_OT_group_ungroup"; - - /* api callbacks */ - ot->exec = node_group_ungroup_exec; - ot->poll = ED_operator_node_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/* ******************** Separate operator ********************** */ - -/* returns 1 if its OK */ -static int node_group_separate_selected(bNodeTree *ntree, bNode *gnode, int make_copy) -{ - bNodeLink *link, *link_next; - bNode *node, *node_next, *newnode; - bNodeTree *ngroup; - ListBase anim_basepaths = {NULL, NULL}; - - ngroup = (bNodeTree *)gnode->id; - if (ngroup == NULL) return 0; - - /* deselect all nodes in the target tree */ - for (node = ntree->nodes.first; node; node = node->next) - node_deselect(node); - - /* clear new pointers, set in nodeCopyNode */ - for (node = ngroup->nodes.first; node; node = node->next) - node->new_node = NULL; - - /* add selected nodes into the ntree */ - for (node = ngroup->nodes.first; node; node = node_next) { - node_next = node->next; - if (!(node->flag & NODE_SELECT)) - continue; - - if (make_copy) { - /* make a copy */ - newnode = nodeCopyNode(ngroup, node); - } - else { - /* use the existing node */ - newnode = node; - } - - /* keep track of this node's RNA "base" path (the part of the path identifying the node) - * if the old nodetree has animation data which potentially covers this node - */ - if (ngroup->adt) { - PointerRNA ptr; - char *path; - - RNA_pointer_create(&ngroup->id, &RNA_Node, newnode, &ptr); - path = RNA_path_from_ID_to_struct(&ptr); - - if (path) - BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); - } - - /* ensure valid parent pointers, detach if parent stays inside the group */ - if (newnode->parent && !(newnode->parent->flag & NODE_SELECT)) - nodeDetachNode(newnode); - - /* migrate node */ - BLI_remlink(&ngroup->nodes, newnode); - BLI_addtail(&ntree->nodes, newnode); - - /* ensure unique node name in the node tree */ - nodeUniqueName(ntree, newnode); - - newnode->locx += gnode->locx; - newnode->locy += gnode->locy; - } - - /* add internal links to the ntree */ - for (link = ngroup->links.first; link; link = link_next) { - int fromselect = (link->fromnode && (link->fromnode->flag & NODE_SELECT)); - int toselect = (link->tonode && (link->tonode->flag & NODE_SELECT)); - link_next = link->next; - - if (make_copy) { - /* make a copy of internal links */ - if (fromselect && toselect) - nodeAddLink(ntree, link->fromnode->new_node, link->fromsock->new_sock, link->tonode->new_node, link->tosock->new_sock); - } - else { - /* move valid links over, delete broken links */ - if (fromselect && toselect) { - BLI_remlink(&ngroup->links, link); - BLI_addtail(&ntree->links, link); - } - else if (fromselect || toselect) { - nodeRemLink(ngroup, link); - } - } - } - - /* and copy across the animation, - * note that the animation data's action can be NULL here */ - if (ngroup->adt) { - LinkData *ld, *ldn = NULL; - - /* now perform the moving */ - BKE_animdata_separate_by_basepath(&ngroup->id, &ntree->id, &anim_basepaths); - - /* paths + their wrappers need to be freed */ - for (ld = anim_basepaths.first; ld; ld = ldn) { - ldn = ld->next; - - MEM_freeN(ld->data); - BLI_freelinkN(&anim_basepaths, ld); - } - } - - ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS; - if (!make_copy) - ngroup->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS; - - return 1; -} - -typedef enum eNodeGroupSeparateType { - NODE_GS_COPY, - NODE_GS_MOVE -} eNodeGroupSeparateType; - -/* Operator Property */ -EnumPropertyItem node_group_separate_types[] = { - {NODE_GS_COPY, "COPY", 0, "Copy", "Copy to parent node tree, keep group intact"}, - {NODE_GS_MOVE, "MOVE", 0, "Move", "Move to parent node tree, remove from group"}, - {0, NULL, 0, NULL, NULL} -}; - -static int node_group_separate_exec(bContext *C, wmOperator *op) -{ - SpaceNode *snode = CTX_wm_space_node(C); - bNode *gnode; - int type = RNA_enum_get(op->ptr, "type"); - - ED_preview_kill_jobs(C); - - /* are we inside of a group? */ - gnode = node_tree_get_editgroup(snode->nodetree); - if (!gnode) { - BKE_report(op->reports, RPT_WARNING, "Not inside node group"); - return OPERATOR_CANCELLED; - } - - switch (type) { - case NODE_GS_COPY: - if (!node_group_separate_selected(snode->nodetree, gnode, 1)) { - BKE_report(op->reports, RPT_WARNING, "Can't separate nodes"); - return OPERATOR_CANCELLED; - } - break; - case NODE_GS_MOVE: - if (!node_group_separate_selected(snode->nodetree, gnode, 0)) { - BKE_report(op->reports, RPT_WARNING, "Can't separate nodes"); - return OPERATOR_CANCELLED; - } - break; - } - - /* switch to parent tree */ - snode_make_group_editable(snode, NULL); - - ntreeUpdateTree(snode->nodetree); - - snode_notify(C, snode); - snode_dag_update(C, snode); - - return OPERATOR_FINISHED; -} - -static int node_group_separate_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event)) -{ - uiPopupMenu *pup = uiPupMenuBegin(C, "Separate", ICON_NONE); - uiLayout *layout = uiPupMenuLayout(pup); - - uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); - uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_COPY); - uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_MOVE); - - uiPupMenuEnd(C, pup); - - return OPERATOR_CANCELLED; -} - -void NODE_OT_group_separate(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Separate"; - ot->description = "Separate selected nodes from the node group"; - ot->idname = "NODE_OT_group_separate"; - - /* api callbacks */ - ot->invoke = node_group_separate_invoke; - ot->exec = node_group_separate_exec; - ot->poll = ED_operator_node_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "type", node_group_separate_types, NODE_GS_COPY, "Type", ""); -} - /* ************************** Node generic ************** */ /* is rct in visible part of node? */ -static bNode *visible_node(SpaceNode *snode, rctf *rct) +static bNode *visible_node(SpaceNode *snode, const rctf *rct) { bNode *node; @@ -1527,319 +774,6 @@ static bNode *visible_node(SpaceNode *snode, rctf *rct) return node; } -/* **************************** */ - -typedef struct NodeViewMove { - int mvalo[2]; - int xmin, ymin, xmax, ymax; -} NodeViewMove; - -static int snode_bg_viewmove_modal(bContext *C, wmOperator *op, wmEvent *event) -{ - SpaceNode *snode = CTX_wm_space_node(C); - ARegion *ar = CTX_wm_region(C); - NodeViewMove *nvm = op->customdata; - - switch (event->type) { - case MOUSEMOVE: - - snode->xof -= (nvm->mvalo[0] - event->mval[0]); - snode->yof -= (nvm->mvalo[1] - event->mval[1]); - nvm->mvalo[0] = event->mval[0]; - nvm->mvalo[1] = event->mval[1]; - - /* prevent dragging image outside of the window and losing it! */ - CLAMP(snode->xof, nvm->xmin, nvm->xmax); - CLAMP(snode->yof, nvm->ymin, nvm->ymax); - - ED_region_tag_redraw(ar); - - break; - - case LEFTMOUSE: - case MIDDLEMOUSE: - case RIGHTMOUSE: - - MEM_freeN(nvm); - op->customdata = NULL; - - WM_event_add_notifier(C, NC_SPACE | ND_SPACE_NODE, NULL); - - return OPERATOR_FINISHED; - } - - return OPERATOR_RUNNING_MODAL; -} - -static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - SpaceNode *snode = CTX_wm_space_node(C); - ARegion *ar = CTX_wm_region(C); - NodeViewMove *nvm; - Image *ima; - ImBuf *ibuf; - const float pad = 32.0f; /* better be bigger then scrollbars */ - - void *lock; - - ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); - ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); - - if (ibuf == NULL) { - BKE_image_release_ibuf(ima, lock); - return OPERATOR_CANCELLED; - } - - nvm = MEM_callocN(sizeof(NodeViewMove), "NodeViewMove struct"); - op->customdata = nvm; - nvm->mvalo[0] = event->mval[0]; - nvm->mvalo[1] = event->mval[1]; - - nvm->xmin = -(ar->winx / 2) - (ibuf->x * (0.5f * snode->zoom)) + pad; - nvm->xmax = (ar->winx / 2) + (ibuf->x * (0.5f * snode->zoom)) - pad; - nvm->ymin = -(ar->winy / 2) - (ibuf->y * (0.5f * snode->zoom)) + pad; - nvm->ymax = (ar->winy / 2) + (ibuf->y * (0.5f * snode->zoom)) - pad; - - BKE_image_release_ibuf(ima, lock); - - /* add modal handler */ - WM_event_add_modal_handler(C, op); - - return OPERATOR_RUNNING_MODAL; -} - -static int 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) -{ - /* identifiers */ - ot->name = "Background Image Move"; - ot->description = "Move Node backdrop"; - ot->idname = "NODE_OT_backimage_move"; - - /* api callbacks */ - ot->invoke = snode_bg_viewmove_invoke; - ot->modal = snode_bg_viewmove_modal; - ot->poll = composite_node_active; - ot->cancel = snode_bg_viewmove_cancel; - - /* flags */ - ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER; -} - -static int backimage_zoom(bContext *C, wmOperator *op) -{ - SpaceNode *snode = CTX_wm_space_node(C); - ARegion *ar = CTX_wm_region(C); - float fac = RNA_float_get(op->ptr, "factor"); - - snode->zoom *= fac; - ED_region_tag_redraw(ar); - - return OPERATOR_FINISHED; -} - - -void NODE_OT_backimage_zoom(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name = "Background Image Zoom"; - ot->idname = "NODE_OT_backimage_zoom"; - ot->description = "Zoom in/out the background image"; - - /* api callbacks */ - ot->exec = backimage_zoom; - ot->poll = composite_node_active; - - /* flags */ - ot->flag = OPTYPE_BLOCKING; - - /* internal */ - RNA_def_float(ot->srna, "factor", 1.2f, 0.0f, 10.0f, "Factor", "", 0.0f, 10.0f); -} - -/******************** sample backdrop operator ********************/ - -typedef struct ImageSampleInfo { - ARegionType *art; - void *draw_handle; - int x, y; - int channels; - int color_manage; - - unsigned char col[4]; - float colf[4]; - - int draw; -} ImageSampleInfo; - -static void sample_draw(const bContext *C, ARegion *ar, void *arg_info) -{ - Scene *scene = CTX_data_scene(C); - ImageSampleInfo *info = arg_info; - - if (info->draw) { - ED_image_draw_info(ar, (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT), info->channels, - info->x, info->y, info->col, info->colf, - NULL, NULL /* zbuf - unused for nodes */ - ); - } -} - -static void sample_apply(bContext *C, wmOperator *op, wmEvent *event) -{ - SpaceNode *snode = CTX_wm_space_node(C); - ARegion *ar = CTX_wm_region(C); - ImageSampleInfo *info = op->customdata; - void *lock; - Image *ima; - ImBuf *ibuf; - float fx, fy, bufx, bufy; - - ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); - ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); - if (!ibuf) { - info->draw = 0; - return; - } - - if (!ibuf->rect) { - if (info->color_manage) - ibuf->profile = IB_PROFILE_LINEAR_RGB; - else - ibuf->profile = IB_PROFILE_NONE; - IMB_rect_from_float(ibuf); - } - - /* map the mouse coords to the backdrop image space */ - bufx = ibuf->x * snode->zoom; - bufy = ibuf->y * snode->zoom; - fx = (bufx > 0.0f ? ((float)event->mval[0] - 0.5f * ar->winx - snode->xof) / bufx + 0.5f : 0.0f); - fy = (bufy > 0.0f ? ((float)event->mval[1] - 0.5f * ar->winy - snode->yof) / bufy + 0.5f : 0.0f); - - if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) { - float *fp; - char *cp; - int x = (int)(fx * ibuf->x), y = (int)(fy * ibuf->y); - - CLAMP(x, 0, ibuf->x - 1); - CLAMP(y, 0, ibuf->y - 1); - - info->x = x; - info->y = y; - info->draw = 1; - info->channels = ibuf->channels; - - if (ibuf->rect) { - cp = (char *)(ibuf->rect + y * ibuf->x + x); - - info->col[0] = cp[0]; - info->col[1] = cp[1]; - info->col[2] = cp[2]; - info->col[3] = cp[3]; - - info->colf[0] = (float)cp[0] / 255.0f; - info->colf[1] = (float)cp[1] / 255.0f; - info->colf[2] = (float)cp[2] / 255.0f; - info->colf[3] = (float)cp[3] / 255.0f; - } - if (ibuf->rect_float) { - fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x)); - - info->colf[0] = fp[0]; - info->colf[1] = fp[1]; - info->colf[2] = fp[2]; - info->colf[3] = fp[3]; - } - - ED_node_sample_set(info->colf); - } - else { - info->draw = 0; - ED_node_sample_set(NULL); - } - - BKE_image_release_ibuf(ima, lock); - - ED_area_tag_redraw(CTX_wm_area(C)); -} - -static void sample_exit(bContext *C, wmOperator *op) -{ - ImageSampleInfo *info = op->customdata; - - ED_node_sample_set(NULL); - ED_region_draw_cb_exit(info->art, info->draw_handle); - ED_area_tag_redraw(CTX_wm_area(C)); - MEM_freeN(info); -} - -static int sample_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - SpaceNode *snode = CTX_wm_space_node(C); - ARegion *ar = CTX_wm_region(C); - ImageSampleInfo *info; - - if (snode->treetype != NTREE_COMPOSIT || !(snode->flag & SNODE_BACKDRAW)) - return OPERATOR_CANCELLED; - - info = MEM_callocN(sizeof(ImageSampleInfo), "ImageSampleInfo"); - info->art = ar->type; - info->draw_handle = ED_region_draw_cb_activate(ar->type, sample_draw, info, REGION_DRAW_POST_PIXEL); - op->customdata = info; - - sample_apply(C, op, event); - - WM_event_add_modal_handler(C, op); - - return OPERATOR_RUNNING_MODAL; -} - -static int sample_modal(bContext *C, wmOperator *op, wmEvent *event) -{ - switch (event->type) { - case LEFTMOUSE: - case RIGHTMOUSE: // XXX hardcoded - sample_exit(C, op); - return OPERATOR_CANCELLED; - case MOUSEMOVE: - sample_apply(C, op, event); - break; - } - - return OPERATOR_RUNNING_MODAL; -} - -static int sample_cancel(bContext *C, wmOperator *op) -{ - sample_exit(C, op); - return OPERATOR_CANCELLED; -} - -void NODE_OT_backimage_sample(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Backimage Sample"; - ot->idname = "NODE_OT_backimage_sample"; - ot->description = "Use mouse to sample background image"; - - /* api callbacks */ - ot->invoke = sample_invoke; - ot->modal = sample_modal; - ot->cancel = sample_cancel; - ot->poll = ED_operator_node_active; - - /* flags */ - ot->flag = OPTYPE_BLOCKING; -} - /* ********************** size widget operator ******************** */ typedef struct NodeSizeWidget { @@ -2070,140 +1004,6 @@ void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set) } } -static int node_link_viewer(const bContext *C, bNode *tonode) -{ - SpaceNode *snode = CTX_wm_space_node(C); - bNode *node; - bNodeLink *link; - bNodeSocket *sock; - - /* context check */ - if (tonode == NULL || tonode->outputs.first == NULL) - return OPERATOR_CANCELLED; - if (ELEM(tonode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) - return OPERATOR_CANCELLED; - - /* get viewer */ - for (node = snode->edittree->nodes.first; node; node = node->next) - if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) - if (node->flag & NODE_DO_OUTPUT) - break; - /* no viewer, we make one active */ - if (node == NULL) { - for (node = snode->edittree->nodes.first; node; node = node->next) { - if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { - node->flag |= NODE_DO_OUTPUT; - break; - } - } - } - - sock = NULL; - - /* try to find an already connected socket to cycle to the next */ - if (node) { - link = NULL; - for (link = snode->edittree->links.first; link; link = link->next) - if (link->tonode == node && link->fromnode == tonode) - if (link->tosock == node->inputs.first) - break; - if (link) { - /* unlink existing connection */ - sock = link->fromsock; - nodeRemLink(snode->edittree, link); - - /* find a socket after the previously connected socket */ - for (sock = sock->next; sock; sock = sock->next) - if (!nodeSocketIsHidden(sock)) - break; - } - } - - /* find a socket starting from the first socket */ - if (!sock) { - for (sock = tonode->outputs.first; sock; sock = sock->next) - if (!nodeSocketIsHidden(sock)) - break; - } - - if (sock) { - /* add a new viewer if none exists yet */ - if (!node) { - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - bNodeTemplate ntemp; - - ntemp.type = CMP_NODE_VIEWER; - /* XXX location is a quick hack, just place it next to the linked socket */ - node = node_add_node(snode, bmain, scene, &ntemp, sock->locx + 100, sock->locy); - if (!node) - return OPERATOR_CANCELLED; - - link = NULL; - } - else { - /* get link to viewer */ - for (link = snode->edittree->links.first; link; link = link->next) - if (link->tonode == node && link->tosock == node->inputs.first) - break; - } - - if (link == NULL) { - nodeAddLink(snode->edittree, tonode, sock, node, node->inputs.first); - } - else { - link->fromnode = tonode; - link->fromsock = sock; - /* make sure the dependency sorting is updated */ - snode->edittree->update |= NTREE_UPDATE_LINKS; - } - ntreeUpdateTree(snode->edittree); - snode_update(snode, node); - } - - return OPERATOR_FINISHED; -} - - -static int node_active_link_viewer(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceNode *snode = CTX_wm_space_node(C); - bNode *node; - - node = editnode_get_active(snode->edittree); - - if (!node) - return OPERATOR_CANCELLED; - - ED_preview_kill_jobs(C); - - if (node_link_viewer(C, node) == OPERATOR_CANCELLED) - return OPERATOR_CANCELLED; - - snode_notify(C, snode); - - return OPERATOR_FINISHED; -} - - - -void NODE_OT_link_viewer(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Link to Viewer Node"; - ot->description = "Link to viewer node"; - ot->idname = "NODE_OT_link_viewer"; - - /* api callbacks */ - ot->exec = node_active_link_viewer; - ot->poll = composite_node_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - - - /* return 0, nothing done */ static int UNUSED_FUNCTION(node_mouse_groupheader) (SpaceNode * snode) { @@ -2320,274 +1120,6 @@ int node_find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **so return 0; } -static int outside_group_rect(SpaceNode *snode) -{ - bNode *gnode = node_tree_get_editgroup(snode->nodetree); - if (gnode) { - return (snode->mx < gnode->totr.xmin || - snode->mx >= gnode->totr.xmax || - snode->my < gnode->totr.ymin || - snode->my >= gnode->totr.ymax); - } - return 0; -} - -/* ****************** Add *********************** */ - - -typedef struct bNodeListItem { - struct bNodeListItem *next, *prev; - struct bNode *node; -} bNodeListItem; - -static int sort_nodes_locx(void *a, void *b) -{ - bNodeListItem *nli1 = (bNodeListItem *)a; - bNodeListItem *nli2 = (bNodeListItem *)b; - bNode *node1 = nli1->node; - bNode *node2 = nli2->node; - - if (node1->locx > node2->locx) - return 1; - else - return 0; -} - -static int socket_is_available(bNodeTree *UNUSED(ntree), bNodeSocket *sock, int allow_used) -{ - if (nodeSocketIsHidden(sock)) - return 0; - - if (!allow_used && (sock->flag & SOCK_IN_USE)) - return 0; - - return 1; -} - -static bNodeSocket *best_socket_output(bNodeTree *ntree, bNode *node, bNodeSocket *sock_target, int allow_multiple) -{ - bNodeSocket *sock; - - /* first look for selected output */ - for (sock = node->outputs.first; sock; sock = sock->next) { - if (!socket_is_available(ntree, sock, allow_multiple)) - continue; - - if (sock->flag & SELECT) - return sock; - } - - /* try to find a socket with a matching name */ - for (sock = node->outputs.first; sock; sock = sock->next) { - if (!socket_is_available(ntree, sock, allow_multiple)) - continue; - - /* check for same types */ - if (sock->type == sock_target->type) { - if (strcmp(sock->name, sock_target->name) == 0) - return sock; - } - } - - /* otherwise settle for the first available socket of the right type */ - for (sock = node->outputs.first; sock; sock = sock->next) { - - if (!socket_is_available(ntree, sock, allow_multiple)) - continue; - - /* check for same types */ - if (sock->type == sock_target->type) { - return sock; - } - } - - return NULL; -} - -/* this is a bit complicated, but designed to prioritize finding - * sockets of higher types, such as image, first */ -static bNodeSocket *best_socket_input(bNodeTree *ntree, bNode *node, int num, int replace) -{ - bNodeSocket *sock; - int socktype, maxtype = 0; - int a = 0; - - for (sock = node->inputs.first; sock; sock = sock->next) { - maxtype = MAX2(sock->type, maxtype); - } - - /* find sockets of higher 'types' first (i.e. image) */ - for (socktype = maxtype; socktype >= 0; socktype--) { - for (sock = node->inputs.first; sock; sock = sock->next) { - - if (!socket_is_available(ntree, sock, replace)) { - a++; - continue; - } - - if (sock->type == socktype) { - /* increment to make sure we don't keep finding - * the same socket on every attempt running this function */ - a++; - if (a > num) - return sock; - } - } - } - - return NULL; -} - -static int snode_autoconnect_input(SpaceNode *snode, bNode *node_fr, bNodeSocket *sock_fr, bNode *node_to, bNodeSocket *sock_to, int replace) -{ - bNodeTree *ntree = snode->edittree; - bNodeLink *link; - - /* then we can connect */ - if (replace) - nodeRemSocketLinks(ntree, sock_to); - - link = nodeAddLink(ntree, node_fr, sock_fr, node_to, sock_to); - /* validate the new link */ - ntreeUpdateTree(ntree); - if (!(link->flag & NODE_LINK_VALID)) { - nodeRemLink(ntree, link); - return 0; - } - - snode_update(snode, node_to); - return 1; -} - -void snode_autoconnect(SpaceNode *snode, int allow_multiple, int replace) -{ - bNodeTree *ntree = snode->edittree; - ListBase *nodelist = MEM_callocN(sizeof(ListBase), "items_list"); - bNodeListItem *nli; - bNode *node; - int i, numlinks = 0; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->flag & NODE_SELECT) { - nli = MEM_mallocN(sizeof(bNodeListItem), "temporary node list item"); - nli->node = node; - BLI_addtail(nodelist, nli); - } - } - - /* sort nodes left to right */ - BLI_sortlist(nodelist, sort_nodes_locx); - - for (nli = nodelist->first; nli; nli = nli->next) { - bNode *node_fr, *node_to; - bNodeSocket *sock_fr, *sock_to; - int has_selected_inputs = 0; - - if (nli->next == NULL) break; - - node_fr = nli->node; - node_to = nli->next->node; - - /* if there are selected sockets, connect those */ - for (sock_to = node_to->inputs.first; sock_to; sock_to = sock_to->next) { - if (sock_to->flag & SELECT) { - has_selected_inputs = 1; - - if (!socket_is_available(ntree, sock_to, replace)) - continue; - - /* check for an appropriate output socket to connect from */ - sock_fr = best_socket_output(ntree, node_fr, sock_to, allow_multiple); - if (!sock_fr) - continue; - - if (snode_autoconnect_input(snode, node_fr, sock_fr, node_to, sock_to, replace)) - ++numlinks; - } - } - - if (!has_selected_inputs) { - /* no selected inputs, connect by finding suitable match */ - int num_inputs = BLI_countlist(&node_to->inputs); - - for (i = 0; i < num_inputs; i++) { - - /* find the best guess input socket */ - sock_to = best_socket_input(ntree, node_to, i, replace); - if (!sock_to) - continue; - - /* check for an appropriate output socket to connect from */ - sock_fr = best_socket_output(ntree, node_fr, sock_to, allow_multiple); - if (!sock_fr) - continue; - - if (snode_autoconnect_input(snode, node_fr, sock_fr, node_to, sock_to, replace)) { - ++numlinks; - break; - } - } - } - } - - if (numlinks > 0) { - ntreeUpdateTree(ntree); - } - - BLI_freelistN(nodelist); - MEM_freeN(nodelist); -} - -/* can be called from menus too, but they should do own undopush and redraws */ -bNode *node_add_node(SpaceNode *snode, Main *bmain, Scene *scene, bNodeTemplate *ntemp, float locx, float locy) -{ - bNode *node = NULL, *gnode; - - node_deselect_all(snode); - - node = nodeAddNode(snode->edittree, ntemp); - - /* generics */ - if (node) { - node_select(node); - - gnode = node_tree_get_editgroup(snode->nodetree); - // arbitrary y offset of 60 so its visible - if (gnode) { - nodeFromView(gnode, locx, locy + 60.0f, &node->locx, &node->locy); - } - else { - node->locx = locx; - node->locy = locy + 60.0f; - } - - ntreeUpdateTree(snode->edittree); - ED_node_set_active(bmain, snode->edittree, node); - - if (snode->nodetree->type == NTREE_COMPOSIT) { - if (ELEM4(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS, CMP_NODE_OUTPUT_FILE)) { - node->id = &scene->id; - } - else if (ELEM3(node->type, CMP_NODE_MOVIECLIP, CMP_NODE_MOVIEDISTORTION, CMP_NODE_STABILIZE2D)) { - node->id = (ID *)scene->clip; - } - - ntreeCompositForceHidden(snode->edittree, scene); - } - - if (node->id) - id_us_plus(node->id); - - snode_update(snode, node); - } - - if (snode->nodetree->type == NTREE_TEXTURE) { - ntreeTexCheckCyclics(snode->edittree); - } - - return node; -} - /* ****************** Duplicate *********************** */ static void node_duplicate_reparent_recursive(bNode *node) @@ -2727,770 +1259,19 @@ void NODE_OT_duplicate(wmOperatorType *ot) RNA_def_boolean(ot->srna, "keep_inputs", 0, "Keep Inputs", "Keep the input links to duplicated nodes"); } -/* *************************** add link op ******************** */ - -static void node_remove_extra_links(SpaceNode *snode, bNodeSocket *tsock, 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; - } - 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); - } - } - else - nodeRemLink(snode->edittree, tlink); - - snode->edittree->update |= NTREE_UPDATE_LINKS; - } - } -} - -/* loop that adds a nodelink, called by function below */ -/* in_out = starting socket */ -static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event) +int ED_node_select_check(ListBase *lb) { - SpaceNode *snode = CTX_wm_space_node(C); - ARegion *ar = CTX_wm_region(C); - bNodeLinkDrag *nldrag = op->customdata; - bNodeTree *ntree = snode->edittree; - bNode *tnode; - bNodeSocket *tsock = NULL; - bNodeLink *link; - LinkData *linkdata; - int in_out; - - in_out = nldrag->in_out; - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], - &snode->mx, &snode->my); - - switch (event->type) { - case MOUSEMOVE: - - if (in_out == SOCK_OUT) { - if (node_find_indicated_socket(snode, &tnode, &tsock, SOCK_IN)) { - for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) { - link = linkdata->data; - - /* skip if this is already the target socket */ - if (link->tosock == tsock) - continue; - /* skip if socket is on the same node as the fromsock */ - if (tnode && link->fromnode == tnode) - continue; - - /* attach links to the socket */ - link->tonode = tnode; - link->tosock = tsock; - /* add it to the node tree temporarily */ - if (BLI_findindex(&ntree->links, link) < 0) - BLI_addtail(&ntree->links, link); - - ntree->update |= NTREE_UPDATE_LINKS; - } - ntreeUpdateTree(ntree); - } - else { - int do_update = FALSE; - for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) { - link = linkdata->data; - - if (link->tonode || link->tosock) { - BLI_remlink(&ntree->links, link); - link->prev = link->next = NULL; - link->tonode = NULL; - link->tosock = NULL; - - ntree->update |= NTREE_UPDATE_LINKS; - do_update = TRUE; - } - } - if (do_update) { - ntreeUpdateTree(ntree); - } - } - } - else { - if (node_find_indicated_socket(snode, &tnode, &tsock, SOCK_OUT)) { - for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) { - link = linkdata->data; - - /* skip if this is already the target socket */ - if (link->fromsock == tsock) - continue; - /* skip if socket is on the same node as the fromsock */ - if (tnode && link->tonode == tnode) - continue; - - /* attach links to the socket */ - link->fromnode = tnode; - link->fromsock = tsock; - /* add it to the node tree temporarily */ - if (BLI_findindex(&ntree->links, link) < 0) - BLI_addtail(&ntree->links, link); - - ntree->update |= NTREE_UPDATE_LINKS; - } - ntreeUpdateTree(ntree); - } - else { - int do_update = FALSE; - for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) { - link = linkdata->data; - - if (link->fromnode || link->fromsock) { - BLI_remlink(&ntree->links, link); - link->prev = link->next = NULL; - link->fromnode = NULL; - link->fromsock = NULL; - - ntree->update |= NTREE_UPDATE_LINKS; - do_update = TRUE; - } - } - if (do_update) { - ntreeUpdateTree(ntree); - } - } - } - - ED_region_tag_redraw(ar); - break; - - case LEFTMOUSE: - case RIGHTMOUSE: - case MIDDLEMOUSE: { - for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) { - link = linkdata->data; - - if (link->tosock && link->fromsock) { - /* send changed events for original tonode and new */ - if (link->tonode) - snode_update(snode, link->tonode); - - /* we might need to remove a link */ - if (in_out == SOCK_OUT) - node_remove_extra_links(snode, link->tosock, link); - - /* when linking to group outputs, update the socket type */ - /* XXX this should all be part of a generic update system */ - if (!link->tonode) { - if (link->tosock->type != link->fromsock->type) - nodeSocketSetType(link->tosock, link->fromsock->type); - } - } - else if (outside_group_rect(snode) && (link->tonode || link->fromnode)) { - /* automatically add new group socket */ - if (link->tonode && link->tosock) { - link->fromsock = node_group_expose_socket(ntree, link->tosock, SOCK_IN); - link->fromnode = NULL; - if (BLI_findindex(&ntree->links, link) < 0) - BLI_addtail(&ntree->links, link); - - ntree->update |= NTREE_UPDATE_GROUP_IN | NTREE_UPDATE_LINKS; - } - else if (link->fromnode && link->fromsock) { - link->tosock = node_group_expose_socket(ntree, link->fromsock, SOCK_OUT); - link->tonode = NULL; - if (BLI_findindex(&ntree->links, link) < 0) - BLI_addtail(&ntree->links, link); - - ntree->update |= NTREE_UPDATE_GROUP_OUT | NTREE_UPDATE_LINKS; - } - } - else - nodeRemLink(ntree, link); - } - - ntreeUpdateTree(ntree); - snode_notify(C, snode); - snode_dag_update(C, snode); - - BLI_remlink(&snode->linkdrag, nldrag); - /* links->data pointers are either held by the tree or freed already */ - BLI_freelistN(&nldrag->links); - MEM_freeN(nldrag); - - return OPERATOR_FINISHED; - } - } - - return OPERATOR_RUNNING_MODAL; -} - -/* return 1 when socket clicked */ -static bNodeLinkDrag *node_link_init(SpaceNode *snode, int detach) -{ - bNode *node; - bNodeSocket *sock; - bNodeLink *link, *link_next, *oplink; - bNodeLinkDrag *nldrag = NULL; - LinkData *linkdata; - int num_links; - - /* output indicated? */ - if (node_find_indicated_socket(snode, &node, &sock, SOCK_OUT)) { - nldrag = MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata"); - - num_links = nodeCountSocketLinks(snode->edittree, sock); - if (num_links > 0 && (num_links >= sock->limit || detach)) { - /* dragged links are fixed on input side */ - nldrag->in_out = SOCK_IN; - /* detach current links and store them in the operator data */ - for (link = snode->edittree->links.first; link; link = link_next) { - link_next = link->next; - if (link->fromsock == sock) { - linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data"); - linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link"); - *oplink = *link; - oplink->next = oplink->prev = NULL; - BLI_addtail(&nldrag->links, linkdata); - nodeRemLink(snode->edittree, link); - } - } - } - else { - /* dragged links are fixed on output side */ - nldrag->in_out = SOCK_OUT; - /* create a new link */ - linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data"); - linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link"); - oplink->fromnode = node; - oplink->fromsock = sock; - BLI_addtail(&nldrag->links, linkdata); - } - } - /* or an input? */ - else if (node_find_indicated_socket(snode, &node, &sock, SOCK_IN)) { - nldrag = MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata"); - - num_links = nodeCountSocketLinks(snode->edittree, sock); - if (num_links > 0 && (num_links >= sock->limit || detach)) { - /* dragged links are fixed on output side */ - nldrag->in_out = SOCK_OUT; - /* detach current links and store them in the operator data */ - for (link = snode->edittree->links.first; link; link = link_next) { - link_next = link->next; - if (link->tosock == sock) { - linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data"); - linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link"); - *oplink = *link; - oplink->next = oplink->prev = NULL; - BLI_addtail(&nldrag->links, linkdata); - nodeRemLink(snode->edittree, link); - - /* send changed event to original link->tonode */ - if (node) - snode_update(snode, node); - } - } - } - else { - /* dragged links are fixed on input side */ - nldrag->in_out = SOCK_IN; - /* create a new link */ - linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data"); - linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link"); - oplink->tonode = node; - oplink->tosock = sock; - BLI_addtail(&nldrag->links, linkdata); - } - } - - return nldrag; -} - -static int node_link_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - SpaceNode *snode = CTX_wm_space_node(C); - ARegion *ar = CTX_wm_region(C); - bNodeLinkDrag *nldrag; - int detach = RNA_boolean_get(op->ptr, "detach"); - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], - &snode->mx, &snode->my); - - ED_preview_kill_jobs(C); - - nldrag = node_link_init(snode, detach); - - if (nldrag) { - op->customdata = nldrag; - BLI_addtail(&snode->linkdrag, nldrag); - - /* add modal handler */ - WM_event_add_modal_handler(C, op); - - return OPERATOR_RUNNING_MODAL; - } - else - return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; -} - -static int node_link_cancel(bContext *C, wmOperator *op) -{ - SpaceNode *snode = CTX_wm_space_node(C); - bNodeLinkDrag *nldrag = op->customdata; - - BLI_remlink(&snode->linkdrag, nldrag); - - BLI_freelistN(&nldrag->links); - MEM_freeN(nldrag); - - return OPERATOR_CANCELLED; -} - -void NODE_OT_link(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Link Nodes"; - ot->idname = "NODE_OT_link"; - ot->description = "Use the mouse to create a link between two nodes"; - - /* api callbacks */ - ot->invoke = node_link_invoke; - ot->modal = node_link_modal; -// ot->exec = node_link_exec; - ot->poll = ED_operator_node_active; - ot->cancel = node_link_cancel; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; - - RNA_def_boolean(ot->srna, "detach", FALSE, "Detach", "Detach and redirect existing links"); -} - -/* ********************** Make Link operator ***************** */ - -/* makes a link between selected output and input sockets */ -static int node_make_link_exec(bContext *C, wmOperator *op) -{ - SpaceNode *snode = CTX_wm_space_node(C); - int replace = RNA_boolean_get(op->ptr, "replace"); - - ED_preview_kill_jobs(C); - - snode_autoconnect(snode, 1, replace); - - /* deselect sockets after linking */ - node_deselect_all_input_sockets(snode, 0); - node_deselect_all_output_sockets(snode, 0); - - ntreeUpdateTree(snode->edittree); - snode_notify(C, snode); - snode_dag_update(C, snode); - - return OPERATOR_FINISHED; -} - -void NODE_OT_link_make(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Make Links"; - ot->description = "Makes a link between selected output in input sockets"; - ot->idname = "NODE_OT_link_make"; - - /* callbacks */ - ot->exec = node_make_link_exec; - ot->poll = ED_operator_node_active; // XXX we need a special poll which checks that there are selected input/output sockets - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_boolean(ot->srna, "replace", 0, "Replace", "Replace socket connections with the new links"); -} - -/* ********************** Add reroute operator ***************** */ -#define LINK_RESOL 12 -static int add_reroute_intersect_check(bNodeLink *link, float mcoords[][2], int tot, float result[2]) -{ - float coord_array[LINK_RESOL + 1][2]; - int i, b; - - if (node_link_bezier_points(NULL, NULL, link, coord_array, LINK_RESOL)) { - - for (i = 0; i < tot - 1; i++) - for (b = 0; b < LINK_RESOL; b++) - if (isect_line_line_v2(mcoords[i], mcoords[i + 1], coord_array[b], coord_array[b + 1]) > 0) { - result[0] = (mcoords[i][0] + mcoords[i + 1][0]) / 2.0f; - result[1] = (mcoords[i][1] + mcoords[i + 1][1]) / 2.0f; - return 1; - } - } - return 0; -} - -static int add_reroute_exec(bContext *C, wmOperator *op) -{ - SpaceNode *snode = CTX_wm_space_node(C); - ARegion *ar = CTX_wm_region(C); - bNode *gnode = node_tree_get_editgroup(snode->nodetree); - float mcoords[256][2]; - int i = 0; - - RNA_BEGIN(op->ptr, itemptr, "path") - { - float loc[2]; - - RNA_float_get_array(&itemptr, "loc", loc); - UI_view2d_region_to_view(&ar->v2d, (short)loc[0], (short)loc[1], - &mcoords[i][0], &mcoords[i][1]); - i++; - if (i >= 256) break; - } - RNA_END; - - if (i > 1) { - bNodeLink *link; - float insertPoint[2]; - - ED_preview_kill_jobs(C); - - for (link = snode->edittree->links.first; link; link = link->next) { - if (add_reroute_intersect_check(link, mcoords, i, insertPoint)) { - bNodeTemplate ntemp; - bNode *rerouteNode; - - node_deselect_all(snode); - - ntemp.type = NODE_REROUTE; - rerouteNode = nodeAddNode(snode->edittree, &ntemp); - if (gnode) { - nodeFromView(gnode, insertPoint[0], insertPoint[1], &rerouteNode->locx, &rerouteNode->locy); - } - else { - rerouteNode->locx = insertPoint[0]; - rerouteNode->locy = insertPoint[1]; - } - - nodeAddLink(snode->edittree, link->fromnode, link->fromsock, rerouteNode, rerouteNode->inputs.first); - link->fromnode = rerouteNode; - link->fromsock = rerouteNode->outputs.first; - - break; // add one reroute at the time. - } - } - - ntreeUpdateTree(snode->edittree); - snode_notify(C, snode); - snode_dag_update(C, snode); - - return OPERATOR_FINISHED; - } - - return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; -} - -void NODE_OT_add_reroute(wmOperatorType *ot) -{ - PropertyRNA *prop; - - ot->name = "Add reroute"; - ot->idname = "NODE_OT_add_reroute"; - - ot->invoke = WM_gesture_lines_invoke; - ot->modal = WM_gesture_lines_modal; - ot->exec = add_reroute_exec; - ot->cancel = WM_gesture_lines_cancel; - - ot->poll = ED_operator_node_active; - - /* flags */ - 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); - /* internal */ - RNA_def_int(ot->srna, "cursor", BC_CROSSCURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX); -} - - -/* ********************** Cut Link operator ***************** */ -static int cut_links_intersect(bNodeLink *link, float mcoords[][2], int tot) -{ - float coord_array[LINK_RESOL + 1][2]; - int i, b; - - if (node_link_bezier_points(NULL, NULL, link, coord_array, LINK_RESOL)) { - - for (i = 0; i < tot - 1; i++) - for (b = 0; b < LINK_RESOL; b++) - if (isect_line_line_v2(mcoords[i], mcoords[i + 1], coord_array[b], coord_array[b + 1]) > 0) - return 1; - } - return 0; -} - -static int cut_links_exec(bContext *C, wmOperator *op) -{ - SpaceNode *snode = CTX_wm_space_node(C); - ARegion *ar = CTX_wm_region(C); - float mcoords[256][2]; - int i = 0; - - RNA_BEGIN(op->ptr, itemptr, "path") - { - float loc[2]; - - RNA_float_get_array(&itemptr, "loc", loc); - UI_view2d_region_to_view(&ar->v2d, (int)loc[0], (int)loc[1], - &mcoords[i][0], &mcoords[i][1]); - i++; - if (i >= 256) break; - } - RNA_END; - - if (i > 1) { - bNodeLink *link, *next; - - ED_preview_kill_jobs(C); - - for (link = snode->edittree->links.first; link; link = next) { - next = link->next; - - if (cut_links_intersect(link, mcoords, i)) { - snode_update(snode, link->tonode); - nodeRemLink(snode->edittree, link); - } - } - - ntreeUpdateTree(snode->edittree); - snode_notify(C, snode); - snode_dag_update(C, snode); - - return OPERATOR_FINISHED; - } - - return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; -} - -void NODE_OT_links_cut(wmOperatorType *ot) -{ - PropertyRNA *prop; - - ot->name = "Cut links"; - ot->idname = "NODE_OT_links_cut"; - ot->description = "Use the mouse to cut (remove) some links"; - - ot->invoke = WM_gesture_lines_invoke; - ot->modal = WM_gesture_lines_modal; - ot->exec = cut_links_exec; - ot->cancel = WM_gesture_lines_cancel; - - ot->poll = ED_operator_node_active; - - /* flags */ - 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); - /* internal */ - RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX); -} - -/* ********************** Detach links operator ***************** */ - -static int detach_links_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceNode *snode = CTX_wm_space_node(C); - bNodeTree *ntree = snode->edittree; bNode *node; - - ED_preview_kill_jobs(C); - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->flag & SELECT) { - nodeInternalRelink(ntree, node); - } - } - - ntreeUpdateTree(ntree); - - snode_notify(C, snode); - snode_dag_update(C, snode); - - return OPERATOR_FINISHED; -} -void NODE_OT_links_detach(wmOperatorType *ot) -{ - ot->name = "Detach Links"; - ot->idname = "NODE_OT_links_detach"; - ot->description = "Remove all links to selected nodes, and try to connect neighbor nodes together"; - - ot->exec = detach_links_exec; - ot->poll = ED_operator_node_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/* ********************* automatic node insert on dragging ******************* */ - -/* assumes sockets in list */ -static bNodeSocket *socket_best_match(ListBase *sockets) -{ - bNodeSocket *sock; - int type, maxtype = 0; - - /* find type range */ - for (sock = sockets->first; sock; sock = sock->next) - maxtype = MAX2(sock->type, maxtype); - - /* try all types, starting from 'highest' (i.e. colors, vectors, values) */ - for (type = maxtype; type >= 0; --type) { - for (sock = sockets->first; sock; sock = sock->next) { - if (!nodeSocketIsHidden(sock) && type == sock->type) { - return sock; - } - } - } - - /* no visible sockets, unhide first of highest type */ - for (type = maxtype; type >= 0; --type) { - for (sock = sockets->first; sock; sock = sock->next) { - if (type == sock->type) { - sock->flag &= ~SOCK_HIDDEN; - return sock; - } - } - } - - return NULL; -} - -/* prevent duplicate testing code below */ -static SpaceNode *ed_node_link_conditions(ScrArea *sa, bNode **select) -{ - SpaceNode *snode = sa ? sa->spacedata.first : NULL; - bNode *node; - bNodeLink *link; - - /* no unlucky accidents */ - if (sa == NULL || sa->spacetype != SPACE_NODE) return NULL; - - *select = NULL; - - for (node = snode->edittree->nodes.first; node; node = node->next) { - if (node->flag & SELECT) { - if (*select) - break; - else - *select = node; + for (node = lb->first; node; node = node->next) { + if (node->flag & NODE_SELECT) { + return TRUE; } } - /* only one selected */ - if (node || *select == NULL) return NULL; - - /* correct node */ - if ((*select)->inputs.first == NULL || (*select)->outputs.first == NULL) return NULL; - - /* test node for links */ - for (link = snode->edittree->links.first; link; link = link->next) { - if (link->tonode == *select || link->fromnode == *select) - return NULL; - } - - return snode; -} -/* assumes link with NODE_LINKFLAG_HILITE set */ -void ED_node_link_insert(ScrArea *sa) -{ - bNode *node, *select; - SpaceNode *snode = ed_node_link_conditions(sa, &select); - bNodeLink *link; - bNodeSocket *sockto; - - if (snode == NULL) return; - - /* get the link */ - for (link = snode->edittree->links.first; link; link = link->next) - if (link->flag & NODE_LINKFLAG_HILITE) - break; - - if (link) { - node = link->tonode; - sockto = link->tosock; - - link->tonode = select; - link->tosock = socket_best_match(&select->inputs); - link->flag &= ~NODE_LINKFLAG_HILITE; - - nodeAddLink(snode->edittree, select, socket_best_match(&select->outputs), node, sockto); - ntreeUpdateTree(snode->edittree); /* needed for pointers */ - snode_update(snode, select); - ED_node_changed_update(snode->id, select); - } -} - - -/* 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); - bNodeLink *link, *selink = NULL; - float mcoords[6][2]; - - if (snode == NULL) return; - - /* clear flags */ - for (link = snode->edittree->links.first; link; link = link->next) - link->flag &= ~NODE_LINKFLAG_HILITE; - - if (test == 0) return; - - /* okay, there's 1 node, without links, now intersect */ - mcoords[0][0] = select->totr.xmin; - mcoords[0][1] = select->totr.ymin; - mcoords[1][0] = select->totr.xmax; - mcoords[1][1] = select->totr.ymin; - mcoords[2][0] = select->totr.xmax; - mcoords[2][1] = select->totr.ymax; - mcoords[3][0] = select->totr.xmin; - mcoords[3][1] = select->totr.ymax; - mcoords[4][0] = select->totr.xmin; - mcoords[4][1] = select->totr.ymin; - mcoords[5][0] = select->totr.xmax; - mcoords[5][1] = select->totr.ymax; - - /* we only tag a single link for intersect now */ - /* idea; use header dist when more? */ - for (link = snode->edittree->links.first; link; link = link->next) { - - if (cut_links_intersect(link, mcoords, 5)) { /* intersect code wants edges */ - if (selink) - break; - selink = link; - } - } - - if (link == NULL && selink) - selink->flag |= NODE_LINKFLAG_HILITE; + return FALSE; } - /* ******************************** */ // XXX some code needing updating to operators... @@ -3611,7 +1392,6 @@ int node_render_changed_exec(bContext *C, wmOperator *UNUSED(op)) void NODE_OT_render_changed(wmOperatorType *ot) { - ot->name = "Render Changed Layer"; ot->idname = "NODE_OT_render_changed"; ot->description = "Render current scene, when input node's layer has been changed"; @@ -3624,326 +1404,6 @@ void NODE_OT_render_changed(wmOperatorType *ot) ot->flag = 0; } - -/* ****************** Make Group operator ******************* */ - -static int node_group_make_test(bNodeTree *ntree, bNode *gnode) -{ - bNode *node; - bNodeLink *link; - int totnode = 0; - - /* is there something to group? also do some clearing */ - for (node = ntree->nodes.first; node; node = node->next) { - if (node == gnode) - continue; - - if (node->flag & NODE_SELECT) { - /* no groups in groups */ - if (node->type == NODE_GROUP) - return 0; - totnode++; - } - - node->done = 0; - } - if (totnode == 0) return 0; - - /* check if all connections are OK, no unselected node has both - * inputs and outputs to a selection */ - for (link = ntree->links.first; link; link = link->next) { - if (link->fromnode && link->tonode && link->fromnode->flag & NODE_SELECT && link->fromnode != gnode) - link->tonode->done |= 1; - if (link->fromnode && link->tonode && link->tonode->flag & NODE_SELECT && link->tonode != gnode) - link->fromnode->done |= 2; - } - - for (node = ntree->nodes.first; node; node = node->next) { - if (node == gnode) - continue; - if ((node->flag & NODE_SELECT) == 0) - if (node->done == 3) - break; - } - if (node) - return 0; - - return 1; -} - -static void node_get_selected_minmax(bNodeTree *ntree, bNode *gnode, float *min, float *max) -{ - bNode *node; - INIT_MINMAX2(min, max); - for (node = ntree->nodes.first; node; node = node->next) { - if (node == gnode) - continue; - if (node->flag & NODE_SELECT) { - DO_MINMAX2((&node->locx), min, max); - } - } -} - -static int node_group_make_insert_selected(bNodeTree *ntree, bNode *gnode) -{ - bNodeTree *ngroup = (bNodeTree *)gnode->id; - bNodeLink *link, *linkn; - bNode *node, *nextn; - bNodeSocket *gsock; - ListBase anim_basepaths = {NULL, NULL}; - float min[2], max[2]; - - /* deselect all nodes in the target tree */ - for (node = ngroup->nodes.first; node; node = node->next) - node_deselect(node); - - node_get_selected_minmax(ntree, gnode, min, max); - - /* move nodes over */ - for (node = ntree->nodes.first; node; node = nextn) { - nextn = node->next; - if (node == gnode) - continue; - if (node->flag & NODE_SELECT) { - /* keep track of this node's RNA "base" path (the part of the pat identifying the node) - * if the old nodetree has animation data which potentially covers this node - */ - if (ntree->adt) { - PointerRNA ptr; - char *path; - - RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); - path = RNA_path_from_ID_to_struct(&ptr); - - if (path) - BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); - } - - /* ensure valid parent pointers, detach if parent stays outside the group */ - if (node->parent && !(node->parent->flag & NODE_SELECT)) - nodeDetachNode(node); - - /* change node-collection membership */ - BLI_remlink(&ntree->nodes, node); - BLI_addtail(&ngroup->nodes, node); - - /* ensure unique node name in the ngroup */ - nodeUniqueName(ngroup, node); - - node->locx -= 0.5f * (min[0] + max[0]); - node->locy -= 0.5f * (min[1] + max[1]); - } - } - - /* move animation data over */ - if (ntree->adt) { - LinkData *ld, *ldn = NULL; - - BKE_animdata_separate_by_basepath(&ntree->id, &ngroup->id, &anim_basepaths); - - /* paths + their wrappers need to be freed */ - for (ld = anim_basepaths.first; ld; ld = ldn) { - ldn = ld->next; - - MEM_freeN(ld->data); - BLI_freelinkN(&anim_basepaths, ld); - } - } - - /* node groups don't use internal cached data */ - ntreeFreeCache(ngroup); - - /* relink external sockets */ - for (link = ntree->links.first; link; link = linkn) { - int fromselect = (link->fromnode && (link->fromnode->flag & NODE_SELECT) && link->fromnode != gnode); - int toselect = (link->tonode && (link->tonode->flag & NODE_SELECT) && link->tonode != gnode); - linkn = link->next; - - if (gnode && ((fromselect && link->tonode == gnode) || (toselect && link->fromnode == gnode))) { - /* remove all links to/from the gnode. - * this can remove link information, but there's no general way to preserve it. - */ - nodeRemLink(ntree, link); - } - else if (fromselect && toselect) { - BLI_remlink(&ntree->links, link); - BLI_addtail(&ngroup->links, link); - } - else if (toselect) { - gsock = node_group_expose_socket(ngroup, link->tosock, SOCK_IN); - link->tosock->link = nodeAddLink(ngroup, NULL, gsock, link->tonode, link->tosock); - link->tosock = node_group_add_extern_socket(ntree, &gnode->inputs, SOCK_IN, gsock); - link->tonode = gnode; - } - else if (fromselect) { - /* search for existing group node socket */ - for (gsock = ngroup->outputs.first; gsock; gsock = gsock->next) - if (gsock->link && gsock->link->fromsock == link->fromsock) - break; - if (!gsock) { - gsock = node_group_expose_socket(ngroup, link->fromsock, SOCK_OUT); - gsock->link = nodeAddLink(ngroup, link->fromnode, link->fromsock, NULL, gsock); - link->fromsock = node_group_add_extern_socket(ntree, &gnode->outputs, SOCK_OUT, gsock); - } - else - link->fromsock = node_group_find_output(gnode, gsock); - link->fromnode = gnode; - } - } - - /* update of the group tree */ - ngroup->update |= NTREE_UPDATE; - /* update of the tree containing the group instance node */ - ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS; - - return 1; -} - -static bNode *node_group_make_from_selected(bNodeTree *ntree) -{ - bNode *gnode; - bNodeTree *ngroup; - float min[2], max[2]; - bNodeTemplate ntemp; - - node_get_selected_minmax(ntree, NULL, min, max); - - /* new nodetree */ - ngroup = ntreeAddTree("NodeGroup", ntree->type, NODE_GROUP); - - /* make group node */ - ntemp.type = NODE_GROUP; - ntemp.ngroup = ngroup; - gnode = nodeAddNode(ntree, &ntemp); - gnode->locx = 0.5f * (min[0] + max[0]); - gnode->locy = 0.5f * (min[1] + max[1]); - - node_group_make_insert_selected(ntree, gnode); - - /* update of the tree containing the group instance node */ - ntree->update |= NTREE_UPDATE_NODES; - - return gnode; -} - -typedef enum eNodeGroupMakeType { - NODE_GM_NEW, - NODE_GM_INSERT -} eNodeGroupMakeType; - -/* Operator Property */ -EnumPropertyItem node_group_make_types[] = { - {NODE_GM_NEW, "NEW", 0, "New", "Create a new node group from selected nodes"}, - {NODE_GM_INSERT, "INSERT", 0, "Insert", "Insert into active node group"}, - {0, NULL, 0, NULL, NULL} -}; - -static int node_group_make_exec(bContext *C, wmOperator *op) -{ - SpaceNode *snode = CTX_wm_space_node(C); - bNode *gnode; - int type = RNA_enum_get(op->ptr, "type"); - - if (snode->edittree != snode->nodetree) { - BKE_report(op->reports, RPT_WARNING, "Can not add a new Group in a Group"); - return OPERATOR_CANCELLED; - } - - /* for time being... is too complex to handle */ - if (snode->treetype == NTREE_COMPOSIT) { - for (gnode = snode->nodetree->nodes.first; gnode; gnode = gnode->next) { - if (gnode->flag & SELECT) - if (gnode->type == CMP_NODE_R_LAYERS) - break; - } - - if (gnode) { - BKE_report(op->reports, RPT_WARNING, "Can not add RenderLayer in a Group"); - return OPERATOR_CANCELLED; - } - } - - ED_preview_kill_jobs(C); - - switch (type) { - case NODE_GM_NEW: - if (node_group_make_test(snode->nodetree, NULL)) { - gnode = node_group_make_from_selected(snode->nodetree); - } - else { - BKE_report(op->reports, RPT_WARNING, "Can not make Group"); - return OPERATOR_CANCELLED; - } - break; - case NODE_GM_INSERT: - gnode = nodeGetActive(snode->nodetree); - if (!gnode || gnode->type != NODE_GROUP) { - BKE_report(op->reports, RPT_WARNING, "No active Group node"); - return OPERATOR_CANCELLED; - } - if (node_group_make_test(snode->nodetree, gnode)) { - node_group_make_insert_selected(snode->nodetree, gnode); - } - else { - BKE_report(op->reports, RPT_WARNING, "Can not insert into Group"); - return OPERATOR_CANCELLED; - } - break; - } - - if (gnode) { - nodeSetActive(snode->nodetree, gnode); - snode_make_group_editable(snode, gnode); - } - - if (gnode) - ntreeUpdateTree((bNodeTree *)gnode->id); - ntreeUpdateTree(snode->nodetree); - - snode_notify(C, snode); - snode_dag_update(C, snode); - - return OPERATOR_FINISHED; -} - -static int node_group_make_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event)) -{ - SpaceNode *snode = CTX_wm_space_node(C); - bNode *act = nodeGetActive(snode->edittree); - uiPopupMenu *pup = uiPupMenuBegin(C, "Make Group", ICON_NONE); - uiLayout *layout = uiPupMenuLayout(pup); - - uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); - uiItemEnumO(layout, "NODE_OT_group_make", NULL, 0, "type", NODE_GM_NEW); - - /* if active node is a group, add insert option */ - if (act && act->type == NODE_GROUP) { - uiItemEnumO(layout, "NODE_OT_group_make", NULL, 0, "type", NODE_GM_INSERT); - } - - uiPupMenuEnd(C, pup); - - return OPERATOR_CANCELLED; -} - -void NODE_OT_group_make(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Group"; - ot->description = "Make group from selected nodes"; - ot->idname = "NODE_OT_group_make"; - - /* api callbacks */ - ot->invoke = node_group_make_invoke; - ot->exec = node_group_make_exec; - ot->poll = ED_operator_node_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "type", node_group_make_types, NODE_GM_NEW, "Type", ""); -} - /* ****************** Hide operator *********************** */ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag) @@ -4251,202 +1711,6 @@ void NODE_OT_delete_reconnect(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ****************** 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(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; -} - -/* ****************** Add File Node Operator ******************* */ - -static int node_add_file_exec(bContext *C, wmOperator *op) -{ - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - SpaceNode *snode = CTX_wm_space_node(C); - bNode *node; - Image *ima = NULL; - bNodeTemplate ntemp; - - /* check input variables */ - if (RNA_struct_property_is_set(op->ptr, "filepath")) { - char path[FILE_MAX]; - RNA_string_get(op->ptr, "filepath", path); - - errno = 0; - - ima = BKE_image_load_exists(path); - - if (!ima) { - BKE_reportf(op->reports, RPT_ERROR, "Can't read: \"%s\", %s", path, errno ? strerror(errno) : "Unsupported image format"); - return OPERATOR_CANCELLED; - } - } - else if (RNA_struct_property_is_set(op->ptr, "name")) { - char name[MAX_ID_NAME - 2]; - RNA_string_get(op->ptr, "name", name); - ima = (Image *)BKE_libblock_find_name(ID_IM, name); - - if (!ima) { - BKE_reportf(op->reports, RPT_ERROR, "Image named \"%s\", not found", name); - return OPERATOR_CANCELLED; - } - } - - node_deselect_all(snode); - - switch (snode->nodetree->type) { - case NTREE_SHADER: - ntemp.type = SH_NODE_TEX_IMAGE; - break; - case NTREE_TEXTURE: - ntemp.type = TEX_NODE_IMAGE; - break; - case NTREE_COMPOSIT: - ntemp.type = CMP_NODE_IMAGE; - break; - default: - return OPERATOR_CANCELLED; - } - - ED_preview_kill_jobs(C); - - node = node_add_node(snode, bmain, scene, &ntemp, snode->mx, snode->my); - - if (!node) { - BKE_report(op->reports, RPT_WARNING, "Could not add an image node"); - return OPERATOR_CANCELLED; - } - - node->id = (ID *)ima; - - snode_notify(C, snode); - snode_dag_update(C, snode); - - return OPERATOR_FINISHED; -} - -static int node_add_file_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - ARegion *ar = CTX_wm_region(C); - SpaceNode *snode = CTX_wm_space_node(C); - - /* convert mouse coordinates to v2d space */ - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], - &snode->mx, &snode->my); - - if (RNA_struct_property_is_set(op->ptr, "filepath") || RNA_struct_property_is_set(op->ptr, "name")) - return node_add_file_exec(C, op); - else - return WM_operator_filesel(C, op, event); -} - -void NODE_OT_add_file(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Add File Node"; - ot->description = "Add a file node to the current node editor"; - ot->idname = "NODE_OT_add_file"; - - /* callbacks */ - ot->exec = node_add_file_exec; - ot->invoke = node_add_file_invoke; - ot->poll = ED_operator_node_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); //XXX TODO, relative_path - RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Datablock name to assign"); -} - -/********************** New node tree operator *********************/ - -static int new_node_tree_exec(bContext *C, wmOperator *op) -{ - SpaceNode *snode; - bNodeTree *ntree; - PointerRNA ptr, idptr; - PropertyRNA *prop; - int treetype; - char treename[MAX_ID_NAME - 2] = "NodeTree"; - - /* retrieve state */ - snode = CTX_wm_space_node(C); - - if (RNA_struct_property_is_set(op->ptr, "type")) - treetype = RNA_enum_get(op->ptr, "type"); - else - treetype = snode->treetype; - - if (RNA_struct_property_is_set(op->ptr, "name")) - RNA_string_get(op->ptr, "name", treename); - - ntree = ntreeAddTree(treename, treetype, 0); - if (!ntree) - return OPERATOR_CANCELLED; - - /* hook into UI */ - uiIDContextProperty(C, &ptr, &prop); - - if (prop) { - RNA_id_pointer_create(&ntree->id, &idptr); - RNA_property_pointer_set(&ptr, prop, idptr); - /* RNA_property_pointer_set increases the user count, - * fixed here as the editor is the initial user. - */ - --ntree->id.us; - RNA_property_update(C, &ptr, prop); - } - else if (snode) { - Scene *scene = CTX_data_scene(C); - snode->nodetree = ntree; - - ED_node_tree_update(snode, scene); - } - - return OPERATOR_FINISHED; -} - -void NODE_OT_new_node_tree(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "New Node Tree"; - ot->idname = "NODE_OT_new_node_tree"; - ot->description = "Create a new node tree"; - - /* api callbacks */ - ot->exec = new_node_tree_exec; - ot->poll = ED_operator_node_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "type", nodetree_type_items, NTREE_COMPOSIT, "Tree Type", ""); - RNA_def_string(ot->srna, "name", "NodeTree", MAX_ID_NAME - 2, "Name", ""); -} /* ****************** File Output Add Socket ******************* */ @@ -4458,18 +1722,18 @@ static int node_output_file_add_socket_exec(bContext *C, wmOperator *op) bNodeTree *ntree; bNode *node; char file_path[MAX_NAME]; - + ptr = CTX_data_pointer_get(C, "node"); if (!ptr.data) return OPERATOR_CANCELLED; node = ptr.data; ntree = ptr.id.data; - + RNA_string_get(op->ptr, "file_path", file_path); ntreeCompositOutputFileAddSocket(ntree, node, file_path, &scene->r.im_format); - + snode_notify(C, snode); - + return OPERATOR_FINISHED; } @@ -4479,14 +1743,14 @@ void NODE_OT_output_file_add_socket(wmOperatorType *ot) ot->name = "Add File Node Socket"; ot->description = "Add a new input to a file output node"; ot->idname = "NODE_OT_output_file_add_socket"; - + /* callbacks */ ot->exec = node_output_file_add_socket_exec; ot->poll = composite_node_active; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + RNA_def_string(ot->srna, "file_path", "Image", MAX_NAME, "File Path", "Sub-path of the output file"); } @@ -4640,305 +1904,188 @@ void NODE_OT_node_copy_color(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ****************** Set Parent ******************* */ +/* ****************** Copy to clipboard ******************* */ -static int node_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) +static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceNode *snode = CTX_wm_space_node(C); bNodeTree *ntree = snode->edittree; - bNode *frame = nodeGetActive(ntree), *node; - if (!frame || frame->type != NODE_FRAME) - return OPERATOR_CANCELLED; + bNode *gnode = node_tree_get_editgroup(snode->nodetree); + float gnode_x = 0.0f, gnode_y = 0.0f; + bNode *node, *new_node; + bNodeLink *link, *newlink; + + ED_preview_kill_jobs(C); + + /* clear current clipboard */ + BKE_node_clipboard_clear(); + BKE_node_clipboard_init(ntree); + + /* get group node offset */ + if (gnode) + nodeToView(gnode, 0.0f, 0.0f, &gnode_x, &gnode_y); for (node = ntree->nodes.first; node; node = node->next) { - if (node == frame) - continue; - if (node->flag & NODE_SELECT) { - nodeDetachNode(node); - nodeAttachNode(node, frame); + if (node->flag & SELECT) { + new_node = nodeCopyNode(NULL, node); + BKE_node_clipboard_add_node(new_node); } } - ED_node_sort(ntree); - WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL); + for (node = ntree->nodes.first; node; node = node->next) { + if (node->flag & SELECT) { + bNode *new_node = node->new_node; + + /* ensure valid pointers */ + if (new_node->parent) { + /* parent pointer must be redirected to new node or detached if parent is not copied */ + if (new_node->parent->flag & NODE_SELECT) { + new_node->parent = new_node->parent->new_node; + } + else { + nodeDetachNode(new_node); + } + } + + /* transform to basic view space. child node location is relative to parent */ + if (!new_node->parent) { + new_node->locx += gnode_x; + new_node->locy += gnode_y; + } + } + } + + /* copy links between selected nodes + * NB: this depends on correct node->new_node and sock->new_sock pointers from above copy! + */ + for (link = ntree->links.first; link; link = link->next) { + /* This creates new links between copied nodes. */ + if (link->tonode && (link->tonode->flag & NODE_SELECT) && + link->fromnode && (link->fromnode->flag & NODE_SELECT)) + { + newlink = MEM_callocN(sizeof(bNodeLink), "bNodeLink"); + newlink->flag = link->flag; + newlink->tonode = link->tonode->new_node; + newlink->tosock = link->tosock->new_sock; + newlink->fromnode = link->fromnode->new_node; + newlink->fromsock = link->fromsock->new_sock; + + BKE_node_clipboard_add_link(newlink); + } + } return OPERATOR_FINISHED; } -void NODE_OT_parent_set(wmOperatorType *ot) +void NODE_OT_clipboard_copy(wmOperatorType *ot) { /* identifiers */ - ot->name = "Make Parent"; - ot->description = "Attach selected nodes"; - ot->idname = "NODE_OT_parent_set"; + ot->name = "Copy to clipboard"; + ot->description = "Copies selected nodes to the clipboard"; + ot->idname = "NODE_OT_clipboard_copy"; /* api callbacks */ - ot->exec = node_parent_set_exec; + ot->exec = node_clipboard_copy_exec; ot->poll = ED_operator_node_active; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ****************** Clear Parent ******************* */ +/* ****************** Paste from clipboard ******************* */ -static int node_parent_clear_exec(bContext *C, wmOperator *UNUSED(op)) +static int node_clipboard_paste_exec(bContext *C, wmOperator *op) { SpaceNode *snode = CTX_wm_space_node(C); bNodeTree *ntree = snode->edittree; + bNode *gnode = node_tree_get_editgroup(snode->nodetree); + float gnode_x = 0.0f, gnode_y = 0.0f; bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->flag & NODE_SELECT) { - nodeDetachNode(node); - } - } - - WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL); + bNodeLink *link; + int num_nodes; + float centerx, centery; - return OPERATOR_FINISHED; -} + if (BKE_node_clipboard_get_type() != ntree->type) { + BKE_report(op->reports, RPT_ERROR, "Clipboard nodes are an incompatible type"); + return OPERATOR_CANCELLED; + } -void NODE_OT_parent_clear(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Clear Parent"; - ot->description = "Detach selected nodes"; - ot->idname = "NODE_OT_parent_clear"; + ED_preview_kill_jobs(C); - /* api callbacks */ - ot->exec = node_parent_clear_exec; - ot->poll = ED_operator_node_active; + /* deselect old nodes */ + node_deselect_all(snode); - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} + /* get group node offset */ + if (gnode) + nodeToView(gnode, 0.0f, 0.0f, &gnode_x, &gnode_y); -/* ****************** Join Nodes ******************* */ + /* calculate "barycenter" for placing on mouse cursor */ + num_nodes = 0; + centerx = centery = 0.0f; + for (node = BKE_node_clipboard_get_nodes()->first; node; node = node->next) { + ++num_nodes; + centerx += 0.5f * (node->totr.xmin + node->totr.xmax); + centery += 0.5f * (node->totr.ymin + node->totr.ymax); + } + centerx /= num_nodes; + centery /= num_nodes; -/* tags for depth-first search */ -#define NODE_JOIN_DONE 1 -#define NODE_JOIN_IS_DESCENDANT 2 + /* copy nodes from clipboard */ + for (node = BKE_node_clipboard_get_nodes()->first; node; node = node->next) { + bNode *new_node = nodeCopyNode(ntree, node); -static void node_join_attach_recursive(bNode *node, bNode *frame) -{ - node->done |= NODE_JOIN_DONE; - - if (node == frame) { - node->done |= NODE_JOIN_IS_DESCENDANT; + /* pasted nodes are selected */ + node_select(new_node); } - else if (node->parent) { - /* call recursively */ - if (!(node->parent->done & NODE_JOIN_DONE)) - node_join_attach_recursive(node->parent, frame); + + /* reparent copied nodes */ + for (node = BKE_node_clipboard_get_nodes()->first; node; node = node->next) { + bNode *new_node = node->new_node; + if (new_node->parent) + new_node->parent = new_node->parent->new_node; + - /* in any case: if the parent is a descendant, so is the child */ - if (node->parent->done & NODE_JOIN_IS_DESCENDANT) - node->done |= NODE_JOIN_IS_DESCENDANT; - else if (node->flag & NODE_TEST) { - /* if parent is not an decendant of the frame, reattach the node */ - nodeDetachNode(node); - nodeAttachNode(node, frame); - node->done |= NODE_JOIN_IS_DESCENDANT; + /* place nodes around the mouse cursor. child nodes locations are relative to parent */ + if (!new_node->parent) { + new_node->locx += snode->mx - centerx - gnode_x; + new_node->locy += snode->my - centery - gnode_y; } } - else if (node->flag & NODE_TEST) { - nodeAttachNode(node, frame); - node->done |= NODE_JOIN_IS_DESCENDANT; - } -} -static int node_join_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceNode *snode = CTX_wm_space_node(C); - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - bNodeTree *ntree = snode->edittree; - bNode *node, *frame; - bNodeTemplate ntemp; - - /* XXX save selection: node_add_node call below sets the new frame as single active+selected node */ - for (node = ntree->nodes.first; node; node = node->next) { - if (node->flag & NODE_SELECT) - node->flag |= NODE_TEST; - else - node->flag &= ~NODE_TEST; + for (link = BKE_node_clipboard_get_links()->first; link; link = link->next) { + nodeAddLink(ntree, link->fromnode->new_node, link->fromsock->new_sock, + link->tonode->new_node, link->tosock->new_sock); } - - ntemp.main = bmain; - ntemp.scene = scene; - ntemp.type = NODE_FRAME; - frame = node_add_node(snode, bmain, scene, &ntemp, 0.0f, 0.0f); - - /* reset tags */ - for (node = ntree->nodes.first; node; node = node->next) - node->done = 0; - - for (node = ntree->nodes.first; node; node = node->next) { - if (!(node->done & NODE_JOIN_DONE)) - node_join_attach_recursive(node, frame); - } - - /* restore selection */ - for (node = ntree->nodes.first; node; node = node->next) { - if (node->flag & NODE_TEST) - node->flag |= NODE_SELECT; - } - - ED_node_sort(ntree); - WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL); - - return OPERATOR_FINISHED; -} -void NODE_OT_join(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Join Nodes"; - ot->description = "Attach selected nodes to a new common frame"; - ot->idname = "NODE_OT_join"; - - /* api callbacks */ - ot->exec = node_join_exec; - ot->poll = ED_operator_node_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} + ntreeUpdateTree(snode->edittree); -/* ****************** Attach ******************* */ + snode_notify(C, snode); + snode_dag_update(C, snode); -static int node_attach_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceNode *snode = CTX_wm_space_node(C); - bNodeTree *ntree = snode->edittree; - bNode *frame; - - /* check nodes front to back */ - for (frame = ntree->nodes.last; frame; frame = frame->prev) { - /* skip selected, those are the nodes we want to attach */ - if ((frame->type != NODE_FRAME) || (frame->flag & NODE_SELECT)) - continue; - if (BLI_in_rctf(&frame->totr, snode->mx, snode->my)) - break; - } - if (frame) { - bNode *node, *parent; - for (node = ntree->nodes.last; node; node = node->prev) { - if (node->flag & NODE_SELECT) { - if (node->parent == NULL) { - /* attach all unparented nodes */ - nodeAttachNode(node, frame); - } - else { - /* attach nodes which share parent with the frame */ - for (parent = frame->parent; parent; parent = parent->parent) - if (parent == node->parent) - break; - if (parent) { - nodeDetachNode(node); - nodeAttachNode(node, frame); - } - } - } - } - } - - ED_node_sort(ntree); - WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL); - return OPERATOR_FINISHED; } -static int node_attach_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int node_clipboard_paste_invoke(bContext *C, wmOperator *op, wmEvent *event) { ARegion *ar = CTX_wm_region(C); SpaceNode *snode = CTX_wm_space_node(C); - + /* convert mouse coordinates to v2d space */ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &snode->mx, &snode->my); - - return node_attach_exec(C, op); -} - -void NODE_OT_attach(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Attach Nodes"; - ot->description = "Attach active node to a frame"; - ot->idname = "NODE_OT_attach"; - - /* api callbacks */ - ot->exec = node_attach_exec; - ot->invoke = node_attach_invoke; - ot->poll = ED_operator_node_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/* ****************** Detach ******************* */ - -/* tags for depth-first search */ -#define NODE_DETACH_DONE 1 -#define NODE_DETACH_IS_DESCENDANT 2 -static void node_detach_recursive(bNode *node) -{ - node->done |= NODE_DETACH_DONE; - - if (node->parent) { - /* call recursively */ - if (!(node->parent->done & NODE_DETACH_DONE)) - node_detach_recursive(node->parent); - - /* in any case: if the parent is a descendant, so is the child */ - if (node->parent->done & NODE_DETACH_IS_DESCENDANT) - node->done |= NODE_DETACH_IS_DESCENDANT; - else if (node->flag & NODE_SELECT) { - /* if parent is not a decendant of a selected node, detach */ - nodeDetachNode(node); - node->done |= NODE_DETACH_IS_DESCENDANT; - } - } - else if (node->flag & NODE_SELECT) { - node->done |= NODE_DETACH_IS_DESCENDANT; - } -} - -/* detach the root nodes in the current selection */ -static int node_detach_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceNode *snode = CTX_wm_space_node(C); - bNodeTree *ntree = snode->edittree; - bNode *node; - - /* reset tags */ - for (node = ntree->nodes.first; node; node = node->next) - node->done = 0; - /* detach nodes recursively - * relative order is preserved here! - */ - for (node = ntree->nodes.first; node; node = node->next) { - if (!(node->done & NODE_DETACH_DONE)) - node_detach_recursive(node); - } - - ED_node_sort(ntree); - WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL); - - return OPERATOR_FINISHED; + return node_clipboard_paste_exec(C, op); } -void NODE_OT_detach(wmOperatorType *ot) +void NODE_OT_clipboard_paste(wmOperatorType *ot) { /* identifiers */ - ot->name = "Detach Nodes"; - ot->description = "Detach selected nodes from parents"; - ot->idname = "NODE_OT_detach"; + ot->name = "Paste from clipboard"; + ot->description = "Pastes nodes from the clipboard to the active node tree"; + ot->idname = "NODE_OT_clipboard_paste"; /* api callbacks */ - ot->exec = node_detach_exec; + ot->exec = node_clipboard_paste_exec; + ot->invoke = node_clipboard_paste_invoke; ot->poll = ED_operator_node_active; /* flags */ diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c new file mode 100644 index 00000000000..7d3c9ce6b5b --- /dev/null +++ b/source/blender/editors/space_node/node_group.c @@ -0,0 +1,1125 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): David Millan Escriva, Juho Vepsäläinen, Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_node/node_group.c + * \ingroup spnode + */ + +#include "MEM_guardedalloc.h" + +#include "DNA_node_types.h" +#include "DNA_object_types.h" +#include "DNA_anim_types.h" + +#include "BLI_blenlib.h" + +#include "BKE_action.h" +#include "BKE_animsys.h" +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_report.h" + +#include "ED_node.h" /* own include */ +#include "ED_screen.h" +#include "ED_render.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "UI_resources.h" + +#include "node_intern.h" /* own include */ +#include "NOD_socket.h" + +static EnumPropertyItem socket_in_out_items[] = { + { SOCK_IN, "SOCK_IN", 0, "Input", "" }, + { SOCK_OUT, "SOCK_OUT", 0, "Output", "" }, + { 0, NULL, 0, NULL, NULL }, +}; + +/* ***************** Edit Group operator ************* */ + +void snode_make_group_editable(SpaceNode *snode, bNode *gnode) +{ + bNode *node; + + /* make sure nothing has group editing on */ + for (node = snode->nodetree->nodes.first; node; node = node->next) { + nodeGroupEditClear(node); + + /* while we're here, clear texture active */ + if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) { + /* this is not 100% sure to be reliable, see comment on the flag */ + node->flag &= ~NODE_ACTIVE_TEXTURE; + } + } + + if (gnode == NULL) { + /* with NULL argument we do a toggle */ + if (snode->edittree == snode->nodetree) + gnode = nodeGetActive(snode->nodetree); + } + + if (gnode) { + snode->edittree = nodeGroupEditSet(gnode, 1); + + /* deselect all other nodes, so we can also do grabbing of entire subtree */ + for (node = snode->nodetree->nodes.first; node; node = node->next) { + node_deselect(node); + + if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) { + /* this is not 100% sure to be reliable, see comment on the flag */ + node->flag &= ~NODE_ACTIVE_TEXTURE; + } + } + node_select(gnode); + } + else + snode->edittree = snode->nodetree; +} + +static int node_group_edit_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + + ED_preview_kill_jobs(C); + + if (snode->nodetree == snode->edittree) { + bNode *gnode = nodeGetActive(snode->edittree); + snode_make_group_editable(snode, gnode); + } + else + snode_make_group_editable(snode, NULL); + + WM_event_add_notifier(C, NC_SCENE | ND_NODES, NULL); + + return OPERATOR_FINISHED; +} + +static int node_group_edit_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNode *gnode; + + /* XXX callback? */ + if (snode->nodetree == snode->edittree) { + gnode = nodeGetActive(snode->edittree); + if (gnode && gnode->id && GS(gnode->id->name) == ID_NT && gnode->id->lib) { + uiPupMenuOkee(C, op->type->idname, "Make group local?"); + return OPERATOR_CANCELLED; + } + } + + return node_group_edit_exec(C, op); +} + +void NODE_OT_group_edit(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Edit Group"; + ot->description = "Edit node group"; + ot->idname = "NODE_OT_group_edit"; + + /* api callbacks */ + ot->invoke = node_group_edit_invoke; + ot->exec = node_group_edit_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/* ***************** Add Group Socket operator ************* */ + +static int node_group_socket_add_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + int in_out = -1; + char name[MAX_NAME] = ""; + int type = SOCK_FLOAT; + bNodeTree *ngroup = snode->edittree; + /* bNodeSocket *sock; */ /* UNUSED */ + + ED_preview_kill_jobs(C); + + if (RNA_struct_property_is_set(op->ptr, "name")) + RNA_string_get(op->ptr, "name", name); + + if (RNA_struct_property_is_set(op->ptr, "type")) + type = RNA_enum_get(op->ptr, "type"); + + if (RNA_struct_property_is_set(op->ptr, "in_out")) + in_out = RNA_enum_get(op->ptr, "in_out"); + else + return OPERATOR_CANCELLED; + + /* using placeholder subtype first */ + /* sock = */ /* UNUSED */ node_group_add_socket(ngroup, name, type, in_out); + + ntreeUpdateTree(ngroup); + + snode_notify(C, snode); + + return OPERATOR_FINISHED; +} + +void NODE_OT_group_socket_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Group Socket"; + ot->description = "Add node group socket"; + ot->idname = "NODE_OT_group_socket_add"; + + /* api callbacks */ + ot->exec = node_group_socket_add_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Type", "Input or Output"); + RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Group socket name"); + RNA_def_enum(ot->srna, "type", node_socket_type_items, SOCK_FLOAT, "Type", "Type of the group socket"); +} + +/* ***************** Remove Group Socket operator ************* */ + +static int node_group_socket_remove_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + int index = -1; + int in_out = -1; + bNodeTree *ngroup = snode->edittree; + bNodeSocket *sock; + + ED_preview_kill_jobs(C); + + if (RNA_struct_property_is_set(op->ptr, "index")) + index = RNA_int_get(op->ptr, "index"); + else + return OPERATOR_CANCELLED; + + if (RNA_struct_property_is_set(op->ptr, "in_out")) + in_out = RNA_enum_get(op->ptr, "in_out"); + else + return OPERATOR_CANCELLED; + + sock = (bNodeSocket *)BLI_findlink(in_out == SOCK_IN ? &ngroup->inputs : &ngroup->outputs, index); + if (sock) { + node_group_remove_socket(ngroup, sock, in_out); + ntreeUpdateTree(ngroup); + + snode_notify(C, snode); + } + + return OPERATOR_FINISHED; +} + +void NODE_OT_group_socket_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Group Socket"; + ot->description = "Remove a node group socket"; + ot->idname = "NODE_OT_group_socket_remove"; + + /* api callbacks */ + ot->exec = node_group_socket_remove_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, INT_MAX); + RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Type", "Input or Output"); +} + +/* ***************** Move Group Socket Up operator ************* */ + +static int node_group_socket_move_up_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + int index = -1; + int in_out = -1; + bNodeTree *ngroup = snode->edittree; + bNodeSocket *sock, *prev; + + ED_preview_kill_jobs(C); + + if (RNA_struct_property_is_set(op->ptr, "index")) + index = RNA_int_get(op->ptr, "index"); + else + return OPERATOR_CANCELLED; + + if (RNA_struct_property_is_set(op->ptr, "in_out")) + in_out = RNA_enum_get(op->ptr, "in_out"); + else + return OPERATOR_CANCELLED; + + /* swap */ + if (in_out == SOCK_IN) { + sock = (bNodeSocket *)BLI_findlink(&ngroup->inputs, index); + prev = sock->prev; + /* can't move up the first socket */ + if (!prev) + return OPERATOR_CANCELLED; + BLI_remlink(&ngroup->inputs, sock); + BLI_insertlinkbefore(&ngroup->inputs, prev, sock); + + ngroup->update |= NTREE_UPDATE_GROUP_IN; + } + else if (in_out == SOCK_OUT) { + sock = (bNodeSocket *)BLI_findlink(&ngroup->outputs, index); + prev = sock->prev; + /* can't move up the first socket */ + if (!prev) + return OPERATOR_CANCELLED; + BLI_remlink(&ngroup->outputs, sock); + BLI_insertlinkbefore(&ngroup->outputs, prev, sock); + + ngroup->update |= NTREE_UPDATE_GROUP_OUT; + } + ntreeUpdateTree(ngroup); + + snode_notify(C, snode); + + return OPERATOR_FINISHED; +} + +void NODE_OT_group_socket_move_up(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Move Group Socket Up"; + ot->description = "Move up node group socket"; + ot->idname = "NODE_OT_group_socket_move_up"; + + /* api callbacks */ + ot->exec = node_group_socket_move_up_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, INT_MAX); + RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Type", "Input or Output"); +} + +/* ***************** Move Group Socket Up operator ************* */ + +static int node_group_socket_move_down_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + int index = -1; + int in_out = -1; + bNodeTree *ngroup = snode->edittree; + bNodeSocket *sock, *next; + + ED_preview_kill_jobs(C); + + if (RNA_struct_property_is_set(op->ptr, "index")) + index = RNA_int_get(op->ptr, "index"); + else + return OPERATOR_CANCELLED; + + if (RNA_struct_property_is_set(op->ptr, "in_out")) + in_out = RNA_enum_get(op->ptr, "in_out"); + else + return OPERATOR_CANCELLED; + + /* swap */ + if (in_out == SOCK_IN) { + sock = (bNodeSocket *)BLI_findlink(&ngroup->inputs, index); + next = sock->next; + /* can't move down the last socket */ + if (!next) + return OPERATOR_CANCELLED; + BLI_remlink(&ngroup->inputs, sock); + BLI_insertlinkafter(&ngroup->inputs, next, sock); + + ngroup->update |= NTREE_UPDATE_GROUP_IN; + } + else if (in_out == SOCK_OUT) { + sock = (bNodeSocket *)BLI_findlink(&ngroup->outputs, index); + next = sock->next; + /* can't move down the last socket */ + if (!next) + return OPERATOR_CANCELLED; + BLI_remlink(&ngroup->outputs, sock); + BLI_insertlinkafter(&ngroup->outputs, next, sock); + + ngroup->update |= NTREE_UPDATE_GROUP_OUT; + } + ntreeUpdateTree(ngroup); + + snode_notify(C, snode); + + return OPERATOR_FINISHED; +} + +void NODE_OT_group_socket_move_down(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Move Group Socket Down"; + ot->description = "Move down node group socket"; + ot->idname = "NODE_OT_group_socket_move_down"; + + /* api callbacks */ + ot->exec = node_group_socket_move_down_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, INT_MAX); + RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Type", "Input or Output"); +} + +/* ******************** Ungroup operator ********************** */ + +/* returns 1 if its OK */ +static int node_group_ungroup(bNodeTree *ntree, bNode *gnode) +{ + bNodeLink *link, *linkn; + bNode *node, *nextn; + bNodeTree *ngroup, *wgroup; + ListBase anim_basepaths = {NULL, NULL}; + + ngroup = (bNodeTree *)gnode->id; + if (ngroup == NULL) return 0; + + /* clear new pointers, set in copytree */ + for (node = ntree->nodes.first; node; node = node->next) + node->new_node = NULL; + + /* wgroup is a temporary copy of the NodeTree we're merging in + * - all of wgroup's nodes are transferred across to their new home + * - ngroup (i.e. the source NodeTree) is left unscathed + */ + wgroup = ntreeCopyTree(ngroup); + + /* add the nodes into the ntree */ + for (node = wgroup->nodes.first; node; node = nextn) { + nextn = node->next; + + /* keep track of this node's RNA "base" path (the part of the path identifying the node) + * if the old nodetree has animation data which potentially covers this node + */ + if (wgroup->adt) { + PointerRNA ptr; + char *path; + + RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr); + path = RNA_path_from_ID_to_struct(&ptr); + + if (path) + BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); + } + + /* migrate node */ + BLI_remlink(&wgroup->nodes, node); + BLI_addtail(&ntree->nodes, node); + + /* ensure unique node name in the nodee tree */ + nodeUniqueName(ntree, node); + + node->locx += gnode->locx; + node->locy += gnode->locy; + + node->flag |= NODE_SELECT; + } + + /* restore external links to and from the gnode */ + for (link = ntree->links.first; link; link = link->next) { + if (link->fromnode == gnode) { + if (link->fromsock->groupsock) { + bNodeSocket *gsock = link->fromsock->groupsock; + if (gsock->link) { + if (gsock->link->fromnode) { + /* NB: using the new internal copies here! the groupsock pointer still maps to the old tree */ + link->fromnode = (gsock->link->fromnode ? gsock->link->fromnode->new_node : NULL); + link->fromsock = gsock->link->fromsock->new_sock; + } + else { + /* group output directly maps to group input */ + bNodeSocket *insock = node_group_find_input(gnode, gsock->link->fromsock); + if (insock->link) { + link->fromnode = insock->link->fromnode; + link->fromsock = insock->link->fromsock; + } + } + } + else { + /* copy the default input value from the group socket default to the external socket */ + node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, gsock->type, gsock->default_value); + } + } + } + } + /* remove internal output links, these are not used anymore */ + for (link = wgroup->links.first; link; link = linkn) { + linkn = link->next; + if (!link->tonode) + nodeRemLink(wgroup, link); + } + /* restore links from internal nodes */ + for (link = wgroup->links.first; link; link = linkn) { + linkn = link->next; + /* indicates link to group input */ + if (!link->fromnode) { + /* NB: can't use find_group_node_input here, + * because gnode sockets still point to the old tree! + */ + bNodeSocket *insock; + for (insock = gnode->inputs.first; insock; insock = insock->next) + if (insock->groupsock->new_sock == link->fromsock) + break; + if (insock->link) { + link->fromnode = insock->link->fromnode; + link->fromsock = insock->link->fromsock; + } + else { + /* copy the default input value from the group node socket default to the internal socket */ + node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, insock->type, insock->default_value); + nodeRemLink(wgroup, link); + } + } + } + + /* add internal links to the ntree */ + for (link = wgroup->links.first; link; link = linkn) { + linkn = link->next; + BLI_remlink(&wgroup->links, link); + BLI_addtail(&ntree->links, link); + } + + /* and copy across the animation, + * note that the animation data's action can be NULL here */ + if (wgroup->adt) { + LinkData *ld, *ldn = NULL; + bAction *waction; + + /* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */ + waction = wgroup->adt->action = BKE_action_copy(wgroup->adt->action); + + /* now perform the moving */ + BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths); + + /* paths + their wrappers need to be freed */ + for (ld = anim_basepaths.first; ld; ld = ldn) { + ldn = ld->next; + + MEM_freeN(ld->data); + BLI_freelinkN(&anim_basepaths, ld); + } + + /* free temp action too */ + if (waction) { + BKE_libblock_free(&G.main->action, waction); + } + } + + /* delete the group instance. this also removes old input links! */ + nodeFreeNode(ntree, gnode); + + /* free the group tree (takes care of user count) */ + BKE_libblock_free(&G.main->nodetree, wgroup); + + ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS; + + return 1; +} + +static int node_group_ungroup_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNode *gnode; + + ED_preview_kill_jobs(C); + + /* are we inside of a group? */ + gnode = node_tree_get_editgroup(snode->nodetree); + if (gnode) + snode_make_group_editable(snode, NULL); + + gnode = nodeGetActive(snode->edittree); + if (gnode == NULL) + return OPERATOR_CANCELLED; + + if (gnode->type != NODE_GROUP) { + BKE_report(op->reports, RPT_WARNING, "Not a group"); + return OPERATOR_CANCELLED; + } + else if (node_group_ungroup(snode->nodetree, gnode)) { + ntreeUpdateTree(snode->nodetree); + } + else { + BKE_report(op->reports, RPT_WARNING, "Can't ungroup"); + return OPERATOR_CANCELLED; + } + + snode_notify(C, snode); + snode_dag_update(C, snode); + + return OPERATOR_FINISHED; +} + +void NODE_OT_group_ungroup(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Ungroup"; + ot->description = "Ungroup selected nodes"; + ot->idname = "NODE_OT_group_ungroup"; + + /* api callbacks */ + ot->exec = node_group_ungroup_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/* ******************** Separate operator ********************** */ + +/* returns 1 if its OK */ +static int node_group_separate_selected(bNodeTree *ntree, bNode *gnode, int make_copy) +{ + bNodeLink *link, *link_next; + bNode *node, *node_next, *newnode; + bNodeTree *ngroup; + ListBase anim_basepaths = {NULL, NULL}; + + ngroup = (bNodeTree *)gnode->id; + if (ngroup == NULL) return 0; + + /* deselect all nodes in the target tree */ + for (node = ntree->nodes.first; node; node = node->next) + node_deselect(node); + + /* clear new pointers, set in nodeCopyNode */ + for (node = ngroup->nodes.first; node; node = node->next) + node->new_node = NULL; + + /* add selected nodes into the ntree */ + for (node = ngroup->nodes.first; node; node = node_next) { + node_next = node->next; + if (!(node->flag & NODE_SELECT)) + continue; + + if (make_copy) { + /* make a copy */ + newnode = nodeCopyNode(ngroup, node); + } + else { + /* use the existing node */ + newnode = node; + } + + /* keep track of this node's RNA "base" path (the part of the path identifying the node) + * if the old nodetree has animation data which potentially covers this node + */ + if (ngroup->adt) { + PointerRNA ptr; + char *path; + + RNA_pointer_create(&ngroup->id, &RNA_Node, newnode, &ptr); + path = RNA_path_from_ID_to_struct(&ptr); + + if (path) + BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); + } + + /* ensure valid parent pointers, detach if parent stays inside the group */ + if (newnode->parent && !(newnode->parent->flag & NODE_SELECT)) + nodeDetachNode(newnode); + + /* migrate node */ + BLI_remlink(&ngroup->nodes, newnode); + BLI_addtail(&ntree->nodes, newnode); + + /* ensure unique node name in the node tree */ + nodeUniqueName(ntree, newnode); + + newnode->locx += gnode->locx; + newnode->locy += gnode->locy; + } + + /* add internal links to the ntree */ + for (link = ngroup->links.first; link; link = link_next) { + int fromselect = (link->fromnode && (link->fromnode->flag & NODE_SELECT)); + int toselect = (link->tonode && (link->tonode->flag & NODE_SELECT)); + link_next = link->next; + + if (make_copy) { + /* make a copy of internal links */ + if (fromselect && toselect) + nodeAddLink(ntree, link->fromnode->new_node, link->fromsock->new_sock, link->tonode->new_node, link->tosock->new_sock); + } + else { + /* move valid links over, delete broken links */ + if (fromselect && toselect) { + BLI_remlink(&ngroup->links, link); + BLI_addtail(&ntree->links, link); + } + else if (fromselect || toselect) { + nodeRemLink(ngroup, link); + } + } + } + + /* and copy across the animation, + * note that the animation data's action can be NULL here */ + if (ngroup->adt) { + LinkData *ld, *ldn = NULL; + + /* now perform the moving */ + BKE_animdata_separate_by_basepath(&ngroup->id, &ntree->id, &anim_basepaths); + + /* paths + their wrappers need to be freed */ + for (ld = anim_basepaths.first; ld; ld = ldn) { + ldn = ld->next; + + MEM_freeN(ld->data); + BLI_freelinkN(&anim_basepaths, ld); + } + } + + ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS; + if (!make_copy) + ngroup->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS; + + return 1; +} + +typedef enum eNodeGroupSeparateType { + NODE_GS_COPY, + NODE_GS_MOVE +} eNodeGroupSeparateType; + +/* Operator Property */ +EnumPropertyItem node_group_separate_types[] = { + {NODE_GS_COPY, "COPY", 0, "Copy", "Copy to parent node tree, keep group intact"}, + {NODE_GS_MOVE, "MOVE", 0, "Move", "Move to parent node tree, remove from group"}, + {0, NULL, 0, NULL, NULL} +}; + +static int node_group_separate_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNode *gnode; + int type = RNA_enum_get(op->ptr, "type"); + + ED_preview_kill_jobs(C); + + /* are we inside of a group? */ + gnode = node_tree_get_editgroup(snode->nodetree); + if (!gnode) { + BKE_report(op->reports, RPT_WARNING, "Not inside node group"); + return OPERATOR_CANCELLED; + } + + switch (type) { + case NODE_GS_COPY: + if (!node_group_separate_selected(snode->nodetree, gnode, 1)) { + BKE_report(op->reports, RPT_WARNING, "Can't separate nodes"); + return OPERATOR_CANCELLED; + } + break; + case NODE_GS_MOVE: + if (!node_group_separate_selected(snode->nodetree, gnode, 0)) { + BKE_report(op->reports, RPT_WARNING, "Can't separate nodes"); + return OPERATOR_CANCELLED; + } + break; + } + + /* switch to parent tree */ + snode_make_group_editable(snode, NULL); + + ntreeUpdateTree(snode->nodetree); + + snode_notify(C, snode); + snode_dag_update(C, snode); + + return OPERATOR_FINISHED; +} + +static int node_group_separate_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event)) +{ + uiPopupMenu *pup = uiPupMenuBegin(C, "Separate", ICON_NONE); + uiLayout *layout = uiPupMenuLayout(pup); + + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); + uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_COPY); + uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_MOVE); + + uiPupMenuEnd(C, pup); + + return OPERATOR_CANCELLED; +} + +void NODE_OT_group_separate(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Separate"; + ot->description = "Separate selected nodes from the node group"; + ot->idname = "NODE_OT_group_separate"; + + /* api callbacks */ + ot->invoke = node_group_separate_invoke; + ot->exec = node_group_separate_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", node_group_separate_types, NODE_GS_COPY, "Type", ""); +} + +/* ****************** Make Group operator ******************* */ + +static int node_group_make_test(bNodeTree *ntree, bNode *gnode) +{ + bNode *node; + bNodeLink *link; + int totnode = 0; + + /* is there something to group? also do some clearing */ + for (node = ntree->nodes.first; node; node = node->next) { + if (node == gnode) + continue; + + if (node->flag & NODE_SELECT) { + /* no groups in groups */ + if (node->type == NODE_GROUP) + return 0; + totnode++; + } + + node->done = 0; + } + if (totnode == 0) return 0; + + /* check if all connections are OK, no unselected node has both + * inputs and outputs to a selection */ + for (link = ntree->links.first; link; link = link->next) { + if (link->fromnode && link->tonode && link->fromnode->flag & NODE_SELECT && link->fromnode != gnode) + link->tonode->done |= 1; + if (link->fromnode && link->tonode && link->tonode->flag & NODE_SELECT && link->tonode != gnode) + link->fromnode->done |= 2; + } + + for (node = ntree->nodes.first; node; node = node->next) { + if (node == gnode) + continue; + if ((node->flag & NODE_SELECT) == 0) + if (node->done == 3) + break; + } + if (node) + return 0; + + return 1; +} + + +static void node_get_selected_minmax(bNodeTree *ntree, bNode *gnode, float *min, float *max) +{ + bNode *node; + INIT_MINMAX2(min, max); + for (node = ntree->nodes.first; node; node = node->next) { + if (node == gnode) + continue; + if (node->flag & NODE_SELECT) { + DO_MINMAX2((&node->locx), min, max); + } + } +} + +static int node_group_make_insert_selected(bNodeTree *ntree, bNode *gnode) +{ + bNodeTree *ngroup = (bNodeTree *)gnode->id; + bNodeLink *link, *linkn; + bNode *node, *nextn; + bNodeSocket *gsock; + ListBase anim_basepaths = {NULL, NULL}; + float min[2], max[2]; + + /* deselect all nodes in the target tree */ + for (node = ngroup->nodes.first; node; node = node->next) + node_deselect(node); + + node_get_selected_minmax(ntree, gnode, min, max); + + /* move nodes over */ + for (node = ntree->nodes.first; node; node = nextn) { + nextn = node->next; + if (node == gnode) + continue; + if (node->flag & NODE_SELECT) { + /* keep track of this node's RNA "base" path (the part of the pat identifying the node) + * if the old nodetree has animation data which potentially covers this node + */ + if (ntree->adt) { + PointerRNA ptr; + char *path; + + RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); + path = RNA_path_from_ID_to_struct(&ptr); + + if (path) + BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); + } + + /* ensure valid parent pointers, detach if parent stays outside the group */ + if (node->parent && !(node->parent->flag & NODE_SELECT)) + nodeDetachNode(node); + + /* change node-collection membership */ + BLI_remlink(&ntree->nodes, node); + BLI_addtail(&ngroup->nodes, node); + + /* ensure unique node name in the ngroup */ + nodeUniqueName(ngroup, node); + + node->locx -= 0.5f * (min[0] + max[0]); + node->locy -= 0.5f * (min[1] + max[1]); + } + } + + /* move animation data over */ + if (ntree->adt) { + LinkData *ld, *ldn = NULL; + + BKE_animdata_separate_by_basepath(&ntree->id, &ngroup->id, &anim_basepaths); + + /* paths + their wrappers need to be freed */ + for (ld = anim_basepaths.first; ld; ld = ldn) { + ldn = ld->next; + + MEM_freeN(ld->data); + BLI_freelinkN(&anim_basepaths, ld); + } + } + + /* node groups don't use internal cached data */ + ntreeFreeCache(ngroup); + + /* relink external sockets */ + for (link = ntree->links.first; link; link = linkn) { + int fromselect = (link->fromnode && (link->fromnode->flag & NODE_SELECT) && link->fromnode != gnode); + int toselect = (link->tonode && (link->tonode->flag & NODE_SELECT) && link->tonode != gnode); + linkn = link->next; + + if (gnode && ((fromselect && link->tonode == gnode) || (toselect && link->fromnode == gnode))) { + /* remove all links to/from the gnode. + * this can remove link information, but there's no general way to preserve it. + */ + nodeRemLink(ntree, link); + } + else if (fromselect && toselect) { + BLI_remlink(&ntree->links, link); + BLI_addtail(&ngroup->links, link); + } + else if (toselect) { + gsock = node_group_expose_socket(ngroup, link->tosock, SOCK_IN); + link->tosock->link = nodeAddLink(ngroup, NULL, gsock, link->tonode, link->tosock); + link->tosock = node_group_add_extern_socket(ntree, &gnode->inputs, SOCK_IN, gsock); + link->tonode = gnode; + } + else if (fromselect) { + /* search for existing group node socket */ + for (gsock = ngroup->outputs.first; gsock; gsock = gsock->next) + if (gsock->link && gsock->link->fromsock == link->fromsock) + break; + if (!gsock) { + gsock = node_group_expose_socket(ngroup, link->fromsock, SOCK_OUT); + gsock->link = nodeAddLink(ngroup, link->fromnode, link->fromsock, NULL, gsock); + link->fromsock = node_group_add_extern_socket(ntree, &gnode->outputs, SOCK_OUT, gsock); + } + else + link->fromsock = node_group_find_output(gnode, gsock); + link->fromnode = gnode; + } + } + + /* update of the group tree */ + ngroup->update |= NTREE_UPDATE; + /* update of the tree containing the group instance node */ + ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS; + + return 1; +} + +static bNode *node_group_make_from_selected(bNodeTree *ntree) +{ + bNode *gnode; + bNodeTree *ngroup; + float min[2], max[2]; + bNodeTemplate ntemp; + + node_get_selected_minmax(ntree, NULL, min, max); + + /* new nodetree */ + ngroup = ntreeAddTree("NodeGroup", ntree->type, NODE_GROUP); + + /* make group node */ + ntemp.type = NODE_GROUP; + ntemp.ngroup = ngroup; + gnode = nodeAddNode(ntree, &ntemp); + gnode->locx = 0.5f * (min[0] + max[0]); + gnode->locy = 0.5f * (min[1] + max[1]); + + node_group_make_insert_selected(ntree, gnode); + + /* update of the tree containing the group instance node */ + ntree->update |= NTREE_UPDATE_NODES; + + return gnode; +} + +typedef enum eNodeGroupMakeType { + NODE_GM_NEW, + NODE_GM_INSERT +} eNodeGroupMakeType; + +/* Operator Property */ +EnumPropertyItem node_group_make_types[] = { + {NODE_GM_NEW, "NEW", 0, "New", "Create a new node group from selected nodes"}, + {NODE_GM_INSERT, "INSERT", 0, "Insert", "Insert into active node group"}, + {0, NULL, 0, NULL, NULL} +}; + +static int node_group_make_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNode *gnode; + int type = RNA_enum_get(op->ptr, "type"); + + if (snode->edittree != snode->nodetree) { + BKE_report(op->reports, RPT_WARNING, "Can not add a new Group in a Group"); + return OPERATOR_CANCELLED; + } + + /* for time being... is too complex to handle */ + if (snode->treetype == NTREE_COMPOSIT) { + for (gnode = snode->nodetree->nodes.first; gnode; gnode = gnode->next) { + if (gnode->flag & SELECT) + if (gnode->type == CMP_NODE_R_LAYERS) + break; + } + + if (gnode) { + BKE_report(op->reports, RPT_WARNING, "Can not add RenderLayer in a Group"); + return OPERATOR_CANCELLED; + } + } + + ED_preview_kill_jobs(C); + + switch (type) { + case NODE_GM_NEW: + if (node_group_make_test(snode->nodetree, NULL)) { + gnode = node_group_make_from_selected(snode->nodetree); + } + else { + BKE_report(op->reports, RPT_WARNING, "Can not make Group"); + return OPERATOR_CANCELLED; + } + break; + case NODE_GM_INSERT: + gnode = nodeGetActive(snode->nodetree); + if (!gnode || gnode->type != NODE_GROUP) { + BKE_report(op->reports, RPT_WARNING, "No active Group node"); + return OPERATOR_CANCELLED; + } + if (node_group_make_test(snode->nodetree, gnode)) { + node_group_make_insert_selected(snode->nodetree, gnode); + } + else { + BKE_report(op->reports, RPT_WARNING, "Can not insert into Group"); + return OPERATOR_CANCELLED; + } + break; + } + + if (gnode) { + nodeSetActive(snode->nodetree, gnode); + snode_make_group_editable(snode, gnode); + } + + if (gnode) + ntreeUpdateTree((bNodeTree *)gnode->id); + ntreeUpdateTree(snode->nodetree); + + snode_notify(C, snode); + snode_dag_update(C, snode); + + return OPERATOR_FINISHED; +} + +static int node_group_make_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNode *act = nodeGetActive(snode->edittree); + uiPopupMenu *pup = uiPupMenuBegin(C, "Make Group", ICON_NONE); + uiLayout *layout = uiPupMenuLayout(pup); + + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); + uiItemEnumO(layout, "NODE_OT_group_make", NULL, 0, "type", NODE_GM_NEW); + + /* if active node is a group, add insert option */ + if (act && act->type == NODE_GROUP) { + uiItemEnumO(layout, "NODE_OT_group_make", NULL, 0, "type", NODE_GM_INSERT); + } + + uiPupMenuEnd(C, pup); + + return OPERATOR_CANCELLED; +} + +void NODE_OT_group_make(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Group"; + ot->description = "Make group from selected nodes"; + ot->idname = "NODE_OT_group_make"; + + /* api callbacks */ + ot->invoke = node_group_make_invoke; + ot->exec = node_group_make_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", node_group_make_types, NODE_GM_NEW, "Type", ""); +} diff --git a/source/blender/editors/space_node/node_header.c b/source/blender/editors/space_node/node_header.c index d4cfa2a3ba2..27ee6006327 100644 --- a/source/blender/editors/space_node/node_header.c +++ b/source/blender/editors/space_node/node_header.c @@ -28,13 +28,10 @@ * \ingroup spnode */ - #include <string.h> -#include <stdio.h> #include "DNA_space_types.h" #include "DNA_node_types.h" -#include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "MEM_guardedalloc.h" @@ -51,43 +48,38 @@ #include "BKE_scene.h" #include "BKE_screen.h" -#include "RNA_access.h" - #include "WM_api.h" #include "WM_types.h" -#include "UI_interface.h" -#include "UI_interface_icons.h" -#include "UI_resources.h" #include "UI_view2d.h" -#include "node_intern.h" +#include "node_intern.h" /* own include */ /* ************************ add menu *********************** */ static void do_node_add(bContext *C, bNodeTemplate *ntemp) { - Main *bmain= CTX_data_main(C); - Scene *scene= CTX_data_scene(C); - SpaceNode *snode= CTX_wm_space_node(C); - ScrArea *sa= CTX_wm_area(C); + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + SpaceNode *snode = CTX_wm_space_node(C); + ScrArea *sa = CTX_wm_area(C); ARegion *ar; bNode *node; /* get location to add node at mouse */ - for (ar=sa->regionbase.first; ar; ar=ar->next) { + for (ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->regiontype == RGN_TYPE_WINDOW) { - wmWindow *win= CTX_wm_window(C); - int x= win->eventstate->x - ar->winrct.xmin; - int y= win->eventstate->y - ar->winrct.ymin; + wmWindow *win = CTX_wm_window(C); + int x = win->eventstate->x - ar->winrct.xmin; + int y = win->eventstate->y - ar->winrct.ymin; - if (y < 60) y+= 60; + if (y < 60) y += 60; UI_view2d_region_to_view(&ar->v2d, x, y, &snode->mx, &snode->my); } } /* store selection in temp test flag */ - for (node= snode->edittree->nodes.first; node; node= node->next) { + for (node = snode->edittree->nodes.first; node; node = node->next) { if (node->flag & NODE_SELECT) node->flag |= NODE_TEST; else node->flag &= ~NODE_TEST; } @@ -95,12 +87,12 @@ static void do_node_add(bContext *C, bNodeTemplate *ntemp) /* node= */ node_add_node(snode, bmain, scene, ntemp, snode->mx, snode->my); /* select previous selection before autoconnect */ - for (node= snode->edittree->nodes.first; node; node= node->next) { + for (node = snode->edittree->nodes.first; node; node = node->next) { if (node->flag & NODE_TEST) node->flag |= NODE_SELECT; } /* deselect after autoconnection */ - for (node= snode->edittree->nodes.first; node; node= node->next) { + for (node = snode->edittree->nodes.first; node; node = node->next) { if (node->flag & NODE_TEST) node->flag &= ~NODE_SELECT; } @@ -123,29 +115,29 @@ static void do_node_add_static(bContext *C, void *UNUSED(arg), int event) static void do_node_add_group(bContext *C, void *UNUSED(arg), int event) { - SpaceNode *snode= CTX_wm_space_node(C); + SpaceNode *snode = CTX_wm_space_node(C); Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); bNodeTemplate ntemp; - if (event>=0) { - ntemp.ngroup= BLI_findlink(&G.main->nodetree, event); + if (event >= 0) { + ntemp.ngroup = BLI_findlink(&G.main->nodetree, event); ntemp.type = ntemp.ngroup->nodetype; } else { ntemp.type = -event; switch (ntemp.type) { - case NODE_GROUP: - ntemp.ngroup = ntreeAddTree("Group", snode->treetype, ntemp.type); - break; - case NODE_FORLOOP: - ntemp.ngroup = ntreeAddTree("For Loop", snode->treetype, ntemp.type); - break; - case NODE_WHILELOOP: - ntemp.ngroup = ntreeAddTree("While Loop", snode->treetype, ntemp.type); - break; - default: - ntemp.ngroup = NULL; + case NODE_GROUP: + ntemp.ngroup = ntreeAddTree("Group", snode->treetype, ntemp.type); + break; + case NODE_FORLOOP: + ntemp.ngroup = ntreeAddTree("For Loop", snode->treetype, ntemp.type); + break; + case NODE_WHILELOOP: + ntemp.ngroup = ntreeAddTree("While Loop", snode->treetype, ntemp.type); + break; + default: + ntemp.ngroup = NULL; } } if (!ntemp.ngroup) @@ -159,10 +151,10 @@ static void do_node_add_group(bContext *C, void *UNUSED(arg), int event) static int node_tree_has_type(int treetype, int nodetype) { - bNodeTreeType *ttype= ntreeGetType(treetype); + bNodeTreeType *ttype = ntreeGetType(treetype); bNodeType *ntype; - for (ntype=ttype->node_types.first; ntype; ntype=ntype->next) { - if (ntype->type==nodetype) + for (ntype = ttype->node_types.first; ntype; ntype = ntype->next) { + if (ntype->type == nodetype) return 1; } return 0; @@ -170,12 +162,12 @@ static int node_tree_has_type(int treetype, int nodetype) static void node_add_menu(bContext *C, uiLayout *layout, void *arg_nodeclass) { - Main *bmain= CTX_data_main(C); - Scene *scene= CTX_data_scene(C); - SpaceNode *snode= CTX_wm_space_node(C); + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + SpaceNode *snode = CTX_wm_space_node(C); bNodeTree *ntree; - int nodeclass= GET_INT_FROM_POINTER(arg_nodeclass); - int event, compatibility= 0; + int nodeclass = GET_INT_FROM_POINTER(arg_nodeclass); + int event, compatibility = 0; ntree = snode->nodetree; @@ -186,12 +178,12 @@ static void node_add_menu(bContext *C, uiLayout *layout, void *arg_nodeclass) if (ntree->type == NTREE_SHADER) { if (BKE_scene_use_new_shading_nodes(scene)) - compatibility= NODE_NEW_SHADING; + compatibility = NODE_NEW_SHADING; else - compatibility= NODE_OLD_SHADING; + compatibility = NODE_OLD_SHADING; } - if (nodeclass==NODE_CLASS_GROUP) { + if (nodeclass == NODE_CLASS_GROUP) { bNodeTree *ngroup; uiLayoutSetFunc(layout, do_node_add_group, NULL); @@ -205,10 +197,10 @@ static void node_add_menu(bContext *C, uiLayout *layout, void *arg_nodeclass) uiItemV(layout, IFACE_("New While Loop"), 0, -NODE_WHILELOOP); uiItemS(layout); - for (ngroup=bmain->nodetree.first, event=0; ngroup; ngroup= ngroup->id.next, ++event) { + for (ngroup = bmain->nodetree.first, event = 0; ngroup; ngroup = ngroup->id.next, ++event) { /* only use group trees */ - if (ngroup->type==ntree->type && ELEM3(ngroup->nodetype, NODE_GROUP, NODE_FORLOOP, NODE_WHILELOOP)) { - uiItemV(layout, ngroup->id.name+2, 0, event); + if (ngroup->type == ntree->type && ELEM3(ngroup->nodetype, NODE_GROUP, NODE_FORLOOP, NODE_WHILELOOP)) { + uiItemV(layout, ngroup->id.name + 2, 0, event); } } } @@ -217,26 +209,28 @@ static void node_add_menu(bContext *C, uiLayout *layout, void *arg_nodeclass) uiLayoutSetFunc(layout, do_node_add_static, NULL); - for (ntype=ntreeGetType(ntree->type)->node_types.first; ntype; ntype=ntype->next) { - if (ntype->nclass==nodeclass && ntype->name) - if (!compatibility || (ntype->compatibility & compatibility)) + for (ntype = ntreeGetType(ntree->type)->node_types.first; ntype; ntype = ntype->next) { + if (ntype->nclass == nodeclass && ntype->name) { + if (!compatibility || (ntype->compatibility & compatibility)) { uiItemV(layout, IFACE_(ntype->name), 0, ntype->type); + } + } } } } static void node_menu_add_foreach_cb(void *calldata, int nclass, const char *name) { - uiLayout *layout= calldata; + uiLayout *layout = calldata; uiItemMenuF(layout, IFACE_(name), 0, node_add_menu, SET_INT_IN_POINTER(nclass)); } static void node_menu_add(const bContext *C, Menu *menu) { - Scene *scene= CTX_data_scene(C); - SpaceNode *snode= CTX_wm_space_node(C); - uiLayout *layout= menu->layout; - bNodeTreeType *ntreetype= ntreeGetType(snode->treetype); + Scene *scene = CTX_data_scene(C); + SpaceNode *snode = CTX_wm_space_node(C); + uiLayout *layout = menu->layout; + bNodeTreeType *ntreetype = ntreeGetType(snode->treetype); if (!snode->nodetree) uiLayoutSetActive(layout, FALSE); @@ -249,10 +243,9 @@ void node_menus_register(void) { MenuType *mt; - mt= MEM_callocN(sizeof(MenuType), "spacetype node menu add"); + mt = MEM_callocN(sizeof(MenuType), "spacetype node menu add"); strcpy(mt->idname, "NODE_MT_add"); strcpy(mt->label, "Add"); - mt->draw= node_menu_add; + mt->draw = node_menu_add; WM_menutype_add(mt); } - diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 9cd62342e19..a6bf8198cb4 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -111,26 +111,70 @@ void NODE_OT_select_same_type(struct wmOperatorType *ot); void NODE_OT_select_same_type_next(wmOperatorType *ot); void NODE_OT_select_same_type_prev(wmOperatorType *ot); -/* node_state.c */ +/* node_view.c */ void NODE_OT_view_all(struct wmOperatorType *ot); +void NODE_OT_backimage_move(struct wmOperatorType *ot); +void NODE_OT_backimage_zoom(struct wmOperatorType *ot); +void NODE_OT_backimage_sample(wmOperatorType *ot); + /* drawnode.c */ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link); -void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3 ); -int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol); +void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3); +int node_link_bezier_points(View2D * v2d, SpaceNode * snode, bNodeLink * link, float coord_array[][2], int resol); // void node_draw_link_straight(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3 ); void draw_nodespace_back_pix(ARegion *ar, SpaceNode *snode, int color_manage); + +/* node_add.c */ +bNode *node_add_node(struct SpaceNode *snode, struct Main *bmain, struct Scene *scene, + struct bNodeTemplate *ntemp, float locx, float locy); +void NODE_OT_add_reroute(struct wmOperatorType *ot); + + +/* node_group.c */ +void NODE_OT_group_make(struct wmOperatorType *ot); +void NODE_OT_group_ungroup(struct wmOperatorType *ot); +void NODE_OT_group_separate(struct wmOperatorType *ot); +void NODE_OT_group_edit(struct wmOperatorType *ot); +void NODE_OT_group_socket_add(struct wmOperatorType *ot); +void NODE_OT_group_socket_remove(struct wmOperatorType *ot); +void NODE_OT_group_socket_move_up(struct wmOperatorType *ot); +void NODE_OT_group_socket_move_down(struct wmOperatorType *ot); + + +/* note_add.c */ +void NODE_OT_add_file(struct wmOperatorType *ot); +void NODE_OT_new_node_tree(struct wmOperatorType *ot); + + +/* node_relationships.c */ +void NODE_OT_link(struct wmOperatorType *ot); +void NODE_OT_link_make(struct wmOperatorType *ot); +void NODE_OT_links_cut(struct wmOperatorType *ot); +void NODE_OT_links_detach(struct wmOperatorType *ot); + +void NODE_OT_parent_set(struct wmOperatorType *ot); +void NODE_OT_parent_clear(struct wmOperatorType *ot); +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 */ void node_tree_from_ID(ID *id, bNodeTree **ntree, bNodeTree **edittree, int *treetype); void snode_notify(bContext *C, SpaceNode *snode); void snode_dag_update(bContext *C, SpaceNode *snode); -bNode *node_add_node(struct SpaceNode *snode, struct Main *bmain, struct Scene *scene, struct bNodeTemplate *ntemp, float locx, float locy); void snode_set_context(SpaceNode *snode, Scene *scene); void snode_make_group_editable(SpaceNode *snode, bNode *gnode); -void snode_composite_job(const struct bContext *C, ScrArea *sa); + bNode *node_tree_get_editgroup(bNodeTree *ntree); -void snode_autoconnect(SpaceNode *snode, int allow_multiple, int replace); +void snode_update(struct SpaceNode *snode, struct bNode *node); +bNode *editnode_get_active(bNodeTree *ntree); +int composite_node_active(struct bContext *C); + int node_has_hidden_sockets(bNode *node); void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set); int node_render_changed_exec(bContext *, wmOperator *); @@ -141,21 +185,6 @@ void NODE_OT_delete(struct wmOperatorType *ot); void NODE_OT_delete_reconnect(struct wmOperatorType *ot); void NODE_OT_resize(struct wmOperatorType *ot); -void NODE_OT_link(struct wmOperatorType *ot); -void NODE_OT_link_make(struct wmOperatorType *ot); -void NODE_OT_links_cut(struct wmOperatorType *ot); -void NODE_OT_links_detach(struct wmOperatorType *ot); -void NODE_OT_add_reroute(struct wmOperatorType *ot); - -void NODE_OT_group_make(struct wmOperatorType *ot); -void NODE_OT_group_ungroup(struct wmOperatorType *ot); -void NODE_OT_group_separate(struct wmOperatorType *ot); -void NODE_OT_group_edit(struct wmOperatorType *ot); -void NODE_OT_group_socket_add(struct wmOperatorType *ot); -void NODE_OT_group_socket_remove(struct wmOperatorType *ot); -void NODE_OT_group_socket_move_up(struct wmOperatorType *ot); -void NODE_OT_group_socket_move_down(struct wmOperatorType *ot); - void NODE_OT_mute_toggle(struct wmOperatorType *ot); void NODE_OT_hide_toggle(struct wmOperatorType *ot); void NODE_OT_hide_socket_toggle(struct wmOperatorType *ot); @@ -163,46 +192,35 @@ void NODE_OT_preview_toggle(struct wmOperatorType *ot); void NODE_OT_options_toggle(struct wmOperatorType *ot); void NODE_OT_node_copy_color(struct wmOperatorType *ot); -void NODE_OT_show_cyclic_dependencies(struct wmOperatorType *ot); -void NODE_OT_link_viewer(struct wmOperatorType *ot); void NODE_OT_read_fullsamplelayers(struct wmOperatorType *ot); void NODE_OT_read_renderlayers(struct wmOperatorType *ot); void NODE_OT_render_changed(struct wmOperatorType *ot); -void NODE_OT_backimage_move(struct wmOperatorType *ot); -void NODE_OT_backimage_zoom(struct wmOperatorType *ot); -void NODE_OT_backimage_sample(wmOperatorType *ot); - -void NODE_OT_add_file(struct wmOperatorType *ot); - -void NODE_OT_new_node_tree(struct wmOperatorType *ot); - void NODE_OT_output_file_add_socket(struct wmOperatorType *ot); void NODE_OT_output_file_remove_active_socket(struct wmOperatorType *ot); void NODE_OT_output_file_move_active_socket(struct wmOperatorType *ot); -void NODE_OT_parent_set(struct wmOperatorType *ot); -void NODE_OT_parent_clear(struct wmOperatorType *ot); -void NODE_OT_join(struct wmOperatorType *ot); -void NODE_OT_attach(struct wmOperatorType *ot); -void NODE_OT_detach(struct wmOperatorType *ot); +/* Note: clipboard_cut is a simple macro of copy + delete */ +void NODE_OT_clipboard_copy(struct wmOperatorType *ot); +void NODE_OT_clipboard_paste(struct wmOperatorType *ot); extern const char *node_context_dir[]; // XXXXXX // XXX from BSE_node.h -#define HIDDEN_RAD 15.0f -#define BASIS_RAD 8.0f -#define NODE_DYS (U.widget_unit/2) -#define NODE_DY U.widget_unit +#define HIDDEN_RAD 15.0f +#define BASIS_RAD 8.0f +#define NODE_DYS (U.widget_unit / 2) +#define NODE_DY U.widget_unit #define NODE_MARGIN_X 15 -#define NODE_SOCKSIZE 5 +#define NODE_SOCKSIZE 5 +#define NODE_LINK_RESOL 12 // XXX button events (butspace) enum { B_NOP = 0, - B_REDR = 1, + B_REDR = 1, B_NODE_USEMAT, B_NODE_USESCENE, B_NODE_USETEX, diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index ff1661f0327..cfd373231ff 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -30,13 +30,12 @@ #include "DNA_node_types.h" -#include "DNA_scene_types.h" #include "BKE_context.h" #include "BLI_utildefines.h" -#include "ED_node.h" +#include "ED_node.h" /* own include */ #include "ED_screen.h" #include "ED_transform.h" @@ -45,7 +44,7 @@ #include "WM_api.h" #include "WM_types.h" -#include "node_intern.h" +#include "node_intern.h" /* own include */ void node_operatortypes(void) { @@ -113,6 +112,9 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_join); WM_operatortype_append(NODE_OT_attach); WM_operatortype_append(NODE_OT_detach); + + WM_operatortype_append(NODE_OT_clipboard_copy); + WM_operatortype_append(NODE_OT_clipboard_paste); } void ED_operatormacros_node(void) @@ -128,14 +130,14 @@ void ED_operatormacros_node(void) ot = WM_operatortype_append_macro("NODE_OT_translate_attach", "Move and Attach", "Move nodes and attach to frame", - OPTYPE_UNDO|OPTYPE_REGISTER); + OPTYPE_UNDO | OPTYPE_REGISTER); mot = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_boolean_set(mot->ptr, "release_confirm", TRUE); WM_operatortype_macro_define(ot, "NODE_OT_attach"); ot = WM_operatortype_append_macro("NODE_OT_detach_translate_attach", "Detach and Move", "Detach nodes, move and attach to frame", - OPTYPE_UNDO|OPTYPE_REGISTER); + OPTYPE_UNDO | OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "NODE_OT_detach"); mot = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_boolean_set(mot->ptr, "release_confirm", TRUE); @@ -143,25 +145,25 @@ void ED_operatormacros_node(void) ot = WM_operatortype_append_macro("NODE_OT_duplicate_move", "Duplicate", "Duplicate selected nodes and move them", - OPTYPE_UNDO|OPTYPE_REGISTER); + OPTYPE_UNDO | OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "NODE_OT_duplicate"); WM_operatortype_macro_define(ot, "NODE_OT_translate_attach"); /* modified operator call for duplicating with input links */ ot = WM_operatortype_append_macro("NODE_OT_duplicate_move_keep_inputs", "Duplicate", "Duplicate selected nodes keeping input links and move them", - OPTYPE_UNDO|OPTYPE_REGISTER); + OPTYPE_UNDO | OPTYPE_REGISTER); mot = WM_operatortype_macro_define(ot, "NODE_OT_duplicate"); RNA_boolean_set(mot->ptr, "keep_inputs", TRUE); WM_operatortype_macro_define(ot, "NODE_OT_translate_attach"); ot = WM_operatortype_append_macro("NODE_OT_move_detach_links", "Detach", "Move a node to detach links", - OPTYPE_UNDO|OPTYPE_REGISTER); + OPTYPE_UNDO | OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "NODE_OT_links_detach"); WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); ot = WM_operatortype_append_macro("NODE_OT_move_detach_links_release", "Detach", "Move a node to detach links", - OPTYPE_UNDO|OPTYPE_REGISTER); + OPTYPE_UNDO | OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "NODE_OT_links_detach"); mot = WM_operatortype_macro_define(ot, "NODE_OT_translate_attach"); } @@ -170,18 +172,18 @@ void ED_operatormacros_node(void) static void node_select_keymap(wmKeyMap *keymap, int extend) { /* modifier combinations */ - const int mod_single[] = { 0, KM_CTRL, KM_ALT, KM_CTRL|KM_ALT, + const int mod_single[] = { 0, KM_CTRL, KM_ALT, KM_CTRL | KM_ALT, -1 /* terminator */ - }; - const int mod_extend[] = { KM_SHIFT, KM_SHIFT|KM_CTRL, - KM_SHIFT|KM_ALT, KM_SHIFT|KM_CTRL|KM_ALT, + }; + const int mod_extend[] = { KM_SHIFT, KM_SHIFT | KM_CTRL, + KM_SHIFT | KM_ALT, KM_SHIFT | KM_CTRL | KM_ALT, -1 /* terminator */ - }; + }; const int *mod = (extend ? mod_extend : mod_single); wmKeyMapItem *kmi; int i; - for (i=0; mod[i] >= 0; ++i) { + for (i = 0; mod[i] >= 0; ++i) { kmi = WM_keymap_add_item(keymap, "NODE_OT_select", ACTIONMOUSE, KM_PRESS, mod[i], 0); RNA_boolean_set(kmi->ptr, "extend", extend); kmi = WM_keymap_add_item(keymap, "NODE_OT_select", SELECTMOUSE, KM_PRESS, mod[i], 0); @@ -212,23 +214,23 @@ void node_keymap(struct wmKeyConfig *keyconf) node_select_keymap(keymap, TRUE); kmi = WM_keymap_add_item(keymap, "NODE_OT_select_border", EVT_TWEAK_S, KM_ANY, 0, 0); - RNA_boolean_set(kmi->ptr, "tweak", TRUE); + RNA_boolean_set(kmi->ptr, "tweak", TRUE); /* each of these falls through if not handled... */ WM_keymap_add_item(keymap, "NODE_OT_link", LEFTMOUSE, KM_PRESS, 0, 0); kmi = WM_keymap_add_item(keymap, "NODE_OT_link", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); - RNA_boolean_set(kmi->ptr, "detach", TRUE); + RNA_boolean_set(kmi->ptr, "detach", TRUE); WM_keymap_add_item(keymap, "NODE_OT_resize", LEFTMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_add_reroute", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "NODE_OT_links_cut", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "NODE_OT_select_link_viewer", LEFTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL, 0); + WM_keymap_add_item(keymap, "NODE_OT_select_link_viewer", LEFTMOUSE, KM_PRESS, KM_SHIFT | KM_CTRL, 0); WM_keymap_add_item(keymap, "NODE_OT_backimage_move", MIDDLEMOUSE, KM_PRESS, KM_ALT, 0); kmi = WM_keymap_add_item(keymap, "NODE_OT_backimage_zoom", VKEY, KM_PRESS, 0, 0); - RNA_float_set(kmi->ptr, "factor", 0.83333f); + RNA_float_set(kmi->ptr, "factor", 0.83333f); kmi = WM_keymap_add_item(keymap, "NODE_OT_backimage_zoom", VKEY, KM_PRESS, KM_ALT, 0); - RNA_float_set(kmi->ptr, "factor", 1.2f); + RNA_float_set(kmi->ptr, "factor", 1.2f); WM_keymap_add_item(keymap, "NODE_OT_backimage_sample", ACTIONMOUSE, KM_PRESS, KM_ALT, 0); kmi = WM_keymap_add_item(keymap, "NODE_OT_link_make", FKEY, KM_PRESS, 0, 0); @@ -239,7 +241,7 @@ void node_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_menu(keymap, "NODE_MT_add", AKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "NODE_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0); /* modified operator call for duplicating with input links */ - WM_keymap_add_item(keymap, "NODE_OT_duplicate_move_keep_inputs", DKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); + WM_keymap_add_item(keymap, "NODE_OT_duplicate_move_keep_inputs", DKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0); WM_keymap_add_item(keymap, "NODE_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "NODE_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0); @@ -261,7 +263,11 @@ void node_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "NODE_OT_delete", DELKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_delete_reconnect", XKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "NODE_OT_select_all", AKEY, KM_PRESS, 0, 0); + kmi = WM_keymap_add_item(keymap, "NODE_OT_select_all", AKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); + kmi = WM_keymap_add_item(keymap, "NODE_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + WM_keymap_add_item(keymap, "NODE_OT_select_linked_to", LKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "NODE_OT_select_linked_from", LKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_select_same_type", GKEY, KM_PRESS, KM_SHIFT, 0); @@ -277,5 +283,8 @@ void node_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "NODE_OT_read_fullsamplelayers", RKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "NODE_OT_render_changed", ZKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "NODE_OT_clipboard_copy", CKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "NODE_OT_clipboard_paste", VKEY, KM_PRESS, KM_CTRL, 0); + transform_keymap_for_space(keyconf, keymap, SPACE_NODE); } diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c new file mode 100644 index 00000000000..d82118facd1 --- /dev/null +++ b/source/blender/editors/space_node/node_relationships.c @@ -0,0 +1,1421 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): David Millan Escriva, Juho Vepsäläinen, Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_node/node_relationships.c + * \ingroup spnode + */ + +#include "MEM_guardedalloc.h" + +#include "DNA_node_types.h" +#include "DNA_object_types.h" + +#include "BLI_math.h" +#include "BLI_blenlib.h" + +#include "BKE_context.h" +#include "BKE_main.h" +#include "BKE_node.h" + +#include "ED_node.h" /* own include */ +#include "ED_screen.h" +#include "ED_render.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "UI_view2d.h" + +#include "node_intern.h" /* own include */ + +/* ****************** Add *********************** */ + + +typedef struct bNodeListItem { + struct bNodeListItem *next, *prev; + struct bNode *node; +} bNodeListItem; + +static int sort_nodes_locx(void *a, void *b) +{ + bNodeListItem *nli1 = (bNodeListItem *)a; + bNodeListItem *nli2 = (bNodeListItem *)b; + bNode *node1 = nli1->node; + bNode *node2 = nli2->node; + + if (node1->locx > node2->locx) + return 1; + else + return 0; +} + +static int socket_is_available(bNodeTree *UNUSED(ntree), bNodeSocket *sock, int allow_used) +{ + if (nodeSocketIsHidden(sock)) + return 0; + + if (!allow_used && (sock->flag & SOCK_IN_USE)) + return 0; + + return 1; +} + +static bNodeSocket *best_socket_output(bNodeTree *ntree, bNode *node, bNodeSocket *sock_target, int allow_multiple) +{ + bNodeSocket *sock; + + /* first look for selected output */ + for (sock = node->outputs.first; sock; sock = sock->next) { + if (!socket_is_available(ntree, sock, allow_multiple)) + continue; + + if (sock->flag & SELECT) + return sock; + } + + /* try to find a socket with a matching name */ + for (sock = node->outputs.first; sock; sock = sock->next) { + if (!socket_is_available(ntree, sock, allow_multiple)) + continue; + + /* check for same types */ + if (sock->type == sock_target->type) { + if (strcmp(sock->name, sock_target->name) == 0) + return sock; + } + } + + /* otherwise settle for the first available socket of the right type */ + for (sock = node->outputs.first; sock; sock = sock->next) { + + if (!socket_is_available(ntree, sock, allow_multiple)) + continue; + + /* check for same types */ + if (sock->type == sock_target->type) { + return sock; + } + } + + return NULL; +} + +/* this is a bit complicated, but designed to prioritize finding + * sockets of higher types, such as image, first */ +static bNodeSocket *best_socket_input(bNodeTree *ntree, bNode *node, int num, int replace) +{ + bNodeSocket *sock; + int socktype, maxtype = 0; + int a = 0; + + for (sock = node->inputs.first; sock; sock = sock->next) { + maxtype = MAX2(sock->type, maxtype); + } + + /* find sockets of higher 'types' first (i.e. image) */ + for (socktype = maxtype; socktype >= 0; socktype--) { + for (sock = node->inputs.first; sock; sock = sock->next) { + + if (!socket_is_available(ntree, sock, replace)) { + a++; + continue; + } + + if (sock->type == socktype) { + /* increment to make sure we don't keep finding + * the same socket on every attempt running this function */ + a++; + if (a > num) + return sock; + } + } + } + + return NULL; +} + +static int snode_autoconnect_input(SpaceNode *snode, bNode *node_fr, bNodeSocket *sock_fr, bNode *node_to, bNodeSocket *sock_to, int replace) +{ + bNodeTree *ntree = snode->edittree; + bNodeLink *link; + + /* then we can connect */ + if (replace) + nodeRemSocketLinks(ntree, sock_to); + + link = nodeAddLink(ntree, node_fr, sock_fr, node_to, sock_to); + /* validate the new link */ + ntreeUpdateTree(ntree); + if (!(link->flag & NODE_LINK_VALID)) { + nodeRemLink(ntree, link); + return 0; + } + + snode_update(snode, node_to); + return 1; +} + +static void snode_autoconnect(SpaceNode *snode, int allow_multiple, int replace) +{ + bNodeTree *ntree = snode->edittree; + ListBase *nodelist = MEM_callocN(sizeof(ListBase), "items_list"); + bNodeListItem *nli; + bNode *node; + int i, numlinks = 0; + + for (node = ntree->nodes.first; node; node = node->next) { + if (node->flag & NODE_SELECT) { + nli = MEM_mallocN(sizeof(bNodeListItem), "temporary node list item"); + nli->node = node; + BLI_addtail(nodelist, nli); + } + } + + /* sort nodes left to right */ + BLI_sortlist(nodelist, sort_nodes_locx); + + for (nli = nodelist->first; nli; nli = nli->next) { + bNode *node_fr, *node_to; + bNodeSocket *sock_fr, *sock_to; + int has_selected_inputs = 0; + + if (nli->next == NULL) break; + + node_fr = nli->node; + node_to = nli->next->node; + + /* if there are selected sockets, connect those */ + for (sock_to = node_to->inputs.first; sock_to; sock_to = sock_to->next) { + if (sock_to->flag & SELECT) { + has_selected_inputs = 1; + + if (!socket_is_available(ntree, sock_to, replace)) + continue; + + /* check for an appropriate output socket to connect from */ + sock_fr = best_socket_output(ntree, node_fr, sock_to, allow_multiple); + if (!sock_fr) + continue; + + if (snode_autoconnect_input(snode, node_fr, sock_fr, node_to, sock_to, replace)) + ++numlinks; + } + } + + if (!has_selected_inputs) { + /* no selected inputs, connect by finding suitable match */ + int num_inputs = BLI_countlist(&node_to->inputs); + + for (i = 0; i < num_inputs; i++) { + + /* find the best guess input socket */ + sock_to = best_socket_input(ntree, node_to, i, replace); + if (!sock_to) + continue; + + /* check for an appropriate output socket to connect from */ + sock_fr = best_socket_output(ntree, node_fr, sock_to, allow_multiple); + if (!sock_fr) + continue; + + if (snode_autoconnect_input(snode, node_fr, sock_fr, node_to, sock_to, replace)) { + ++numlinks; + break; + } + } + } + } + + if (numlinks > 0) { + ntreeUpdateTree(ntree); + } + + BLI_freelistN(nodelist); + MEM_freeN(nodelist); +} + +/* *************************** link viewer op ******************** */ + +static int node_link_viewer(const bContext *C, bNode *tonode) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNode *node; + bNodeLink *link; + bNodeSocket *sock; + + /* context check */ + if (tonode == NULL || tonode->outputs.first == NULL) + return OPERATOR_CANCELLED; + if (ELEM(tonode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) + return OPERATOR_CANCELLED; + + /* get viewer */ + for (node = snode->edittree->nodes.first; node; node = node->next) + if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) + if (node->flag & NODE_DO_OUTPUT) + break; + /* no viewer, we make one active */ + if (node == NULL) { + for (node = snode->edittree->nodes.first; node; node = node->next) { + if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { + node->flag |= NODE_DO_OUTPUT; + break; + } + } + } + + sock = NULL; + + /* try to find an already connected socket to cycle to the next */ + if (node) { + link = NULL; + for (link = snode->edittree->links.first; link; link = link->next) + if (link->tonode == node && link->fromnode == tonode) + if (link->tosock == node->inputs.first) + break; + if (link) { + /* unlink existing connection */ + sock = link->fromsock; + nodeRemLink(snode->edittree, link); + + /* find a socket after the previously connected socket */ + for (sock = sock->next; sock; sock = sock->next) + if (!nodeSocketIsHidden(sock)) + break; + } + } + + /* find a socket starting from the first socket */ + if (!sock) { + for (sock = tonode->outputs.first; sock; sock = sock->next) + if (!nodeSocketIsHidden(sock)) + break; + } + + if (sock) { + /* add a new viewer if none exists yet */ + if (!node) { + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + bNodeTemplate ntemp; + + ntemp.type = CMP_NODE_VIEWER; + /* XXX location is a quick hack, just place it next to the linked socket */ + node = node_add_node(snode, bmain, scene, &ntemp, sock->locx + 100, sock->locy); + if (!node) + return OPERATOR_CANCELLED; + + link = NULL; + } + else { + /* get link to viewer */ + for (link = snode->edittree->links.first; link; link = link->next) + if (link->tonode == node && link->tosock == node->inputs.first) + break; + } + + if (link == NULL) { + nodeAddLink(snode->edittree, tonode, sock, node, node->inputs.first); + } + else { + link->fromnode = tonode; + link->fromsock = sock; + /* make sure the dependency sorting is updated */ + snode->edittree->update |= NTREE_UPDATE_LINKS; + } + ntreeUpdateTree(snode->edittree); + snode_update(snode, node); + } + + return OPERATOR_FINISHED; +} + + +static int node_active_link_viewer(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNode *node; + + node = editnode_get_active(snode->edittree); + + if (!node) + return OPERATOR_CANCELLED; + + ED_preview_kill_jobs(C); + + if (node_link_viewer(C, node) == OPERATOR_CANCELLED) + return OPERATOR_CANCELLED; + + snode_notify(C, snode); + + return OPERATOR_FINISHED; +} + + +void NODE_OT_link_viewer(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Link to Viewer Node"; + ot->description = "Link to viewer node"; + ot->idname = "NODE_OT_link_viewer"; + + /* api callbacks */ + ot->exec = node_active_link_viewer; + ot->poll = composite_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + + +/* *************************** add link op ******************** */ + +static void node_remove_extra_links(SpaceNode *snode, bNodeSocket *tsock, 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; + } + 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); + } + } + else + nodeRemLink(snode->edittree, tlink); + + snode->edittree->update |= NTREE_UPDATE_LINKS; + } + } +} + +static int outside_group_rect(SpaceNode *snode) +{ + bNode *gnode = node_tree_get_editgroup(snode->nodetree); + if (gnode) { + return (snode->mx < gnode->totr.xmin || + snode->mx >= gnode->totr.xmax || + snode->my < gnode->totr.ymin || + snode->my >= gnode->totr.ymax); + } + return 0; +} + +/* loop that adds a nodelink, called by function below */ +/* in_out = starting socket */ +static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceNode *snode = CTX_wm_space_node(C); + ARegion *ar = CTX_wm_region(C); + bNodeLinkDrag *nldrag = op->customdata; + bNodeTree *ntree = snode->edittree; + bNode *tnode; + bNodeSocket *tsock = NULL; + bNodeLink *link; + LinkData *linkdata; + int in_out; + + in_out = nldrag->in_out; + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], + &snode->mx, &snode->my); + + switch (event->type) { + case MOUSEMOVE: + + if (in_out == SOCK_OUT) { + if (node_find_indicated_socket(snode, &tnode, &tsock, SOCK_IN)) { + for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) { + link = linkdata->data; + + /* skip if this is already the target socket */ + if (link->tosock == tsock) + continue; + /* skip if socket is on the same node as the fromsock */ + if (tnode && link->fromnode == tnode) + continue; + + /* attach links to the socket */ + link->tonode = tnode; + link->tosock = tsock; + /* add it to the node tree temporarily */ + if (BLI_findindex(&ntree->links, link) < 0) + BLI_addtail(&ntree->links, link); + + ntree->update |= NTREE_UPDATE_LINKS; + } + ntreeUpdateTree(ntree); + } + else { + int do_update = FALSE; + for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) { + link = linkdata->data; + + if (link->tonode || link->tosock) { + BLI_remlink(&ntree->links, link); + link->prev = link->next = NULL; + link->tonode = NULL; + link->tosock = NULL; + + ntree->update |= NTREE_UPDATE_LINKS; + do_update = TRUE; + } + } + if (do_update) { + ntreeUpdateTree(ntree); + } + } + } + else { + if (node_find_indicated_socket(snode, &tnode, &tsock, SOCK_OUT)) { + for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) { + link = linkdata->data; + + /* skip if this is already the target socket */ + if (link->fromsock == tsock) + continue; + /* skip if socket is on the same node as the fromsock */ + if (tnode && link->tonode == tnode) + continue; + + /* attach links to the socket */ + link->fromnode = tnode; + link->fromsock = tsock; + /* add it to the node tree temporarily */ + if (BLI_findindex(&ntree->links, link) < 0) + BLI_addtail(&ntree->links, link); + + ntree->update |= NTREE_UPDATE_LINKS; + } + ntreeUpdateTree(ntree); + } + else { + int do_update = FALSE; + for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) { + link = linkdata->data; + + if (link->fromnode || link->fromsock) { + BLI_remlink(&ntree->links, link); + link->prev = link->next = NULL; + link->fromnode = NULL; + link->fromsock = NULL; + + ntree->update |= NTREE_UPDATE_LINKS; + do_update = TRUE; + } + } + if (do_update) { + ntreeUpdateTree(ntree); + } + } + } + + ED_region_tag_redraw(ar); + break; + + case LEFTMOUSE: + case RIGHTMOUSE: + case MIDDLEMOUSE: { + for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) { + link = linkdata->data; + + if (link->tosock && link->fromsock) { + /* send changed events for original tonode and new */ + if (link->tonode) + snode_update(snode, link->tonode); + + /* we might need to remove a link */ + if (in_out == SOCK_OUT) + node_remove_extra_links(snode, link->tosock, link); + + /* when linking to group outputs, update the socket type */ + /* XXX this should all be part of a generic update system */ + if (!link->tonode) { + if (link->tosock->type != link->fromsock->type) + nodeSocketSetType(link->tosock, link->fromsock->type); + } + } + else if (outside_group_rect(snode) && (link->tonode || link->fromnode)) { + /* automatically add new group socket */ + if (link->tonode && link->tosock) { + link->fromsock = node_group_expose_socket(ntree, link->tosock, SOCK_IN); + link->fromnode = NULL; + if (BLI_findindex(&ntree->links, link) < 0) + BLI_addtail(&ntree->links, link); + + ntree->update |= NTREE_UPDATE_GROUP_IN | NTREE_UPDATE_LINKS; + } + else if (link->fromnode && link->fromsock) { + link->tosock = node_group_expose_socket(ntree, link->fromsock, SOCK_OUT); + link->tonode = NULL; + if (BLI_findindex(&ntree->links, link) < 0) + BLI_addtail(&ntree->links, link); + + ntree->update |= NTREE_UPDATE_GROUP_OUT | NTREE_UPDATE_LINKS; + } + } + else + nodeRemLink(ntree, link); + } + + ntreeUpdateTree(ntree); + snode_notify(C, snode); + snode_dag_update(C, snode); + + BLI_remlink(&snode->linkdrag, nldrag); + /* links->data pointers are either held by the tree or freed already */ + BLI_freelistN(&nldrag->links); + MEM_freeN(nldrag); + + return OPERATOR_FINISHED; + } + } + + return OPERATOR_RUNNING_MODAL; +} + +/* return 1 when socket clicked */ +static bNodeLinkDrag *node_link_init(SpaceNode *snode, int detach) +{ + bNode *node; + bNodeSocket *sock; + bNodeLink *link, *link_next, *oplink; + bNodeLinkDrag *nldrag = NULL; + LinkData *linkdata; + int num_links; + + /* output indicated? */ + if (node_find_indicated_socket(snode, &node, &sock, SOCK_OUT)) { + nldrag = MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata"); + + num_links = nodeCountSocketLinks(snode->edittree, sock); + if (num_links > 0 && (num_links >= sock->limit || detach)) { + /* dragged links are fixed on input side */ + nldrag->in_out = SOCK_IN; + /* detach current links and store them in the operator data */ + for (link = snode->edittree->links.first; link; link = link_next) { + link_next = link->next; + if (link->fromsock == sock) { + linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data"); + linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link"); + *oplink = *link; + oplink->next = oplink->prev = NULL; + BLI_addtail(&nldrag->links, linkdata); + nodeRemLink(snode->edittree, link); + } + } + } + else { + /* dragged links are fixed on output side */ + nldrag->in_out = SOCK_OUT; + /* create a new link */ + linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data"); + linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link"); + oplink->fromnode = node; + oplink->fromsock = sock; + BLI_addtail(&nldrag->links, linkdata); + } + } + /* or an input? */ + else if (node_find_indicated_socket(snode, &node, &sock, SOCK_IN)) { + nldrag = MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata"); + + num_links = nodeCountSocketLinks(snode->edittree, sock); + if (num_links > 0 && (num_links >= sock->limit || detach)) { + /* dragged links are fixed on output side */ + nldrag->in_out = SOCK_OUT; + /* detach current links and store them in the operator data */ + for (link = snode->edittree->links.first; link; link = link_next) { + link_next = link->next; + if (link->tosock == sock) { + linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data"); + linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link"); + *oplink = *link; + oplink->next = oplink->prev = NULL; + BLI_addtail(&nldrag->links, linkdata); + nodeRemLink(snode->edittree, link); + + /* send changed event to original link->tonode */ + if (node) + snode_update(snode, node); + } + } + } + else { + /* dragged links are fixed on input side */ + nldrag->in_out = SOCK_IN; + /* create a new link */ + linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data"); + linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link"); + oplink->tonode = node; + oplink->tosock = sock; + BLI_addtail(&nldrag->links, linkdata); + } + } + + return nldrag; +} + +static int node_link_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceNode *snode = CTX_wm_space_node(C); + ARegion *ar = CTX_wm_region(C); + bNodeLinkDrag *nldrag; + int detach = RNA_boolean_get(op->ptr, "detach"); + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], + &snode->mx, &snode->my); + + ED_preview_kill_jobs(C); + + nldrag = node_link_init(snode, detach); + + if (nldrag) { + op->customdata = nldrag; + BLI_addtail(&snode->linkdrag, nldrag); + + /* add modal handler */ + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; + } + else + return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; +} + +static int node_link_cancel(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNodeLinkDrag *nldrag = op->customdata; + + BLI_remlink(&snode->linkdrag, nldrag); + + BLI_freelistN(&nldrag->links); + MEM_freeN(nldrag); + + return OPERATOR_CANCELLED; +} + +void NODE_OT_link(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Link Nodes"; + ot->idname = "NODE_OT_link"; + ot->description = "Use the mouse to create a link between two nodes"; + + /* api callbacks */ + ot->invoke = node_link_invoke; + ot->modal = node_link_modal; +// ot->exec = node_link_exec; + ot->poll = ED_operator_node_active; + ot->cancel = node_link_cancel; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; + + RNA_def_boolean(ot->srna, "detach", FALSE, "Detach", "Detach and redirect existing links"); +} + +/* ********************** Make Link operator ***************** */ + +/* makes a link between selected output and input sockets */ +static int node_make_link_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + int replace = RNA_boolean_get(op->ptr, "replace"); + + ED_preview_kill_jobs(C); + + snode_autoconnect(snode, 1, replace); + + /* deselect sockets after linking */ + node_deselect_all_input_sockets(snode, 0); + node_deselect_all_output_sockets(snode, 0); + + ntreeUpdateTree(snode->edittree); + snode_notify(C, snode); + snode_dag_update(C, snode); + + return OPERATOR_FINISHED; +} + +void NODE_OT_link_make(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Make Links"; + ot->description = "Makes a link between selected output in input sockets"; + ot->idname = "NODE_OT_link_make"; + + /* callbacks */ + ot->exec = node_make_link_exec; + ot->poll = ED_operator_node_active; // XXX we need a special poll which checks that there are selected input/output sockets + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "replace", 0, "Replace", "Replace socket connections with the new links"); +} + +/* ********************** Cut Link operator ***************** */ +static int cut_links_intersect(bNodeLink *link, float mcoords[][2], int tot) +{ + float coord_array[NODE_LINK_RESOL + 1][2]; + int i, b; + + if (node_link_bezier_points(NULL, NULL, link, coord_array, NODE_LINK_RESOL)) { + + for (i = 0; i < tot - 1; i++) + for (b = 0; b < NODE_LINK_RESOL; b++) + if (isect_line_line_v2(mcoords[i], mcoords[i + 1], coord_array[b], coord_array[b + 1]) > 0) + return 1; + } + return 0; +} + +static int cut_links_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + ARegion *ar = CTX_wm_region(C); + float mcoords[256][2]; + int i = 0; + + RNA_BEGIN(op->ptr, itemptr, "path") + { + float loc[2]; + + RNA_float_get_array(&itemptr, "loc", loc); + UI_view2d_region_to_view(&ar->v2d, (int)loc[0], (int)loc[1], + &mcoords[i][0], &mcoords[i][1]); + i++; + if (i >= 256) break; + } + RNA_END; + + if (i > 1) { + int found = FALSE; + bNodeLink *link, *next; + + for (link = snode->edittree->links.first; link; link = next) { + next = link->next; + + if (cut_links_intersect(link, mcoords, i)) { + + if (found == FALSE) { + ED_preview_kill_jobs(C); + found = TRUE; + } + + snode_update(snode, link->tonode); + nodeRemLink(snode->edittree, link); + } + } + + if (found) { + ntreeUpdateTree(snode->edittree); + snode_notify(C, snode); + snode_dag_update(C, snode); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } + + } + + return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; +} + +void NODE_OT_links_cut(wmOperatorType *ot) +{ + PropertyRNA *prop; + + ot->name = "Cut links"; + ot->idname = "NODE_OT_links_cut"; + ot->description = "Use the mouse to cut (remove) some links"; + + ot->invoke = WM_gesture_lines_invoke; + ot->modal = WM_gesture_lines_modal; + ot->exec = cut_links_exec; + ot->cancel = WM_gesture_lines_cancel; + + ot->poll = ED_operator_node_active; + + /* flags */ + 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); + /* internal */ + RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX); +} + +/* ********************** Detach links operator ***************** */ + +static int detach_links_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNodeTree *ntree = snode->edittree; + bNode *node; + + ED_preview_kill_jobs(C); + + for (node = ntree->nodes.first; node; node = node->next) { + if (node->flag & SELECT) { + nodeInternalRelink(ntree, node); + } + } + + ntreeUpdateTree(ntree); + + snode_notify(C, snode); + snode_dag_update(C, snode); + + return OPERATOR_FINISHED; +} + +void NODE_OT_links_detach(wmOperatorType *ot) +{ + ot->name = "Detach Links"; + ot->idname = "NODE_OT_links_detach"; + ot->description = "Remove all links to selected nodes, and try to connect neighbor nodes together"; + + ot->exec = detach_links_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + + +/* ****************** 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(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)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNodeTree *ntree = snode->edittree; + bNode *frame = nodeGetActive(ntree), *node; + if (!frame || frame->type != NODE_FRAME) + return OPERATOR_CANCELLED; + + for (node = ntree->nodes.first; node; node = node->next) { + if (node == frame) + continue; + if (node->flag & NODE_SELECT) { + nodeDetachNode(node); + nodeAttachNode(node, frame); + } + } + + ED_node_sort(ntree); + WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL); + + return OPERATOR_FINISHED; +} + +void NODE_OT_parent_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Make Parent"; + ot->description = "Attach selected nodes"; + ot->idname = "NODE_OT_parent_set"; + + /* api callbacks */ + ot->exec = node_parent_set_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/* ****************** Clear Parent ******************* */ + +static int node_parent_clear_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNodeTree *ntree = snode->edittree; + bNode *node; + + for (node = ntree->nodes.first; node; node = node->next) { + if (node->flag & NODE_SELECT) { + nodeDetachNode(node); + } + } + + WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL); + + return OPERATOR_FINISHED; +} + +void NODE_OT_parent_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Parent"; + ot->description = "Detach selected nodes"; + ot->idname = "NODE_OT_parent_clear"; + + /* api callbacks */ + ot->exec = node_parent_clear_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/* ****************** Join Nodes ******************* */ + +/* tags for depth-first search */ +#define NODE_JOIN_DONE 1 +#define NODE_JOIN_IS_DESCENDANT 2 + +static void node_join_attach_recursive(bNode *node, bNode *frame) +{ + node->done |= NODE_JOIN_DONE; + + if (node == frame) { + node->done |= NODE_JOIN_IS_DESCENDANT; + } + else if (node->parent) { + /* call recursively */ + if (!(node->parent->done & NODE_JOIN_DONE)) + node_join_attach_recursive(node->parent, frame); + + /* in any case: if the parent is a descendant, so is the child */ + if (node->parent->done & NODE_JOIN_IS_DESCENDANT) + node->done |= NODE_JOIN_IS_DESCENDANT; + else if (node->flag & NODE_TEST) { + /* if parent is not an decendant of the frame, reattach the node */ + nodeDetachNode(node); + nodeAttachNode(node, frame); + node->done |= NODE_JOIN_IS_DESCENDANT; + } + } + else if (node->flag & NODE_TEST) { + nodeAttachNode(node, frame); + node->done |= NODE_JOIN_IS_DESCENDANT; + } +} + +static int node_join_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + bNodeTree *ntree = snode->edittree; + bNode *node, *frame; + bNodeTemplate ntemp; + + /* XXX save selection: node_add_node call below sets the new frame as single active+selected node */ + for (node = ntree->nodes.first; node; node = node->next) { + if (node->flag & NODE_SELECT) + node->flag |= NODE_TEST; + else + node->flag &= ~NODE_TEST; + } + + ntemp.main = bmain; + ntemp.scene = scene; + ntemp.type = NODE_FRAME; + frame = node_add_node(snode, bmain, scene, &ntemp, 0.0f, 0.0f); + + /* reset tags */ + for (node = ntree->nodes.first; node; node = node->next) + node->done = 0; + + for (node = ntree->nodes.first; node; node = node->next) { + if (!(node->done & NODE_JOIN_DONE)) + node_join_attach_recursive(node, frame); + } + + /* restore selection */ + for (node = ntree->nodes.first; node; node = node->next) { + if (node->flag & NODE_TEST) + node->flag |= NODE_SELECT; + } + + ED_node_sort(ntree); + WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL); + + return OPERATOR_FINISHED; +} + +void NODE_OT_join(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Join Nodes"; + ot->description = "Attach selected nodes to a new common frame"; + ot->idname = "NODE_OT_join"; + + /* api callbacks */ + ot->exec = node_join_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/* ****************** Attach ******************* */ + +static int node_attach_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNodeTree *ntree = snode->edittree; + bNode *frame; + + /* check nodes front to back */ + for (frame = ntree->nodes.last; frame; frame = frame->prev) { + /* skip selected, those are the nodes we want to attach */ + if ((frame->type != NODE_FRAME) || (frame->flag & NODE_SELECT)) + continue; + if (BLI_in_rctf(&frame->totr, snode->mx, snode->my)) + break; + } + if (frame) { + bNode *node, *parent; + for (node = ntree->nodes.last; node; node = node->prev) { + if (node->flag & NODE_SELECT) { + if (node->parent == NULL) { + /* disallow moving a parent into its child */ + if (nodeAttachNodeCheck(frame, node) == FALSE) { + /* attach all unparented nodes */ + nodeAttachNode(node, frame); + } + } + else { + /* attach nodes which share parent with the frame */ + for (parent = frame->parent; parent; parent = parent->parent) { + if (parent == node->parent) { + break; + } + } + + if (parent) { + /* disallow moving a parent into its child */ + if (nodeAttachNodeCheck(frame, node) == FALSE) { + nodeDetachNode(node); + nodeAttachNode(node, frame); + } + } + } + } + } + } + + ED_node_sort(ntree); + WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL); + + return OPERATOR_FINISHED; +} + +static int node_attach_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + ARegion *ar = CTX_wm_region(C); + SpaceNode *snode = CTX_wm_space_node(C); + + /* convert mouse coordinates to v2d space */ + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &snode->mx, &snode->my); + + return node_attach_exec(C, op); +} + +void NODE_OT_attach(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Attach Nodes"; + ot->description = "Attach active node to a frame"; + ot->idname = "NODE_OT_attach"; + + /* api callbacks */ + ot->exec = node_attach_exec; + ot->invoke = node_attach_invoke; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/* ****************** Detach ******************* */ + +/* tags for depth-first search */ +#define NODE_DETACH_DONE 1 +#define NODE_DETACH_IS_DESCENDANT 2 + +static void node_detach_recursive(bNode *node) +{ + node->done |= NODE_DETACH_DONE; + + if (node->parent) { + /* call recursively */ + if (!(node->parent->done & NODE_DETACH_DONE)) + node_detach_recursive(node->parent); + + /* in any case: if the parent is a descendant, so is the child */ + if (node->parent->done & NODE_DETACH_IS_DESCENDANT) + node->done |= NODE_DETACH_IS_DESCENDANT; + else if (node->flag & NODE_SELECT) { + /* if parent is not a decendant of a selected node, detach */ + nodeDetachNode(node); + node->done |= NODE_DETACH_IS_DESCENDANT; + } + } + else if (node->flag & NODE_SELECT) { + node->done |= NODE_DETACH_IS_DESCENDANT; + } +} + + +/* detach the root nodes in the current selection */ +static int node_detach_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNodeTree *ntree = snode->edittree; + bNode *node; + + /* reset tags */ + for (node = ntree->nodes.first; node; node = node->next) + node->done = 0; + /* detach nodes recursively + * relative order is preserved here! + */ + for (node = ntree->nodes.first; node; node = node->next) { + if (!(node->done & NODE_DETACH_DONE)) + node_detach_recursive(node); + } + + ED_node_sort(ntree); + WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL); + + return OPERATOR_FINISHED; +} + +void NODE_OT_detach(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Detach Nodes"; + ot->description = "Detach selected nodes from parents"; + ot->idname = "NODE_OT_detach"; + + /* api callbacks */ + ot->exec = node_detach_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/* ********************* automatic node insert on dragging ******************* */ + + +/* prevent duplicate testing code below */ +static SpaceNode *ed_node_link_conditions(ScrArea *sa, bNode **select) +{ + SpaceNode *snode = sa ? sa->spacedata.first : NULL; + bNode *node; + bNodeLink *link; + + /* no unlucky accidents */ + if (sa == NULL || sa->spacetype != SPACE_NODE) return NULL; + + *select = NULL; + + for (node = snode->edittree->nodes.first; node; node = node->next) { + if (node->flag & SELECT) { + if (*select) + break; + else + *select = node; + } + } + /* only one selected */ + if (node || *select == NULL) return NULL; + + /* correct node */ + if ((*select)->inputs.first == NULL || (*select)->outputs.first == NULL) return NULL; + + /* test node for links */ + for (link = snode->edittree->links.first; link; link = link->next) { + if (link->tonode == *select || link->fromnode == *select) + return NULL; + } + + return snode; +} + +/* 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); + bNodeLink *link, *selink = NULL; + float mcoords[6][2]; + + if (snode == NULL) return; + + /* clear flags */ + for (link = snode->edittree->links.first; link; link = link->next) + link->flag &= ~NODE_LINKFLAG_HILITE; + + if (test == 0) return; + + /* okay, there's 1 node, without links, now intersect */ + mcoords[0][0] = select->totr.xmin; + mcoords[0][1] = select->totr.ymin; + mcoords[1][0] = select->totr.xmax; + mcoords[1][1] = select->totr.ymin; + mcoords[2][0] = select->totr.xmax; + mcoords[2][1] = select->totr.ymax; + mcoords[3][0] = select->totr.xmin; + mcoords[3][1] = select->totr.ymax; + mcoords[4][0] = select->totr.xmin; + mcoords[4][1] = select->totr.ymin; + mcoords[5][0] = select->totr.xmax; + mcoords[5][1] = select->totr.ymax; + + /* we only tag a single link for intersect now */ + /* idea; use header dist when more? */ + for (link = snode->edittree->links.first; link; link = link->next) { + + if (cut_links_intersect(link, mcoords, 5)) { /* intersect code wants edges */ + if (selink) + break; + selink = link; + } + } + + if (link == NULL && selink) + selink->flag |= NODE_LINKFLAG_HILITE; +} + +/* assumes sockets in list */ +static bNodeSocket *socket_best_match(ListBase *sockets) +{ + bNodeSocket *sock; + int type, maxtype = 0; + + /* find type range */ + for (sock = sockets->first; sock; sock = sock->next) + maxtype = MAX2(sock->type, maxtype); + + /* try all types, starting from 'highest' (i.e. colors, vectors, values) */ + for (type = maxtype; type >= 0; --type) { + for (sock = sockets->first; sock; sock = sock->next) { + if (!nodeSocketIsHidden(sock) && type == sock->type) { + return sock; + } + } + } + + /* no visible sockets, unhide first of highest type */ + for (type = maxtype; type >= 0; --type) { + for (sock = sockets->first; sock; sock = sock->next) { + if (type == sock->type) { + sock->flag &= ~SOCK_HIDDEN; + return sock; + } + } + } + + return NULL; +} + +/* assumes link with NODE_LINKFLAG_HILITE set */ +void ED_node_link_insert(ScrArea *sa) +{ + bNode *node, *select; + SpaceNode *snode = ed_node_link_conditions(sa, &select); + bNodeLink *link; + bNodeSocket *sockto; + + if (snode == NULL) return; + + /* get the link */ + for (link = snode->edittree->links.first; link; link = link->next) + if (link->flag & NODE_LINKFLAG_HILITE) + break; + + if (link) { + node = link->tonode; + sockto = link->tosock; + + link->tonode = select; + link->tosock = socket_best_match(&select->inputs); + link->flag &= ~NODE_LINKFLAG_HILITE; + + nodeAddLink(snode->edittree, select, socket_best_match(&select->outputs), node, sockto); + ntreeUpdateTree(snode->edittree); /* needed for pointers */ + snode_update(snode, select); + ED_node_changed_update(snode->id, select); + } +} diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index 1ea763a413d..43676ff572f 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -28,13 +28,7 @@ * \ingroup spnode */ - -#include <stdio.h> - -#include "BLI_listbase.h" - #include "DNA_node_types.h" -#include "DNA_scene_types.h" #include "BKE_context.h" #include "BKE_main.h" @@ -43,7 +37,7 @@ #include "BLI_rect.h" #include "BLI_utildefines.h" -#include "ED_node.h" +#include "ED_node.h" /* own include */ #include "ED_screen.h" #include "ED_types.h" @@ -55,7 +49,7 @@ #include "UI_view2d.h" -#include "node_intern.h" +#include "node_intern.h" /* own include */ /* ****** helpers ****** */ @@ -63,7 +57,7 @@ static bNode *node_under_mouse_select(bNodeTree *ntree, int mx, int my) { bNode *node; - for (node=ntree->nodes.last; node; node=node->prev) { + for (node = ntree->nodes.last; node; node = node->prev) { if (node->typeinfo->select_area_func) { if (node->typeinfo->select_area_func(node, mx, my)) return node; @@ -76,7 +70,7 @@ static bNode *node_under_mouse_tweak(bNodeTree *ntree, int mx, int my) { bNode *node; - for (node=ntree->nodes.last; node; node=node->prev) { + for (node = ntree->nodes.last; node; node = node->prev) { if (node->typeinfo->tweak_area_func) { if (node->typeinfo->tweak_area_func(node, mx, my)) return node; @@ -97,9 +91,9 @@ void node_deselect(bNode *node) node->flag &= ~SELECT; /* deselect sockets too */ - for (sock=node->inputs.first; sock; sock=sock->next) + for (sock = node->inputs.first; sock; sock = sock->next) sock->flag &= ~SELECT; - for (sock=node->outputs.first; sock; sock=sock->next) + for (sock = node->outputs.first; sock; sock = sock->next) sock->flag &= ~SELECT; } @@ -125,16 +119,16 @@ void node_socket_deselect(bNode *node, bNodeSocket *sock, int deselect_node) sock->flag &= ~SELECT; if (node && deselect_node) { - int sel=0; + int sel = 0; /* if no selected sockets remain, also deselect the node */ - for (sock=node->inputs.first; sock; sock=sock->next) { + for (sock = node->inputs.first; sock; sock = sock->next) { if (sock->flag & SELECT) { sel = 1; break; } } - for (sock=node->outputs.first; sock; sock=sock->next) { + for (sock = node->outputs.first; sock; sock = sock->next) { if (sock->flag & SELECT) { sel = 1; break; @@ -159,7 +153,7 @@ void node_deselect_all(SpaceNode *snode) { bNode *node; - for (node= snode->edittree->nodes.first; node; node= node->next) + for (node = snode->edittree->nodes.first; node; node = node->next) node_deselect(node); } @@ -173,15 +167,15 @@ void node_deselect_all_input_sockets(SpaceNode *snode, int deselect_nodes) * We can do that more efficiently here. */ - for (node= snode->edittree->nodes.first; node; node= node->next) { - int sel=0; + for (node = snode->edittree->nodes.first; node; node = node->next) { + int sel = 0; - for (sock= node->inputs.first; sock; sock=sock->next) + for (sock = node->inputs.first; sock; sock = sock->next) sock->flag &= ~SELECT; /* if no selected sockets remain, also deselect the node */ if (deselect_nodes) { - for (sock= node->outputs.first; sock; sock=sock->next) { + for (sock = node->outputs.first; sock; sock = sock->next) { if (sock->flag & SELECT) { sel = 1; break; @@ -193,7 +187,7 @@ void node_deselect_all_input_sockets(SpaceNode *snode, int deselect_nodes) } } - for (sock= snode->edittree->outputs.first; sock; sock=sock->next) + for (sock = snode->edittree->outputs.first; sock; sock = sock->next) sock->flag &= ~SELECT; } @@ -207,15 +201,15 @@ void node_deselect_all_output_sockets(SpaceNode *snode, int deselect_nodes) * We can do that more efficiently here. */ - for (node= snode->edittree->nodes.first; node; node= node->next) { - int sel=0; + for (node = snode->edittree->nodes.first; node; node = node->next) { + int sel = 0; - for (sock= node->outputs.first; sock; sock=sock->next) + for (sock = node->outputs.first; sock; sock = sock->next) sock->flag &= ~SELECT; /* if no selected sockets remain, also deselect the node */ if (deselect_nodes) { - for (sock= node->inputs.first; sock; sock=sock->next) { + for (sock = node->inputs.first; sock; sock = sock->next) { if (sock->flag & SELECT) { sel = 1; break; @@ -227,7 +221,7 @@ void node_deselect_all_output_sockets(SpaceNode *snode, int deselect_nodes) } } - for (sock= snode->edittree->inputs.first; sock; sock=sock->next) + for (sock = snode->edittree->inputs.first; sock; sock = sock->next) sock->flag &= ~SELECT; } @@ -238,7 +232,7 @@ int node_select_same_type(SpaceNode *snode) int redraw; /* search for the active node. */ - for (nac= snode->edittree->nodes.first; nac; nac= nac->next) { + for (nac = snode->edittree->nodes.first; nac; nac = nac->next) { if (nac->flag & SELECT) break; } @@ -247,16 +241,16 @@ int node_select_same_type(SpaceNode *snode) if (!nac) return(0); - redraw= 0; - for (p= snode->edittree->nodes.first; p; p= p->next) { + redraw = 0; + for (p = snode->edittree->nodes.first; p; p = p->next) { if (p->type != nac->type && p->flag & SELECT) { /* if it's selected but different type, unselect */ - redraw= 1; + redraw = 1; node_deselect(p); } else if (p->type == nac->type && (!(p->flag & SELECT))) { /* if it's the same type and is not selected, select! */ - redraw= 1; + redraw = 1; node_select(p); } } @@ -271,7 +265,7 @@ int node_select_same_type_np(SpaceNode *snode, int dir) bNode *nac, *p, *tnode; /* search the active one. */ - for (nac= snode->edittree->nodes.first; nac; nac= nac->next) { + for (nac = snode->edittree->nodes.first; nac; nac = nac->next) { if (nac->flag & SELECT) break; } @@ -281,9 +275,9 @@ int node_select_same_type_np(SpaceNode *snode, int dir) return(0); if (dir == 0) - p= nac->next; + p = nac->next; else - p= nac->prev; + p = nac->prev; while (p) { /* Now search the next with the same type. */ @@ -291,14 +285,14 @@ int node_select_same_type_np(SpaceNode *snode, int dir) break; if (dir == 0) - p= p->next; + p = p->next; else - p= p->prev; + p = p->prev; } if (p) { - for (tnode=snode->edittree->nodes.first; tnode; tnode=tnode->next) - if (tnode!=p) + for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) + if (tnode != p) node_deselect(tnode); node_select(p); return(1); @@ -308,12 +302,12 @@ int node_select_same_type_np(SpaceNode *snode, int dir) void node_select_single(bContext *C, bNode *node) { - Main *bmain= CTX_data_main(C); - SpaceNode *snode= CTX_wm_space_node(C); + Main *bmain = CTX_data_main(C); + SpaceNode *snode = CTX_wm_space_node(C); bNode *tnode; - for (tnode=snode->edittree->nodes.first; tnode; tnode=tnode->next) - if (tnode!=node) + for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) + if (tnode != node) node_deselect(tnode); node_select(node); @@ -321,7 +315,7 @@ void node_select_single(bContext *C, bNode *node) ED_node_sort(snode->edittree); - WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); + WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL); } /* ****** Click Select ****** */ @@ -356,7 +350,7 @@ static int node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const i * allows selecting outputs from different nodes though. */ if (node) { - for (tsock=node->outputs.first; tsock; tsock=tsock->next) + for (tsock = node->outputs.first; tsock; tsock = tsock->next) node_socket_deselect(node, tsock, 1); } node_socket_select(node, sock); @@ -368,20 +362,28 @@ static int node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const i node = node_under_mouse_select(snode->edittree, mx, my); if (node) { - node_toggle(node); - - ED_node_set_active(bmain, snode->edittree, node); + if ((node->flag & SELECT) && (node->flag & NODE_ACTIVE) == 0) { + /* if node is selected but not active make it active + * before it'll be desleected + */ + ED_node_set_active(bmain, snode->edittree, node); + } + else { + node_toggle(node); + ED_node_set_active(bmain, snode->edittree, node); + } + selected = 1; } } } - else { /* extend==0 */ + else { /* extend==0 */ /* find the closest visible node */ node = node_under_mouse_select(snode->edittree, mx, my); if (node) { - for (tnode=snode->edittree->nodes.first; tnode; tnode=tnode->next) + for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) node_deselect(tnode); node_select(node); ED_node_set_active(bmain, snode->edittree, node); @@ -398,9 +400,9 @@ static int node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const i static int node_select_exec(bContext *C, wmOperator *op) { - Main *bmain= CTX_data_main(C); - SpaceNode *snode= CTX_wm_space_node(C); - ARegion *ar= CTX_wm_region(C); + Main *bmain = CTX_data_main(C); + SpaceNode *snode = CTX_wm_space_node(C); + ARegion *ar = CTX_wm_region(C); int mval[2]; short extend; @@ -413,14 +415,14 @@ static int node_select_exec(bContext *C, wmOperator *op) /* perform the select */ if (node_mouse_select(bmain, snode, ar, mval, extend)) { /* send notifiers */ - WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); + WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL); /* allow tweak event to work too */ - return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH; + return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH; } else { /* allow tweak event to work too */ - return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH; + return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; } } @@ -445,7 +447,7 @@ void NODE_OT_select(wmOperatorType *ot) ot->poll = ED_operator_node_active; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ RNA_def_int(ot->srna, "mouse_x", 0, INT_MIN, INT_MAX, "Mouse X", "", INT_MIN, INT_MAX); @@ -457,13 +459,13 @@ void NODE_OT_select(wmOperatorType *ot) static int node_borderselect_exec(bContext *C, wmOperator *op) { - SpaceNode *snode= CTX_wm_space_node(C); - ARegion *ar= CTX_wm_region(C); + SpaceNode *snode = CTX_wm_space_node(C); + ARegion *ar = CTX_wm_region(C); bNode *node; rcti rect; rctf rectf; - int gesture_mode= RNA_int_get(op->ptr, "gesture_mode"); - int extend= RNA_boolean_get(op->ptr, "extend"); + int gesture_mode = RNA_int_get(op->ptr, "gesture_mode"); + int extend = RNA_boolean_get(op->ptr, "extend"); rect.xmin = RNA_int_get(op->ptr, "xmin"); rect.ymin = RNA_int_get(op->ptr, "ymin"); @@ -473,9 +475,9 @@ static int node_borderselect_exec(bContext *C, wmOperator *op) rect.ymax = RNA_int_get(op->ptr, "ymax"); UI_view2d_region_to_view(&ar->v2d, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax); - for (node= snode->edittree->nodes.first; node; node= node->next) { + for (node = snode->edittree->nodes.first; node; node = node->next) { if (BLI_rctf_isect(&rectf, &node->totr, NULL)) { - if (gesture_mode==GESTURE_MODAL_SELECT) + if (gesture_mode == GESTURE_MODAL_SELECT) node_select(node); else node_deselect(node); @@ -487,7 +489,7 @@ static int node_borderselect_exec(bContext *C, wmOperator *op) ED_node_sort(snode->edittree); - WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); + WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL); return OPERATOR_FINISHED; } @@ -499,14 +501,14 @@ static int node_border_select_invoke(bContext *C, wmOperator *op, wmEvent *event if (tweak) { /* prevent initiating the border select if the mouse is over a node */ /* this allows border select on empty space, but drag-translate on nodes */ - SpaceNode *snode= CTX_wm_space_node(C); - ARegion *ar= CTX_wm_region(C); + SpaceNode *snode = CTX_wm_space_node(C); + ARegion *ar = CTX_wm_region(C); float mx, my; UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &mx, &my); if (node_under_mouse_tweak(snode->edittree, mx, my)) - return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH; + return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; } return WM_border_select_invoke(C, op, event); @@ -528,7 +530,7 @@ void NODE_OT_select_border(wmOperatorType *ot) ot->poll = ED_operator_node_active; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* rna */ WM_operator_properties_gesture_border(ot, TRUE); @@ -537,29 +539,37 @@ void NODE_OT_select_border(wmOperatorType *ot) /* ****** Select/Deselect All ****** */ -static int node_select_all_exec(bContext *C, wmOperator *UNUSED(op)) +static int node_select_all_exec(bContext *C, wmOperator *op) { SpaceNode *snode = CTX_wm_space_node(C); - bNode *first = snode->edittree->nodes.first; + ListBase *node_lb = &snode->edittree->nodes; bNode *node; - int count= 0; + int action = RNA_enum_get(op->ptr, "action"); - for (node=first; node; node=node->next) - if (node->flag & NODE_SELECT) - count++; - - if (count) { - for (node=first; node; node=node->next) - node_deselect(node); + if (action == SEL_TOGGLE) { + if (ED_node_select_check(node_lb)) + action = SEL_DESELECT; + else + action = SEL_SELECT; } - else { - for (node=first; node; node=node->next) - node_select(node); + + for (node = node_lb->first; node; node = node->next) { + switch (action) { + case SEL_SELECT: + node_select(node); + break; + case SEL_DESELECT: + node_deselect(node); + break; + case SEL_INVERT: + ((node->flag & SELECT) ? node_deselect : node_select)(node); + break; + } } - + ED_node_sort(snode->edittree); - WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); + WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL); return OPERATOR_FINISHED; } @@ -575,7 +585,9 @@ void NODE_OT_select_all(wmOperatorType *ot) ot->poll = ED_operator_node_active; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + WM_operator_properties_select_all(ot); } /* ****** Select Linked To ****** */ @@ -586,22 +598,22 @@ static int node_select_linked_to_exec(bContext *C, wmOperator *UNUSED(op)) bNodeLink *link; bNode *node; - for (node=snode->edittree->nodes.first; node; node=node->next) + for (node = snode->edittree->nodes.first; node; node = node->next) node->flag &= ~NODE_TEST; - for (link=snode->edittree->links.first; link; link=link->next) { + for (link = snode->edittree->links.first; link; link = link->next) { if (link->fromnode && link->tonode && (link->fromnode->flag & NODE_SELECT)) link->tonode->flag |= NODE_TEST; } - for (node=snode->edittree->nodes.first; node; node=node->next) { + for (node = snode->edittree->nodes.first; node; node = node->next) { if (node->flag & NODE_TEST) node_select(node); } ED_node_sort(snode->edittree); - WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); + WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL); return OPERATOR_FINISHED; } @@ -617,7 +629,7 @@ void NODE_OT_select_linked_to(wmOperatorType *ot) ot->poll = ED_operator_node_active; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } /* ****** Select Linked From ****** */ @@ -628,22 +640,22 @@ static int node_select_linked_from_exec(bContext *C, wmOperator *UNUSED(op)) bNodeLink *link; bNode *node; - for (node=snode->edittree->nodes.first; node; node=node->next) + for (node = snode->edittree->nodes.first; node; node = node->next) node->flag &= ~NODE_TEST; - for (link=snode->edittree->links.first; link; link=link->next) { + for (link = snode->edittree->links.first; link; link = link->next) { if (link->fromnode && link->tonode && (link->tonode->flag & NODE_SELECT)) link->fromnode->flag |= NODE_TEST; } - for (node=snode->edittree->nodes.first; node; node=node->next) { + for (node = snode->edittree->nodes.first; node; node = node->next) { if (node->flag & NODE_TEST) node_select(node); } ED_node_sort(snode->edittree); - WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); + WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL); return OPERATOR_FINISHED; } @@ -659,7 +671,7 @@ void NODE_OT_select_linked_from(wmOperatorType *ot) ot->poll = ED_operator_node_active; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } /* ****** Select Same Type ****** */ @@ -672,7 +684,7 @@ static int node_select_same_type_exec(bContext *C, wmOperator *UNUSED(op)) ED_node_sort(snode->edittree); - WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); + WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL); return OPERATOR_FINISHED; } @@ -688,7 +700,7 @@ void NODE_OT_select_same_type(wmOperatorType *ot) ot->poll = ED_operator_node_active; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } /* ****** Select The Next/Prev Node Of The Same Type ****** */ @@ -701,7 +713,7 @@ static int node_select_same_type_next_exec(bContext *C, wmOperator *UNUSED(op)) ED_node_sort(snode->edittree); - WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); + WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL); return OPERATOR_FINISHED; } @@ -718,7 +730,7 @@ void NODE_OT_select_same_type_next(wmOperatorType *ot) ot->poll = ED_operator_node_active; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } static int node_select_same_type_prev_exec(bContext *C, wmOperator *UNUSED(op)) @@ -729,7 +741,7 @@ static int node_select_same_type_prev_exec(bContext *C, wmOperator *UNUSED(op)) ED_node_sort(snode->edittree); - WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); + WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL); return OPERATOR_FINISHED; } @@ -745,5 +757,5 @@ void NODE_OT_select_same_type_prev(wmOperatorType *ot) ot->poll = ED_operator_node_active; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } diff --git a/source/blender/editors/space_node/node_state.c b/source/blender/editors/space_node/node_state.c deleted file mode 100644 index b21d31ad619..00000000000 --- a/source/blender/editors/space_node/node_state.c +++ /dev/null @@ -1,133 +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) 2008 Blender Foundation. - * All rights reserved. - * - * - * Contributor(s): Blender Foundation, Nathan Letwory - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_node/node_state.c - * \ingroup spnode - */ - - -#include <stdio.h> - -#include "DNA_node_types.h" -#include "DNA_scene_types.h" - -#include "BLI_rect.h" -#include "BLI_utildefines.h" - -#include "BKE_context.h" -#include "BKE_node.h" - -#include "ED_screen.h" - -#include "RNA_access.h" -#include "RNA_define.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "UI_view2d.h" - -#include "node_intern.h" - - -/* **************** View All Operator ************** */ - -static void snode_home(ScrArea *UNUSED(sa), ARegion *ar, SpaceNode* snode) -{ - bNode *node; - rctf *cur; - float oldwidth, oldheight, width, height; - int first= 1; - - cur= &ar->v2d.cur; - - oldwidth= cur->xmax - cur->xmin; - oldheight= cur->ymax - cur->ymin; - - cur->xmin = cur->ymin = 0.0f; - cur->xmax=ar->winx; - cur->ymax=ar->winy; - - if (snode->edittree) { - for (node= snode->edittree->nodes.first; node; node= node->next) { - if (first) { - first= 0; - ar->v2d.cur= node->totr; - } - else { - BLI_rctf_union(cur, &node->totr); - } - } - } - - snode->xof= 0; - snode->yof= 0; - width= cur->xmax - cur->xmin; - height= cur->ymax- cur->ymin; - - if (width > height) { - float newheight; - newheight= oldheight * width/oldwidth; - cur->ymin = cur->ymin - newheight/4; - cur->ymax = cur->ymax + newheight/4; - } - else { - float newwidth; - newwidth= oldwidth * height/oldheight; - cur->xmin = cur->xmin - newwidth/4; - cur->xmax = cur->xmax + newwidth/4; - } - - ar->v2d.tot= ar->v2d.cur; - UI_view2d_curRect_validate(&ar->v2d); -} - -static int node_view_all_exec(bContext *C, wmOperator *UNUSED(op)) -{ - ScrArea *sa= CTX_wm_area(C); - ARegion *ar= CTX_wm_region(C); - SpaceNode *snode= CTX_wm_space_node(C); - - snode_home(sa, ar, snode); - ED_region_tag_redraw(ar); - - return OPERATOR_FINISHED; -} - -void NODE_OT_view_all(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "View All"; - ot->idname = "NODE_OT_view_all"; - ot->description = "Resize view so you can see all nodes"; - - /* api callbacks */ - ot->exec = node_view_all_exec; - ot->poll = ED_operator_node_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; -} diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index f12c7941e1d..a8fe8318f22 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -24,41 +24,32 @@ * \ingroup edinterface */ -#include <stdlib.h> -#include <stddef.h> #include <string.h> #include "MEM_guardedalloc.h" #include "DNA_node_types.h" -#include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "BLI_listbase.h" #include "BLI_string.h" -#include "BLI_utildefines.h" #include "BLF_translation.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_library.h" #include "BKE_main.h" -#include "BKE_node.h" #include "BKE_scene.h" #include "RNA_access.h" #include "NOD_socket.h" -#include "WM_api.h" -#include "WM_types.h" - #include "UI_interface.h" -#include "UI_resources.h" -#include "../interface/interface_intern.h" +#include "../interface/interface_intern.h" /* XXX bad level */ + +#include "ED_node.h" /* own include */ -#include "ED_node.h" #include "ED_util.h" /************************* Node Socket Manipulation **************************/ diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c new file mode 100644 index 00000000000..248998a3a56 --- /dev/null +++ b/source/blender/editors/space_node/node_view.c @@ -0,0 +1,450 @@ +/* + * ***** 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, Nathan Letwory + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_node/node_view.c + * \ingroup spnode + */ + +#include "DNA_node_types.h" + +#include "BLI_rect.h" +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_image.h" +#include "BKE_screen.h" + +#include "ED_node.h" /* own include */ +#include "ED_screen.h" +#include "ED_space_api.h" +#include "ED_image.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "UI_view2d.h" + +#include "MEM_guardedalloc.h" + +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +#include "node_intern.h" /* own include */ + + +/* **************** View All Operator ************** */ + +static void snode_home(ScrArea *UNUSED(sa), ARegion *ar, SpaceNode *snode) +{ + bNode *node; + rctf *cur; + float oldwidth, oldheight, width, height; + int first = 1; + + cur = &ar->v2d.cur; + + oldwidth = cur->xmax - cur->xmin; + oldheight = cur->ymax - cur->ymin; + + cur->xmin = cur->ymin = 0.0f; + cur->xmax = ar->winx; + cur->ymax = ar->winy; + + if (snode->edittree) { + for (node = snode->edittree->nodes.first; node; node = node->next) { + if (first) { + first = 0; + ar->v2d.cur = node->totr; + } + else { + BLI_rctf_union(cur, &node->totr); + } + } + } + + snode->xof = 0; + snode->yof = 0; + width = cur->xmax - cur->xmin; + height = cur->ymax - cur->ymin; + + if (width > height) { + float newheight; + newheight = oldheight * width / oldwidth; + cur->ymin = cur->ymin - newheight / 4; + cur->ymax = cur->ymax + newheight / 4; + } + else { + float newwidth; + newwidth = oldwidth * height / oldheight; + cur->xmin = cur->xmin - newwidth / 4; + cur->xmax = cur->xmax + newwidth / 4; + } + + ar->v2d.tot = ar->v2d.cur; + UI_view2d_curRect_validate(&ar->v2d); +} + +static int node_view_all_exec(bContext *C, wmOperator *UNUSED(op)) +{ + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + SpaceNode *snode = CTX_wm_space_node(C); + + snode_home(sa, ar, snode); + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + +void NODE_OT_view_all(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "View All"; + ot->idname = "NODE_OT_view_all"; + ot->description = "Resize view so you can see all nodes"; + + /* api callbacks */ + ot->exec = node_view_all_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + + +/* **************** Backround Image Operators ************** */ + +typedef struct NodeViewMove { + int mvalo[2]; + int xmin, ymin, xmax, ymax; +} NodeViewMove; + +static int snode_bg_viewmove_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceNode *snode = CTX_wm_space_node(C); + ARegion *ar = CTX_wm_region(C); + NodeViewMove *nvm = op->customdata; + + switch (event->type) { + case MOUSEMOVE: + + snode->xof -= (nvm->mvalo[0] - event->mval[0]); + snode->yof -= (nvm->mvalo[1] - event->mval[1]); + nvm->mvalo[0] = event->mval[0]; + nvm->mvalo[1] = event->mval[1]; + + /* prevent dragging image outside of the window and losing it! */ + CLAMP(snode->xof, nvm->xmin, nvm->xmax); + CLAMP(snode->yof, nvm->ymin, nvm->ymax); + + ED_region_tag_redraw(ar); + + break; + + case LEFTMOUSE: + case MIDDLEMOUSE: + case RIGHTMOUSE: + + MEM_freeN(nvm); + op->customdata = NULL; + + return OPERATOR_FINISHED; + } + + return OPERATOR_RUNNING_MODAL; +} + +static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceNode *snode = CTX_wm_space_node(C); + ARegion *ar = CTX_wm_region(C); + NodeViewMove *nvm; + Image *ima; + ImBuf *ibuf; + const float pad = 32.0f; /* better be bigger then scrollbars */ + + void *lock; + + ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); + ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); + + if (ibuf == NULL) { + BKE_image_release_ibuf(ima, lock); + return OPERATOR_CANCELLED; + } + + nvm = MEM_callocN(sizeof(NodeViewMove), "NodeViewMove struct"); + op->customdata = nvm; + nvm->mvalo[0] = event->mval[0]; + nvm->mvalo[1] = event->mval[1]; + + nvm->xmin = -(ar->winx / 2) - (ibuf->x * (0.5f * snode->zoom)) + pad; + nvm->xmax = (ar->winx / 2) + (ibuf->x * (0.5f * snode->zoom)) - pad; + nvm->ymin = -(ar->winy / 2) - (ibuf->y * (0.5f * snode->zoom)) + pad; + nvm->ymax = (ar->winy / 2) + (ibuf->y * (0.5f * snode->zoom)) - pad; + + BKE_image_release_ibuf(ima, lock); + + /* add modal handler */ + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int 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) +{ + /* identifiers */ + ot->name = "Background Image Move"; + ot->description = "Move Node backdrop"; + ot->idname = "NODE_OT_backimage_move"; + + /* api callbacks */ + ot->invoke = snode_bg_viewmove_invoke; + ot->modal = snode_bg_viewmove_modal; + ot->poll = composite_node_active; + ot->cancel = snode_bg_viewmove_cancel; + + /* flags */ + ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER; +} + +static int backimage_zoom(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + ARegion *ar = CTX_wm_region(C); + float fac = RNA_float_get(op->ptr, "factor"); + + snode->zoom *= fac; + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + + +void NODE_OT_backimage_zoom(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name = "Background Image Zoom"; + ot->idname = "NODE_OT_backimage_zoom"; + ot->description = "Zoom in/out the background image"; + + /* api callbacks */ + ot->exec = backimage_zoom; + ot->poll = composite_node_active; + + /* flags */ + ot->flag = OPTYPE_BLOCKING; + + /* internal */ + RNA_def_float(ot->srna, "factor", 1.2f, 0.0f, 10.0f, "Factor", "", 0.0f, 10.0f); +} + +/******************** sample backdrop operator ********************/ + +typedef struct ImageSampleInfo { + ARegionType *art; + void *draw_handle; + int x, y; + int channels; + int color_manage; + + unsigned char col[4]; + float colf[4]; + + int draw; +} ImageSampleInfo; + +static void sample_draw(const bContext *C, ARegion *ar, void *arg_info) +{ + Scene *scene = CTX_data_scene(C); + ImageSampleInfo *info = arg_info; + + if (info->draw) { + ED_image_draw_info(ar, (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT), info->channels, + info->x, info->y, info->col, info->colf, + NULL, NULL /* zbuf - unused for nodes */ + ); + } +} + +static void sample_apply(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceNode *snode = CTX_wm_space_node(C); + ARegion *ar = CTX_wm_region(C); + ImageSampleInfo *info = op->customdata; + void *lock; + Image *ima; + ImBuf *ibuf; + float fx, fy, bufx, bufy; + + ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); + ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); + if (!ibuf) { + info->draw = 0; + return; + } + + if (!ibuf->rect) { + if (info->color_manage) + ibuf->profile = IB_PROFILE_LINEAR_RGB; + else + ibuf->profile = IB_PROFILE_NONE; + IMB_rect_from_float(ibuf); + } + + /* map the mouse coords to the backdrop image space */ + bufx = ibuf->x * snode->zoom; + bufy = ibuf->y * snode->zoom; + fx = (bufx > 0.0f ? ((float)event->mval[0] - 0.5f * ar->winx - snode->xof) / bufx + 0.5f : 0.0f); + fy = (bufy > 0.0f ? ((float)event->mval[1] - 0.5f * ar->winy - snode->yof) / bufy + 0.5f : 0.0f); + + if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) { + float *fp; + char *cp; + int x = (int)(fx * ibuf->x), y = (int)(fy * ibuf->y); + + CLAMP(x, 0, ibuf->x - 1); + CLAMP(y, 0, ibuf->y - 1); + + info->x = x; + info->y = y; + info->draw = 1; + info->channels = ibuf->channels; + + if (ibuf->rect) { + cp = (char *)(ibuf->rect + y * ibuf->x + x); + + info->col[0] = cp[0]; + info->col[1] = cp[1]; + info->col[2] = cp[2]; + info->col[3] = cp[3]; + + info->colf[0] = (float)cp[0] / 255.0f; + info->colf[1] = (float)cp[1] / 255.0f; + info->colf[2] = (float)cp[2] / 255.0f; + info->colf[3] = (float)cp[3] / 255.0f; + } + if (ibuf->rect_float) { + fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x)); + + info->colf[0] = fp[0]; + info->colf[1] = fp[1]; + info->colf[2] = fp[2]; + info->colf[3] = fp[3]; + } + + ED_node_sample_set(info->colf); + } + else { + info->draw = 0; + ED_node_sample_set(NULL); + } + + BKE_image_release_ibuf(ima, lock); + + ED_area_tag_redraw(CTX_wm_area(C)); +} + +static void sample_exit(bContext *C, wmOperator *op) +{ + ImageSampleInfo *info = op->customdata; + + ED_node_sample_set(NULL); + ED_region_draw_cb_exit(info->art, info->draw_handle); + ED_area_tag_redraw(CTX_wm_area(C)); + MEM_freeN(info); +} + +static int sample_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceNode *snode = CTX_wm_space_node(C); + ARegion *ar = CTX_wm_region(C); + ImageSampleInfo *info; + + if (snode->treetype != NTREE_COMPOSIT || !(snode->flag & SNODE_BACKDRAW)) + return OPERATOR_CANCELLED; + + info = MEM_callocN(sizeof(ImageSampleInfo), "ImageSampleInfo"); + info->art = ar->type; + info->draw_handle = ED_region_draw_cb_activate(ar->type, sample_draw, info, REGION_DRAW_POST_PIXEL); + op->customdata = info; + + sample_apply(C, op, event); + + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int sample_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + switch (event->type) { + case LEFTMOUSE: + case RIGHTMOUSE: // XXX hardcoded + sample_exit(C, op); + return OPERATOR_CANCELLED; + case MOUSEMOVE: + sample_apply(C, op, event); + break; + } + + return OPERATOR_RUNNING_MODAL; +} + +static int sample_cancel(bContext *C, wmOperator *op) +{ + sample_exit(C, op); + return OPERATOR_CANCELLED; +} + +void NODE_OT_backimage_sample(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Backimage Sample"; + ot->idname = "NODE_OT_backimage_sample"; + ot->description = "Use mouse to sample background image"; + + /* api callbacks */ + ot->invoke = sample_invoke; + ot->modal = sample_modal; + ot->cancel = sample_cancel; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_BLOCKING; +} diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index ce187c46625..a79bfe39257 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -29,31 +29,24 @@ */ -#include <string.h> -#include <stdio.h> #include "DNA_lamp_types.h" #include "DNA_material_types.h" #include "DNA_node_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" #include "DNA_world_types.h" #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLI_rand.h" -#include "BLI_utildefines.h" #include "BKE_context.h" #include "BKE_screen.h" #include "BKE_node.h" -#include "ED_space_api.h" #include "ED_render.h" #include "ED_screen.h" - +#include "ED_node.h" #include "WM_api.h" #include "WM_types.h" @@ -63,7 +56,7 @@ #include "RNA_access.h" -#include "node_intern.h" // own include +#include "node_intern.h" /* own include */ /* ******************** manage regions ********************* */ @@ -263,7 +256,7 @@ static void node_area_listener(ScrArea *sa, wmNotifier *wmn) } } -static void node_area_refresh(const struct bContext *C, struct ScrArea *sa) +static void node_area_refresh(const struct bContext *C, ScrArea *sa) { /* default now: refresh node is starting preview */ SpaceNode *snode = sa->spacedata.first; @@ -296,8 +289,9 @@ static void node_area_refresh(const struct bContext *C, struct ScrArea *sa) snode->recalc = 0; node_render_changed_exec((struct bContext *)C, NULL); } - else - snode_composite_job(C, sa); + else { + ED_node_composite_job(C, snode->nodetree, scene); + } } } else if (snode->treetype == NTREE_TEXTURE) { diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 3d01de1c67a..bf76fdda61e 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -324,6 +324,14 @@ static void id_fake_user_clear_cb(bContext *UNUSED(C), Scene *UNUSED(scene), Tre } } +static void id_select_linked_cb(bContext *C, Scene *UNUSED(scene), TreeElement *UNUSED(te), + TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) +{ + ID *id = tselem->id; + + ED_object_select_linked_by_id(C, id); +} + static void singleuser_action_cb(bContext *C, Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *tsep, TreeStoreElem *tselem) { @@ -522,6 +530,18 @@ static void sequence_cb(int event, TreeElement *te, TreeStoreElem *tselem, void (void)tselem; } +static void data_select_linked_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *C_v) +{ + if (event == 5) { + if (RNA_struct_is_ID(te->rnaptr.type)) { + bContext *C = (bContext *) C_v; + ID *id = te->rnaptr.data; + + ED_object_select_linked_by_id(C, id); + } + } +} + static void outliner_do_data_operation(SpaceOops *soops, int type, int event, ListBase *lb, void (*operation_cb)(int, TreeElement *, TreeStoreElem *, void *), void *arg) @@ -728,7 +748,9 @@ typedef enum eOutlinerIdOpTypes { OUTLINER_IDOP_FAKE_ADD, OUTLINER_IDOP_FAKE_CLEAR, - OUTLINER_IDOP_RENAME + OUTLINER_IDOP_RENAME, + + OUTLINER_IDOP_SELECT_LINKED } eOutlinerIdOpTypes; // TODO: implement support for changing the ID-block used @@ -740,6 +762,7 @@ static EnumPropertyItem prop_id_op_types[] = { "Ensure datablock gets saved even if it isn't in use (e.g. for motion and material libraries)"}, {OUTLINER_IDOP_FAKE_CLEAR, "CLEAR_FAKE", 0, "Clear Fake User", ""}, {OUTLINER_IDOP_RENAME, "RENAME", 0, "Rename", ""}, + {OUTLINER_IDOP_SELECT_LINKED, "SELECT_LINKED", 0, "Select Linked", ""}, {0, NULL, 0, NULL, NULL} }; @@ -855,6 +878,11 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) ED_undo_push(C, "Rename"); } break; + + case OUTLINER_IDOP_SELECT_LINKED: + outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_select_linked_cb); + ED_undo_push(C, "Select"); + break; default: // invalid - unhandled @@ -1115,6 +1143,7 @@ static EnumPropertyItem prop_data_op_types[] = { {2, "DESELECT", 0, "Deselect", ""}, {3, "HIDE", 0, "Hide", ""}, {4, "UNHIDE", 0, "Unhide", ""}, + {5, "SELECT_LINKED", 0, "Select Linked", ""}, {0, NULL, 0, NULL, NULL} }; @@ -1158,6 +1187,11 @@ static int outliner_data_operation_exec(bContext *C, wmOperator *op) outliner_do_data_operation(soops, datalevel, event, &soops->tree, sequence_cb, scene); } } + else if (datalevel == TSE_RNA_STRUCT) { + if (event == 5) { + outliner_do_data_operation(soops, datalevel, event, &soops->tree, data_select_linked_cb, C); + } + } return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 26bedd14d6e..c52f4ca629a 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -613,7 +613,8 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); RNA_def_boolean(ot->srna, "sound", TRUE, "Sound", "Load sound with the movie"); } @@ -667,7 +668,8 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory"); } @@ -772,7 +774,8 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_ENDFRAME); } @@ -928,7 +931,8 @@ void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_ENDFRAME); RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_TYPE_CROSS, "Type", "Sequencer effect type"); RNA_def_float_vector(ot->srna, "color", 3, NULL, 0.0f, 1.0f, "Color", "Initialize the strip with this color (only used when type='COLOR')", 0.0f, 1.0f); diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 38f29e8816e..9cbb9006187 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -990,55 +990,28 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq /* draw grease-pencil (screen aligned) */ draw_gpencil_view2d(C, 0); - //if (sc->mode == SC_MODE_MASKEDIT) { - if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { - Sequence *seq_act = BKE_sequencer_active_get(scene); - - if (seq_act && seq_act->type == SEQ_TYPE_MASK && seq_act->mask) { - int x, y; - int width, height; - float zoomx, zoomy; - - /* frame image */ - float maxdim; - float xofs, yofs; - - /* find window pixel coordinates of origin */ - UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y); - - width = v2d->tot.xmax - v2d->tot.xmin; - height = v2d->tot.ymax - v2d->tot.ymin; - zoomx = (float)(ar->winrct.xmax - ar->winrct.xmin + 1) / (float)((ar->v2d.cur.xmax - ar->v2d.cur.xmin)); - zoomy = (float)(ar->winrct.ymax - ar->winrct.ymin + 1) / (float)((ar->v2d.cur.ymax - ar->v2d.cur.ymin)); - x += v2d->tot.xmin * zoomx; - y += v2d->tot.ymin * zoomy; + /* NOTE: sequencer mask editing isnt finished, the draw code is working but editing not, + * for now just disable drawing since the strip frame will likely be offset */ - /* frame the image */ - maxdim = maxf(width, height); - if (width == height) { - xofs = yofs = 0; - } - else if (width < height) { - xofs = ((height - width) / -2.0f) * zoomx; - yofs = 0.0f; - } - else { /* (width > height) */ - xofs = 0.0f; - yofs = ((width - height) / -2.0f) * zoomy; - } - - /* apply transformation so mask editing tools will assume drawing from the origin in normalized space */ - glPushMatrix(); - glTranslatef(x + xofs, y + yofs, 0); - glScalef(maxdim * zoomx, maxdim * zoomy, 0); + //if (sc->mode == SC_MODE_MASKEDIT) { + if (0 && sseq->mainb == SEQ_DRAW_IMG_IMBUF) { + Mask *mask = BKE_sequencer_mask_get(scene); - ED_mask_draw((bContext *)C, 0, 0); // sc->mask_draw_flag, sc->mask_draw_type + if (mask) { + int width, height; + // ED_mask_get_size(C, &width, &height); - ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); + //Scene *scene = CTX_data_scene(C); + width = (scene->r.size * scene->r.xsch) / 100; + height = (scene->r.size * scene->r.ysch) / 100; - glPopMatrix(); + ED_mask_draw_region(mask, ar, + 0, 0, /* TODO */ + width, height, + FALSE, TRUE, + NULL, C); } } @@ -1081,7 +1054,7 @@ static void draw_seq_backdrop(View2D *v2d) glRectf(v2d->cur.xmin, -1.0, v2d->cur.xmax, 1.0); /* Alternating horizontal stripes */ - i = MAX2(1, ((int)v2d->cur.ymin) - 1); + i = maxi(1, ((int)v2d->cur.ymin) - 1); glBegin(GL_QUADS); while (i < v2d->cur.ymax) { @@ -1100,7 +1073,7 @@ static void draw_seq_backdrop(View2D *v2d) glEnd(); /* Darker lines separating the horizontal bands */ - i = MAX2(1, ((int)v2d->cur.ymin) - 1); + i = maxi(1, ((int)v2d->cur.ymin) - 1); UI_ThemeColor(TH_GRID); glBegin(GL_LINES); diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 82e2730c59e..16a83cbcc9e 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -466,6 +466,33 @@ void recurs_sel_seq(Sequence *seqm) } } +int ED_space_sequencer_maskedit_mask_poll(bContext *C) +{ + /* in this case both funcs are the same, for clip editor not */ + return ED_space_sequencer_maskedit_poll(C); +} + +int ED_space_sequencer_check_show_maskedit(SpaceSeq *sseq, Scene *scene) +{ + if (sseq && sseq->mainb == SEQ_DRAW_IMG_IMBUF) { + return (BKE_sequencer_mask_get(scene) != NULL); + } + + return FALSE; +} + +int ED_space_sequencer_maskedit_poll(bContext *C) +{ + SpaceSeq *sseq = CTX_wm_space_seq(C); + + if (sseq) { + Scene *scene = CTX_data_scene(C); + return ED_space_sequencer_check_show_maskedit(sseq, scene); + } + + return FALSE; +} + int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequence **selseq1, Sequence **selseq2, Sequence **selseq3, const char **error_str) { Editing *ed = BKE_sequencer_editing_get(scene, FALSE); @@ -2084,7 +2111,7 @@ static int sequencer_view_all_preview_exec(bContext *C, wmOperator *UNUSED(op)) zoomY = ((float)height) / ((float)imgheight); sseq->zoom = (zoomX < zoomY) ? zoomX : zoomY; - sseq->zoom = 1.0f / power_of_2(1 / MIN2(zoomX, zoomY) ); + sseq->zoom = 1.0f / power_of_2(1 / minf(zoomX, zoomY)); } else { sseq->zoom = 1.0f; @@ -2113,13 +2140,13 @@ void SEQUENCER_OT_view_all_preview(wmOperatorType *ot) static int sequencer_view_zoom_ratio_exec(bContext *C, wmOperator *op) { - RenderData *r = &CTX_data_scene(C)->r; + RenderData *rd = &CTX_data_scene(C)->r; View2D *v2d = UI_view2d_fromcontext(C); float ratio = RNA_float_get(op->ptr, "ratio"); - float winx = (int)(r->size * r->xsch) / 100; - float winy = (int)(r->size * r->ysch) / 100; + float winx = (int)(rd->size * rd->xsch) / 100; + float winy = (int)(rd->size * rd->ysch) / 100; float facx = (v2d->mask.xmax - v2d->mask.xmin) / winx; float facy = (v2d->mask.ymax - v2d->mask.ymin) / winy; @@ -3047,6 +3074,8 @@ void SEQUENCER_OT_change_path(struct wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILEPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILEPATH | WM_FILESEL_FILES, + FILE_DEFAULTDISPLAY); } diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index cabc761161e..34ca26a3176 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -300,7 +300,10 @@ static void sequencer_main_area_init(wmWindowManager *wm, ARegion *ar) ListBase *lb; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); - + +// keymap = WM_keymap_find(wm->defaultconf, "Mask Editing", 0, 0); +// WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); + keymap = WM_keymap_find(wm->defaultconf, "SequencerCommon", SPACE_SEQ, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); @@ -409,9 +412,9 @@ static int sequencer_context(const bContext *C, const char *member, bContextData return TRUE; } else if (CTX_data_equals(member, "edit_mask")) { - Sequence *seq_act = BKE_sequencer_active_get(scene); - if (seq_act && seq_act->type == SEQ_TYPE_MASK && seq_act->mask) { - CTX_data_id_pointer_set(result, &seq_act->mask->id); + Mask *mask = BKE_sequencer_mask_get(scene); + if (mask) { + CTX_data_id_pointer_set(result, &mask->id); } return TRUE; } @@ -468,6 +471,9 @@ static void sequencer_preview_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); +// keymap = WM_keymap_find(wm->defaultconf, "Mask Editing", 0, 0); +// WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); + keymap = WM_keymap_find(wm->defaultconf, "SequencerCommon", SPACE_SEQ, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index 8be5b644afb..6240d174575 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -50,7 +50,6 @@ #include "BKE_suggestions.h" #include "BKE_text.h" - #include "BIF_gl.h" #include "ED_datafiles.h" @@ -1854,7 +1853,7 @@ void draw_text_main(SpaceText *st, ARegion *ar) /* draw other stuff */ draw_brackets(st, ar); draw_markers(st, ar); - glTranslatef(0.375f, 0.375f, 0.0f); /* XXX scroll requires exact pixel space */ + glTranslatef(GLA_PIXEL_OFS, GLA_PIXEL_OFS, 0.0f); /* XXX scroll requires exact pixel space */ draw_textscroll(st, &scroll, &back); draw_documentation(st, ar); draw_suggestion_list(st, ar); diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 1eba2deed96..df90ce24dda 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -310,7 +310,8 @@ void TEXT_OT_open(wmOperatorType *ot) ot->flag = OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE | TEXTFILE | PYSCRIPTFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); //XXX TODO, relative_path + WM_operator_properties_filesel(ot, FOLDERFILE | TEXTFILE | PYSCRIPTFILE, FILE_SPECIAL, FILE_OPENFILE, + WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); //XXX TODO, relative_path RNA_def_boolean(ot->srna, "internal", 0, "Make internal", "Make text file internal after loading"); } @@ -570,7 +571,8 @@ void TEXT_OT_save_as(wmOperatorType *ot) ot->poll = text_edit_poll; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE | TEXTFILE | PYSCRIPTFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); //XXX TODO, relative_path + WM_operator_properties_filesel(ot, FOLDERFILE | TEXTFILE | PYSCRIPTFILE, FILE_SPECIAL, FILE_SAVE, + WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); //XXX TODO, relative_path } /******************* run script operator *********************/ diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index 48b3672c144..a05bc5eddc7 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -171,7 +171,7 @@ static short set_pchan_glColor(short colCode, int boneflag, short constflag) } else { if ((boneflag & BONE_DRAW_ACTIVE) && (boneflag & BONE_SELECTED)) { - UI_ThemeColorShade(TH_BONE_POSE, 40); + UI_ThemeColor(TH_BONE_POSE_ACTIVE); } else if (boneflag & BONE_DRAW_ACTIVE) { UI_ThemeColorBlend(TH_WIRE, TH_BONE_POSE, 0.15f); /* unselected active */ diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 3c88c99b2f0..d3fe05266f8 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -849,7 +849,7 @@ void view3d_cached_text_draw_add(const float co[3], BLI_addtail(strings, vos); copy_v3_v3(vos->vec, co); - vos->col.pack = *((int *)col); + copy_v4_v4_char((char *)vos->col.ub, (const char *)col); vos->xoffs = xoffs; vos->flag = flag; vos->str_len = alloc_len - 1; @@ -4287,7 +4287,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv ParticleDrawData *pdd = psys->pdd; Material *ma; float vel[3], imat[4][4]; - float timestep, pixsize_scale, pa_size, r_tilt, r_length; + float timestep, pixsize_scale = 1.0f, pa_size, r_tilt, r_length; float pa_time, pa_birthtime, pa_dietime, pa_health, intensity; float cfra; float ma_col[3] = {0.0f, 0.0f, 0.0f}; @@ -6442,14 +6442,12 @@ static void draw_hooks(Object *ob) } } -static void draw_rigid_body_pivot(bRigidBodyJointConstraint *data, const unsigned char ob_wire_col[4]) +static void draw_rigid_body_pivot(bRigidBodyJointConstraint *data, const short dflag, unsigned char ob_wire_col[4]) { const char *axis_str[3] = {"px", "py", "pz"}; int axis; float mat[4][4]; - /* color */ - eul_to_mat4(mat, &data->axX); glLineWidth(4.0f); setlinestyle(2); @@ -6459,7 +6457,7 @@ static void draw_rigid_body_pivot(bRigidBodyJointConstraint *data, const unsigne copy_v3_v3(v, &data->pivX); - dir[axis] = 1.f; + dir[axis] = 1.0f; glBegin(GL_LINES); mul_m4_v3(mat, dir); add_v3_v3(v, dir); @@ -6467,7 +6465,11 @@ static void draw_rigid_body_pivot(bRigidBodyJointConstraint *data, const unsigne glVertex3fv(v); glEnd(); - view3d_cached_text_draw_add(v, axis_str[axis], 0, V3D_CACHE_TEXT_ASCII, ob_wire_col); + /* when const color is set wirecolor is NULL - we could get the current color but + * with selection and group instancing its not needed to draw the text */ + if ((dflag & DRAW_CONSTCOLOR) == 0) { + view3d_cached_text_draw_add(v, axis_str[axis], 0, V3D_CACHE_TEXT_ASCII, ob_wire_col); + } } glLineWidth(1.0f); setlinestyle(0); @@ -6682,8 +6684,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short /* 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)) { - + if (!(ob->dtx & OB_DRAWWIRE) && (ob->flag & SELECT) && !(dflag & (DRAW_PICKING | DRAW_CONSTCOLOR))) { drawObjectSelect(scene, v3d, ar, base, ob_wire_col); } } @@ -7070,7 +7071,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short if (con->type == CONSTRAINT_TYPE_RIGIDBODYJOINT) { bRigidBodyJointConstraint *data = (bRigidBodyJointConstraint *)con->data; if (data->flag & CONSTRAINT_DRAW_PIVOT) - draw_rigid_body_pivot(data, ob_wire_col); + draw_rigid_body_pivot(data, dflag, ob_wire_col); } } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 88d08d937be..1e371cb074d 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -984,7 +984,7 @@ static void view3d_props_area_listener(ARegion *ar, wmNotifier *wmn) } /*area (not region) level listener*/ -static void space_view3d_listener(struct ScrArea *sa, struct wmNotifier *wmn) +static void space_view3d_listener(ScrArea *sa, struct wmNotifier *wmn) { View3D *v3d = sa->spacedata.first; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 1dbc40a0c07..85a4d911df5 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1716,7 +1716,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, /* for some reason; zoomlevels down refuses to use GL_ALPHA_SCALE */ if (zoomx < 1.0f || zoomy < 1.0f) { - float tzoom = MIN2(zoomx, zoomy); + float tzoom = minf(zoomx, zoomy); int mip = 0; if ((ibuf->userflags & IB_MIPMAP_INVALID) != 0) { @@ -1779,8 +1779,12 @@ static void view3d_draw_bgpic_test(Scene *scene, ARegion *ar, View3D *v3d, if ((v3d->flag & V3D_DISPBGPICS) == 0) return; + /* disabled - mango request, since footage /w only render is quite useful + * and this option is easy to disable all background images at once */ +#if 0 if (v3d->flag2 & V3D_RENDER_OVERRIDE) return; +#endif if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) { if (rv3d->persp == RV3D_CAMOB) { diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 97123767211..ba665cfb89c 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2435,7 +2435,7 @@ static int view3d_center_camera_exec(bContext *C, wmOperator *UNUSED(op)) /* was xfac = (float)ar->winx / (float)(size[0] + 4); yfac = (float)ar->winy / (float)(size[1] + 4); - rv3d->camzoom = BKE_screen_view3d_zoom_from_fac(MIN2(xfac, yfac)); + rv3d->camzoom = BKE_screen_view3d_zoom_from_fac(minf(xfac, yfac)); CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); @@ -2873,7 +2873,7 @@ static int viewnumpad_exec(bContext *C, wmOperator *op) break; case RV3D_VIEW_BACK: - axis_set_view(C, v3d, ar, 0.0, 0.0, -cosf(M_PI / 4.0), -cosf(M_PI / 4.0), + axis_set_view(C, v3d, ar, 0.0, 0.0, -M_SQRT1_2, -M_SQRT1_2, viewnum, nextperspo, align_active); break; @@ -2888,7 +2888,7 @@ static int viewnumpad_exec(bContext *C, wmOperator *op) break; case RV3D_VIEW_FRONT: - axis_set_view(C, v3d, ar, cosf(M_PI / 4.0), -sinf(M_PI / 4.0), 0.0, 0.0, + axis_set_view(C, v3d, ar, M_SQRT1_2, -M_SQRT1_2, 0.0, 0.0, viewnum, nextperspo, align_active); break; @@ -3008,7 +3008,6 @@ static int vieworbit_exec(bContext *C, wmOperator *op) View3D *v3d; ARegion *ar; RegionView3D *rv3d; - float phi, q1[4], new_quat[4]; int orbitdir; /* no NULL check is needed, poll checks */ @@ -3019,36 +3018,40 @@ static int vieworbit_exec(bContext *C, wmOperator *op) if (rv3d->viewlock == 0) { if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) { - if (orbitdir == V3D_VIEW_STEPLEFT || orbitdir == V3D_VIEW_STEPRIGHT) { - float si; + float angle = DEG2RADF((float)U.pad_rot_angle); + float quat_mul[4]; + float quat_new[4]; + + if (ELEM(orbitdir, V3D_VIEW_STEPLEFT, V3D_VIEW_STEPRIGHT)) { + const float zvec[3] = {0.0f, 0.0f, 1.0f}; + + if (orbitdir == V3D_VIEW_STEPRIGHT) { + angle = -angle; + } + /* z-axis */ - phi = (float)(M_PI / 360.0) * U.pad_rot_angle; - if (orbitdir == V3D_VIEW_STEPRIGHT) phi = -phi; - si = (float)sin(phi); - q1[0] = (float)cos(phi); - q1[1] = q1[2] = 0.0; - q1[3] = si; - mul_qt_qtqt(new_quat, rv3d->viewquat, q1); - rv3d->view = RV3D_VIEW_USER; + axis_angle_to_quat(quat_mul, zvec, angle); } - else if (orbitdir == V3D_VIEW_STEPDOWN || orbitdir == V3D_VIEW_STEPUP) { + else { + + if (orbitdir == V3D_VIEW_STEPDOWN) { + angle = -angle; + } + /* horizontal axis */ - copy_v3_v3(q1 + 1, rv3d->viewinv[0]); - - normalize_v3(q1 + 1); - phi = (float)(M_PI / 360.0) * U.pad_rot_angle; - if (orbitdir == V3D_VIEW_STEPDOWN) phi = -phi; - q1[0] = (float)cos(phi); - mul_v3_fl(q1 + 1, sin(phi)); - mul_qt_qtqt(new_quat, rv3d->viewquat, q1); - rv3d->view = RV3D_VIEW_USER; + axis_angle_to_quat(quat_mul, rv3d->viewinv[0], angle); } - smooth_view(C, CTX_wm_view3d(C), ar, NULL, NULL, NULL, new_quat, NULL, NULL); + mul_qt_qtqt(quat_new, rv3d->viewquat, quat_mul); + rv3d->view = RV3D_VIEW_USER; + + smooth_view(C, CTX_wm_view3d(C), ar, NULL, NULL, NULL, quat_new, NULL, NULL); + + return OPERATOR_FINISHED; } } - return OPERATOR_FINISHED; + return OPERATOR_CANCELLED; } void VIEW3D_OT_view_orbit(wmOperatorType *ot) @@ -3645,7 +3648,7 @@ int ED_view3d_autodist_simple(ARegion *ar, const int mval[2], float mouse_worldl return 1; } -int ED_view3d_autodist_depth(struct ARegion *ar, const int mval[2], int margin, float *depth) +int ED_view3d_autodist_depth(ARegion *ar, const int mval[2], int margin, float *depth) { *depth = view_autodist_depth_margin(ar, mval, margin); @@ -3654,7 +3657,7 @@ int ED_view3d_autodist_depth(struct ARegion *ar, const int mval[2], int margin, static int depth_segment_cb(int x, int y, void *userData) { - struct { struct ARegion *ar; int margin; float depth; } *data = userData; + struct { ARegion *ar; int margin; float depth; } *data = userData; int mval[2]; float depth; @@ -3672,10 +3675,10 @@ static int depth_segment_cb(int x, int y, void *userData) } } -int ED_view3d_autodist_depth_seg(struct ARegion *ar, const int mval_sta[2], const int mval_end[2], +int ED_view3d_autodist_depth_seg(ARegion *ar, const int mval_sta[2], const int mval_end[2], int margin, float *depth) { - struct { struct ARegion *ar; int margin; float depth; } data = {NULL}; + struct { ARegion *ar; int margin; float depth; } data = {NULL}; int p1[2]; int p2[2]; diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index 15e32ea2de4..561e97a8393 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -219,7 +219,7 @@ typedef struct FlyInfo { } FlyInfo; -static void drawFlyPixel(const struct bContext *UNUSED(C), struct ARegion *UNUSED(ar), void *arg) +static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg) { FlyInfo *fly = arg; @@ -549,7 +549,7 @@ static void flyEvent(FlyInfo *fly, wmEvent *event) time_wheel = (float)(time_currwheel - fly->time_lastwheel); fly->time_lastwheel = time_currwheel; /* Mouse wheel delays range from (0.5 == slow) to (0.01 == fast) */ - time_wheel = 1.0f + (10.0f - (20.0f * MIN2(time_wheel, 0.5f))); /* 0-0.5 -> 0-5.0 */ + time_wheel = 1.0f + (10.0f - (20.0f * minf(time_wheel, 0.5f))); /* 0-0.5 -> 0-5.0 */ if (fly->speed < 0.0f) { fly->speed = 0.0f; @@ -567,7 +567,7 @@ static void flyEvent(FlyInfo *fly, wmEvent *event) time_currwheel = PIL_check_seconds_timer(); time_wheel = (float)(time_currwheel - fly->time_lastwheel); fly->time_lastwheel = time_currwheel; - time_wheel = 1.0f + (10.0f - (20.0f * MIN2(time_wheel, 0.5f))); /* 0-0.5 -> 0-5.0 */ + time_wheel = 1.0f + (10.0f - (20.0f * minf(time_wheel, 0.5f))); /* 0-0.5 -> 0-5.0 */ if (fly->speed > 0.0f) { fly->speed = 0; @@ -843,7 +843,7 @@ static int flyApply(bContext *C, FlyInfo *fly) #endif time_current = PIL_check_seconds_timer(); time_redraw = (float)(time_current - fly->time_lastdraw); - time_redraw_clamped = MIN2(0.05f, time_redraw); /* clamp redraw time to avoid jitter in roll correction */ + time_redraw_clamped = minf(0.05f, time_redraw); /* clamp redraw time to avoid jitter in roll correction */ fly->time_lastdraw = time_current; /* Scale the time to use shift to scale the speed down- just like diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 3abfda78ec3..f9776855d61 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1125,7 +1125,7 @@ int ED_view3d_lock(RegionView3D *rv3d) break; case RV3D_VIEW_BACK: - QUATSET(rv3d->viewquat, 0.0, 0.0, -cosf(M_PI / 4.0), -cosf(M_PI / 4.0)); + QUATSET(rv3d->viewquat, 0.0, 0.0, -M_SQRT1_2, -M_SQRT1_2); break; case RV3D_VIEW_LEFT: @@ -1137,7 +1137,7 @@ int ED_view3d_lock(RegionView3D *rv3d) break; case RV3D_VIEW_FRONT: - QUATSET(rv3d->viewquat, (float)cos(M_PI / 4.0), -sinf(M_PI / 4.0), 0.0, 0.0); + QUATSET(rv3d->viewquat, M_SQRT1_2, -M_SQRT1_2, 0.0, 0.0); break; case RV3D_VIEW_RIGHT: diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 6aee12c4b41..acda6c3d399 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -74,6 +74,7 @@ #include "ED_view3d.h" #include "ED_mesh.h" #include "ED_clip.h" +#include "ED_mask.h" #include "UI_view2d.h" #include "WM_types.h" @@ -93,7 +94,7 @@ #include <stdio.h> -static void drawTransformApply(const struct bContext *C, struct ARegion *ar, void *arg); +static void drawTransformApply(const struct bContext *C, ARegion *ar, void *arg); static int doEdgeSlide(TransInfo *t, float perc); /* ************************** SPACE DEPENDANT CODE **************************** */ @@ -120,16 +121,44 @@ void setTransformViewMatrices(TransInfo *t) calculateCenter2D(t); } -static void convertViewVec2D(View2D *v2d, float vec[3], int dx, int dy) +static void convertViewVec2D(View2D *v2d, float r_vec[3], int dx, int dy) { float divx, divy; divx = v2d->mask.xmax - v2d->mask.xmin; divy = v2d->mask.ymax - v2d->mask.ymin; - vec[0] = (v2d->cur.xmax - v2d->cur.xmin) * dx / divx; - vec[1] = (v2d->cur.ymax - v2d->cur.ymin) * dy / divy; - vec[2] = 0.0f; + r_vec[0] = (v2d->cur.xmax - v2d->cur.xmin) * dx / divx; + r_vec[1] = (v2d->cur.ymax - v2d->cur.ymin) * dy / divy; + r_vec[2] = 0.0f; +} + +static void convertViewVec2D_mask(View2D *v2d, float r_vec[3], int dx, int dy) +{ + float divx, divy; + float mulx, muly; + + divx = v2d->mask.xmax - v2d->mask.xmin; + divy = v2d->mask.ymax - v2d->mask.ymin; + + mulx = (v2d->cur.xmax - v2d->cur.xmin); + muly = (v2d->cur.ymax - v2d->cur.ymin); + + /* difference with convertViewVec2D */ + /* clamp w/h, mask only */ + if (mulx / divx < muly / divy) { + divy = divx; + muly = mulx; + } + else { + divx = divy; + mulx = muly; + } + /* end difference */ + + r_vec[0] = mulx * dx / divx; + r_vec[1] = muly * dy / divy; + r_vec[2] = 0.0f; } void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) @@ -143,9 +172,16 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) else if (t->spacetype == SPACE_IMAGE) { float aspx, aspy; - convertViewVec2D(t->view, r_vec, dx, dy); + if (t->options & CTX_MASK) { + + convertViewVec2D_mask(t->view, r_vec, dx, dy); + ED_space_image_get_aspect(t->sa->spacedata.first, &aspx, &aspy); + } + else { + convertViewVec2D(t->view, r_vec, dx, dy); + ED_space_image_get_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); + } - ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); r_vec[0] *= aspx; r_vec[1] *= aspy; } @@ -156,32 +192,14 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) convertViewVec2D(&t->ar->v2d, r_vec, dx, dy); } else if (t->spacetype == SPACE_CLIP) { - View2D *v2d = t->view; - float divx, divy; - float mulx, muly; - float aspx = 1.0f, aspy = 1.0f; - - divx = v2d->mask.xmax - v2d->mask.xmin; - divy = v2d->mask.ymax - v2d->mask.ymin; - - mulx = (v2d->cur.xmax - v2d->cur.xmin); - muly = (v2d->cur.ymax - v2d->cur.ymin); + float aspx, aspy; if (t->options & CTX_MASK) { - /* clamp w/h, mask only */ - if (mulx / divx < muly / divy) { - divy = divx; - muly = mulx; - } - else { - divx = divy; - mulx = muly; - } + convertViewVec2D_mask(t->view, r_vec, dx, dy); + } + else { + convertViewVec2D(t->view, r_vec, dx, dy); } - - r_vec[0] = mulx * (dx) / divx; - r_vec[1] = muly * (dy) / divy; - r_vec[2] = 0.0f; if (t->options & CTX_MOVIECLIP) { ED_space_clip_get_aspect_dimension_aware(t->sa->spacedata.first, &aspx, &aspy); @@ -207,13 +225,21 @@ void projectIntView(TransInfo *t, const float vec[3], int adr[2]) project_int_noclip(t->ar, vec, adr); } else if (t->spacetype == SPACE_IMAGE) { - float aspx, aspy, v[2]; + if (t->options & CTX_MASK) { + float v[2]; + ED_mask_point_pos__reverse(t->sa, t->ar, vec[0], vec[1], &v[0], &v[1]); + adr[0] = v[0]; + adr[1] = v[1]; + } + else { + float aspx, aspy, v[2]; - ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); - v[0] = vec[0] / aspx; - v[1] = vec[1] / aspy; + ED_space_image_get_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); + v[0] = vec[0] / aspx; + v[1] = vec[1] / aspy; - UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr + 1); + UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr + 1); + } } else if (t->spacetype == SPACE_ACTION) { int out[2] = {0, 0}; @@ -254,10 +280,13 @@ void projectIntView(TransInfo *t, const float vec[3], int adr[2]) copy_v2_v2(v, vec); - if (t->options & CTX_MOVIECLIP) + if (t->options & CTX_MOVIECLIP) { ED_space_clip_get_aspect_dimension_aware(t->sa->spacedata.first, &aspx, &aspy); - else if (t->options & CTX_MASK) + } + else if (t->options & CTX_MASK) { + /* MASKTODO - not working as expected */ ED_space_clip_get_aspect(t->sa->spacedata.first, &aspx, &aspy); + } v[0] /= aspx; v[1] /= aspy; @@ -304,13 +333,13 @@ void applyAspectRatio(TransInfo *t, float vec[2]) if ((sima->flag & SI_COORDFLOATS) == 0) { int width, height; - ED_space_image_size(sima, &width, &height); + ED_space_image_get_size(sima, &width, &height); vec[0] *= width; vec[1] *= height; } - ED_space_image_uv_aspect(sima, &aspx, &aspy); + ED_space_image_get_uv_aspect(sima, &aspx, &aspy); vec[0] /= aspx; vec[1] /= aspy; } @@ -344,13 +373,13 @@ void removeAspectRatio(TransInfo *t, float vec[2]) if ((sima->flag & SI_COORDFLOATS) == 0) { int width, height; - ED_space_image_size(sima, &width, &height); + ED_space_image_get_size(sima, &width, &height); vec[0] /= width; vec[1] /= height; } - ED_space_image_uv_aspect(sima, &aspx, &aspy); + ED_space_image_get_uv_aspect(sima, &aspx, &aspy); vec[0] *= aspx; vec[1] *= aspy; } @@ -406,10 +435,17 @@ static void viewRedrawForce(const bContext *C, TransInfo *t) WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, NULL); } else if (t->spacetype == SPACE_IMAGE) { - // XXX how to deal with lock? - SpaceImage *sima = (SpaceImage *)t->sa->spacedata.first; - if (sima->lock) WM_event_add_notifier(C, NC_GEOM | ND_DATA, t->obedit->data); - else ED_area_tag_redraw(t->sa); + if (t->options & CTX_MASK) { + Mask *mask = CTX_data_edit_mask(C); + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + } + else { + // XXX how to deal with lock? + SpaceImage *sima = (SpaceImage *)t->sa->spacedata.first; + if (sima->lock) WM_event_add_notifier(C, NC_GEOM | ND_DATA, t->obedit->data); + else ED_area_tag_redraw(t->sa); + } } else if (t->spacetype == SPACE_CLIP) { SpaceClip *sc = (SpaceClip *)t->sa->spacedata.first; @@ -423,7 +459,7 @@ static void viewRedrawForce(const bContext *C, TransInfo *t) WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip); } else if (ED_space_clip_check_show_maskedit(sc)) { - Mask *mask = ED_space_clip_get_mask(sc); + Mask *mask = CTX_data_edit_mask(C); WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); } @@ -935,7 +971,7 @@ int transformEvent(TransInfo *t, wmEvent *event) if (t->flag & T_PROP_EDIT) { t->prop_size *= 1.1f; if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO) - t->prop_size = MIN2(t->prop_size, ((View3D *)t->view)->far); + t->prop_size = minf(t->prop_size, ((View3D *)t->view)->far); calculatePropRatio(t); } t->redraw |= TREDRAW_HARD; @@ -1105,7 +1141,7 @@ int transformEvent(TransInfo *t, wmEvent *event) if (event->alt && t->flag & T_PROP_EDIT) { t->prop_size *= 1.1f; if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO) - t->prop_size = MIN2(t->prop_size, ((View3D *)t->view)->far); + t->prop_size = minf(t->prop_size, ((View3D *)t->view)->far); calculatePropRatio(t); } t->redraw = 1; @@ -1306,10 +1342,11 @@ static void drawArc(float size, float angle_start, float angle_end, int segments { float delta = (angle_end - angle_start) / segments; float angle; + int a; glBegin(GL_LINE_STRIP); - for (angle = angle_start; angle < angle_end; angle += delta) { + for (angle = angle_start, a = 0; a < segments; angle += delta, a++) { glVertex2f(cosf(angle) * size, sinf(angle) * size); } glVertex2f(cosf(angle_end) * size, sinf(angle_end) * size); @@ -1459,7 +1496,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) } } -static void drawTransformView(const struct bContext *C, struct ARegion *UNUSED(ar), void *arg) +static void drawTransformView(const struct bContext *C, ARegion *UNUSED(ar), void *arg) { TransInfo *t = arg; @@ -1470,7 +1507,7 @@ static void drawTransformView(const struct bContext *C, struct ARegion *UNUSED(a } #if 0 -static void drawTransformPixel(const struct bContext *UNUSED(C), struct ARegion *UNUSED(ar), void *UNUSED(arg)) +static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar), void *UNUSED(arg)) { // TransInfo *t = arg; // @@ -1911,7 +1948,7 @@ void transformApply(bContext *C, TransInfo *t) t->context = NULL; } -static void drawTransformApply(const bContext *C, struct ARegion *UNUSED(ar), void *arg) +static void drawTransformApply(const bContext *C, ARegion *UNUSED(ar), void *arg) { TransInfo *t = arg; diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 3ab5bf7bbfb..1585fb1ad6b 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -666,7 +666,7 @@ int initTransInfo(struct bContext *C, TransInfo *t, struct wmOperator *op, struc void postTrans (struct bContext *C, TransInfo *t); void resetTransRestrictions(TransInfo *t); -void drawLine(TransInfo *t, float *center, float *dir, char axis, short options); +void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis, short options); void drawNonPropEdge(const struct bContext *C, TransInfo *t); diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index 55110e48469..0aa46a36afe 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -722,7 +722,13 @@ void drawPropCircle(const struct bContext *C, TransInfo *t) else if (t->spacetype == SPACE_IMAGE) { float aspx, aspy; - ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); + if (t->options & CTX_MASK) { + /* untested - mask aspect is TODO */ + ED_space_image_get_aspect(t->sa->spacedata.first, &aspx, &aspy); + } + else { + ED_space_image_get_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); + } glScalef(1.0f / aspx, 1.0f / aspy, 1.0); } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 949266a0cc2..0fdd8736248 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -438,7 +438,7 @@ static short apply_targetless_ik(Object *ob) /* rotation */ /* [#22409] is partially caused by this, as slight numeric error introduced during * the solving process leads to locked-axis values changing. However, we cannot modify - * the values here, or else there are huge discreptancies between IK-solver (interactive) + * the values here, or else there are huge discrepancies between IK-solver (interactive) * and applied poses. */ if (parchan->rotmode > 0) @@ -2189,12 +2189,13 @@ cleanup: void flushTransNodes(TransInfo *t) { int a; - TransData2D *td; + TransData *td; + TransData2D *td2d; /* flush to 2d vector from internally used 3d vector */ - for (a = 0, td = t->data2d; a < t->total; a++, td++) { - td->loc2d[0] = td->loc[0]; - td->loc2d[1] = td->loc[1]; + for (a = 0, td = t->data, td2d = t->data2d; a < t->total; a++, td++, td2d++) { + bNode *node = td->extra; + add_v2_v2v2(&node->locx, td2d->loc, td2d->ih1); } /* handle intersection with noodles */ @@ -2320,7 +2321,7 @@ static void UVsToTransData(SpaceImage *sima, TransData *td, TransData2D *td2d, f { float aspx, aspy; - ED_space_image_uv_aspect(sima, &aspx, &aspy); + ED_space_image_get_uv_aspect(sima, &aspx, &aspy); /* uv coords are scaled by aspects. this is needed for rotations and * proportional editing to be consistent with the stretched uv coords @@ -2428,8 +2429,8 @@ void flushTransUVs(TransInfo *t) int a, width, height; float aspx, aspy, invx, invy; - ED_space_image_uv_aspect(sima, &aspx, &aspy); - ED_space_image_size(sima, &width, &height); + ED_space_image_get_uv_aspect(sima, &aspx, &aspy); + ED_space_image_get_size(sima, &width, &height); invx = 1.0f / aspx; invy = 1.0f / aspy; @@ -2451,7 +2452,7 @@ int clipUVTransform(TransInfo *t, float *vec, int resize) int a, clipx = 1, clipy = 1; float aspx, aspy, min[2], max[2]; - ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); + ED_space_image_get_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); min[0] = min[1] = 0.0f; max[0] = aspx; max[1] = aspy; @@ -4964,6 +4965,37 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *o } } +static void special_aftertrans_update__mask(bContext *C, TransInfo *t) +{ + Mask *mask; + + if (t->spacetype == SPACE_CLIP) { + SpaceClip *sc = t->sa->spacedata.first; + mask = ED_space_clip_get_mask(sc); + } + else if (t->spacetype == SPACE_IMAGE) { + SpaceImage *sima = t->sa->spacedata.first; + mask = ED_space_image_get_mask(sima); + } + else { + BLI_assert(0); + } + + if (t->scene->nodetree) { + /* tracks can be used for stabilization nodes, + * flush update for such nodes */ + //if (nodeUpdateID(t->scene->nodetree, &mask->id)) { + WM_event_add_notifier(C, NC_MASK | ND_DATA, &mask->id); + //} + } + + /* TODO - dont key all masks... */ + if (IS_AUTOKEY_ON(t->scene)) { + Scene *scene = t->scene; + + ED_mask_layer_shape_auto_key_select(mask, CFRA); + } +} /* inserting keys, pointcache, redraw events... */ /* @@ -5009,7 +5041,8 @@ void special_aftertrans_update(bContext *C, TransInfo *t) } } } - + + if (t->spacetype == SPACE_SEQ) { /* freeSeqData in transform_conversions.c does this * keep here so the else at the end wont run... */ @@ -5030,7 +5063,11 @@ void special_aftertrans_update(bContext *C, TransInfo *t) ED_markers_post_apply_transform(&t->scene->markers, t->scene, TFM_TIME_EXTEND, t->values[0], t->frame_side); } } - + } + else if (t->spacetype == SPACE_IMAGE) { + if (t->options & CTX_MASK) { + special_aftertrans_update__mask(C, t); + } } else if (t->spacetype == SPACE_NODE) { SpaceNode *snode = (SpaceNode *)t->sa->spacedata.first; @@ -5056,22 +5093,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) } } else if (t->options & CTX_MASK) { - SpaceClip *sc = t->sa->spacedata.first; - Mask *mask = ED_space_clip_get_mask(sc); - - if (t->scene->nodetree) { - /* tracks can be used for stabilization nodes, - * flush update for such nodes */ - nodeUpdateID(t->scene->nodetree, &mask->id); - WM_event_add_notifier(C, NC_SCENE | ND_NODES, NULL); - } - - /* TODO - dont key all masks... */ - if (IS_AUTOKEY_ON(t->scene)) { - Scene *scene = t->scene; - - ED_mask_layer_shape_auto_key_select(mask, CFRA); - } + special_aftertrans_update__mask(C, t); } } else if (t->spacetype == SPACE_ACTION) { @@ -5356,6 +5378,8 @@ void special_aftertrans_update(bContext *C, TransInfo *t) else { /* Objects */ int i, recalcObPaths = 0; + BLI_assert(t->flag & T_OBJECT); + for (i = 0; i < t->total; i++) { TransData *td = t->data + i; ListBase pidlist; @@ -5502,24 +5526,22 @@ static void createTransObject(bContext *C, TransInfo *t) /* transcribe given node into TransData2D for Transforming */ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node) -// static void NodeToTransData(bContext *C, TransInfo *t, TransData2D *td, bNode *node) { - td2d->loc[0] = node->locx; /* hold original location */ - td2d->loc[1] = node->locy; + /* hold original location */ + float locxy[2] = {(node->totr.xmax + node->totr.xmin) / 2.0f, + (node->totr.ymax + node->totr.ymin) / 2.0f}; + + copy_v2_v2(td2d->loc, locxy); td2d->loc[2] = 0.0f; - td2d->loc2d = &node->locx; /* current location */ + td2d->loc2d = td2d->loc; /* current location */ td->flag = 0; - /* exclude nodes whose parent is also transformed */ - if (node->parent && (node->parent->flag & NODE_TRANSFORM)) { - td->flag |= TD_SKIP; - } td->loc = td2d->loc; copy_v3_v3(td->iloc, td->loc); /* use node center instead of origin (top-left corner) */ - td->center[0] = node->locx + 0.5f * (node->totr.xmax - node->totr.xmin); - td->center[1] = node->locy - 0.5f * (node->totr.ymax - node->totr.ymin); /* node height is used negative */ + td->center[0] = locxy[0]; + td->center[1] = locxy[1]; td->center[2] = 0.0f; memset(td->axismtx, 0, sizeof(td->axismtx)); @@ -5533,37 +5555,53 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node) unit_m3(td->mtx); unit_m3(td->smtx); + sub_v2_v2v2(td2d->ih1, &node->locx, locxy); + td->extra = node; } -static void createTransNodeData(bContext *C, TransInfo *t) +static int is_node_parent_select(bNode *node) +{ + while ((node = node->parent)) { + if (node->flag & NODE_TRANSFORM) { + return TRUE; + } + } + return FALSE; +} + +static void createTransNodeData(bContext *UNUSED(C), TransInfo *t) { TransData *td; TransData2D *td2d; SpaceNode *snode = t->sa->spacedata.first; bNode *node; + t->total = 0; + if (!snode->edittree) { - t->total = 0; return; } /* set transform flags on nodes */ for (node = snode->edittree->nodes.first; node; node = node->next) { - if ((node->flag & NODE_SELECT) || (node->parent && (node->parent->flag & NODE_TRANSFORM))) + if (node->flag & NODE_SELECT && is_node_parent_select(node) == FALSE) { node->flag |= NODE_TRANSFORM; - else + t->total++; + } + else { node->flag &= ~NODE_TRANSFORM; + } } - t->total = CTX_DATA_COUNT(C, selected_nodes); - td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransNode TransData"); td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransNode TransData2D"); - CTX_DATA_BEGIN(C, bNode *, selnode, selected_nodes) - NodeToTransData(td++, td2d++, selnode); - CTX_DATA_END + for (node = snode->edittree->nodes.first; node; node = node->next) { + if (node->flag & NODE_TRANSFORM) { + NodeToTransData(td++, td2d++, node); + } + } } /* *** CLIP EDITOR *** */ @@ -6069,19 +6107,17 @@ typedef struct TransDataMasking { MaskSplinePoint *point; } TransDataMasking; -static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, - TransData *td, TransData2D *td2d, TransDataMasking *tdm, int propmode) +static void MaskPointToTransData(MaskSplinePoint *point, + TransData *td, TransData2D *td2d, TransDataMasking *tdm, + const int propmode, const float asp[2]) { BezTriple *bezt = &point->bezt; - float aspx, aspy; short is_sel_point = MASKPOINT_ISSEL_KNOT(point); short is_sel_any = MASKPOINT_ISSEL_ANY(point); tdm->point = point; copy_m3_m3(tdm->vec, bezt->vec); - ED_space_clip_get_aspect(sc, &aspx, &aspy); - if (propmode || is_sel_point) { int i; for (i = 0; i < 3; i++) { @@ -6089,8 +6125,8 @@ static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, * proportional editing to be consistent with the stretched CV coords * that are displayed. this also means that for display and numinput, * and when the the CV coords are flushed, these are converted each time */ - td2d->loc[0] = bezt->vec[i][0] * aspx; - td2d->loc[1] = bezt->vec[i][1] * aspy; + td2d->loc[0] = bezt->vec[i][0] * asp[0]; + td2d->loc[1] = bezt->vec[i][1] * asp[1]; td2d->loc[2] = 0.0f; td2d->loc2d = bezt->vec[i]; @@ -6132,8 +6168,8 @@ static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, copy_v2_v2(tdm->orig_handle, tdm->handle); - td2d->loc[0] = tdm->handle[0] * aspx; - td2d->loc[1] = tdm->handle[1] * aspy; + td2d->loc[0] = tdm->handle[0] * asp[0]; + td2d->loc[1] = tdm->handle[1] * asp[1]; td2d->loc[2] = 0.0f; td2d->loc2d = tdm->handle; @@ -6164,7 +6200,6 @@ static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, static void createTransMaskingData(bContext *C, TransInfo *t) { - SpaceClip *sc = CTX_wm_space_clip(C); Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; TransData *td = NULL; @@ -6172,6 +6207,7 @@ static void createTransMaskingData(bContext *C, TransInfo *t) TransDataMasking *tdm = NULL; int count = 0, countsel = 0; int propmode = t->flag & T_PROP_EDIT; + float asp[2]; t->total = 0; @@ -6206,7 +6242,11 @@ static void createTransMaskingData(bContext *C, TransInfo *t) } /* note: in prop mode we need at least 1 selected */ - if (countsel == 0) return; + if (countsel == 0) { + return; + } + + ED_mask_get_aspect(t->sa, t->ar, &asp[0], &asp[1]); t->total = (propmode) ? count : countsel; td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Mask Editing)"); @@ -6232,7 +6272,7 @@ static void createTransMaskingData(bContext *C, TransInfo *t) MaskSplinePoint *point = &spline->points[i]; if (propmode || MASKPOINT_ISSEL_ANY(point)) { - MaskPointToTransData(sc, point, td, td2d, tdm, propmode); + MaskPointToTransData(point, td, td2d, tdm, propmode, asp); if (propmode || MASKPOINT_ISSEL_KNOT(point)) { td += 3; @@ -6252,20 +6292,19 @@ static void createTransMaskingData(bContext *C, TransInfo *t) void flushTransMasking(TransInfo *t) { - SpaceClip *sc = t->sa->spacedata.first; TransData2D *td; TransDataMasking *tdm; int a; - float aspx, aspy, invx, invy; + float asp[2], inv[2]; - ED_space_clip_get_aspect(sc, &aspx, &aspy); - invx = 1.0f / aspx; - invy = 1.0f / aspy; + ED_mask_get_aspect(t->sa, t->ar, &asp[0], &asp[1]); + inv[0] = 1.0f / asp[0]; + inv[1] = 1.0f / asp[1]; /* flush to 2d vector from internally used 3d vector */ for (a = 0, td = t->data2d, tdm = t->customData; a < t->total; a++, td++, tdm++) { - td->loc2d[0] = td->loc[0] * invx; - td->loc2d[1] = td->loc[1] * invy; + td->loc2d[0] = td->loc[0] * inv[0]; + td->loc2d[1] = td->loc[1] * inv[1]; if (tdm->is_handle) BKE_mask_point_set_handle(tdm->point, td->loc2d, t->flag & T_ALT_TRANSFORM, tdm->orig_handle, tdm->vec); @@ -6297,11 +6336,23 @@ void createTransData(bContext *C, TransInfo *t) } else if (t->spacetype == SPACE_IMAGE) { t->flag |= T_POINTS | T_2D_EDIT; - createTransUVs(C, t); - if (t->data && (t->flag & T_PROP_EDIT)) { - sort_trans_data(t); // makes selected become first in array - set_prop_dist(t, 1); - sort_trans_data_dist(t); + if (t->options & CTX_MASK) { + /* copied from below */ + createTransMaskingData(C, t); + + if (t->data && (t->flag & T_PROP_EDIT)) { + sort_trans_data(t); // makes selected become first in array + set_prop_dist(t, TRUE); + sort_trans_data_dist(t); + } + } + else { + createTransUVs(C, t); + if (t->data && (t->flag & T_PROP_EDIT)) { + sort_trans_data(t); // makes selected become first in array + set_prop_dist(t, 1); + sort_trans_data_dist(t); + } } } else if (t->spacetype == SPACE_ACTION) { @@ -6342,6 +6393,7 @@ void createTransData(bContext *C, TransInfo *t) if (t->options & CTX_MOVIECLIP) createTransTrackingData(C, t); else if (t->options & CTX_MASK) { + /* copied from above */ createTransMaskingData(C, t); if (t->data && (t->flag & T_PROP_EDIT)) { diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index dba597d316d..8e73fb8b8cb 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -73,6 +73,7 @@ #include "BKE_context.h" #include "BKE_tessmesh.h" #include "BKE_tracking.h" +#include "BKE_mask.h" #include "ED_anim_api.h" #include "ED_armature.h" @@ -607,10 +608,22 @@ static void recalcData_nla(TransInfo *t) } } +static void recalcData_mask_common(TransInfo *t) +{ + Mask *mask = CTX_data_edit_mask(t->context); + + flushTransMasking(t); + + DAG_id_tag_update(&mask->id, 0); +} + /* helper for recalcData() - for Image Editor transforms */ static void recalcData_image(TransInfo *t) { - if (t->obedit && t->obedit->type == OB_MESH) { + if (t->options & CTX_MASK) { + recalcData_mask_common(t); + } + else if (t->obedit && t->obedit->type == OB_MESH) { SpaceImage *sima = t->sa->spacedata.first; flushTransUVs(t); @@ -662,12 +675,8 @@ static void recalcData_spaceclip(TransInfo *t) DAG_id_tag_update(&clip->id, 0); } - else if (ED_space_clip_check_show_maskedit(sc)) { - Mask *mask = ED_space_clip_get_mask(sc); - - flushTransMasking(t); - - DAG_id_tag_update(&mask->id, 0); + else if (t->options & CTX_MASK) { + recalcData_mask_common(t); } } @@ -908,9 +917,13 @@ void recalcData(TransInfo *t) else if (t->spacetype == SPACE_CLIP) { recalcData_spaceclip(t); } + + if (t->options & CTX_MASK) { + + } } -void drawLine(TransInfo *t, float *center, float *dir, char axis, short options) +void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis, short options) { float v1[3], v2[3], v3[3]; unsigned char col[3], col2[3]; @@ -1004,15 +1017,10 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) t->total = 0; t->val = 0.0f; - - t->vec[0] = - t->vec[1] = - t->vec[2] = 0.0f; - t->center[0] = - t->center[1] = - t->center[2] = 0.0f; - + zero_v3(t->vec); + zero_v3(t->center); + unit_m3(t->mat); /* if there's an event, we're modal */ @@ -1099,6 +1107,16 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) // XXX for now, get View2D from the active region t->view = &ar->v2d; t->around = sima->around; + + if (ED_space_image_show_uvedit(sima, t->obedit)) { + /* UV transform */ + } + else if (sima->mode == SI_MODE_MASK) { + t->options |= CTX_MASK; + } + else { + BLI_assert(0); + } } else if (t->spacetype == SPACE_NODE) { // XXX for now, get View2D from the active region @@ -1280,9 +1298,14 @@ void postTrans(bContext *C, TransInfo *t) } if (t->spacetype == SPACE_IMAGE) { - SpaceImage *sima = t->sa->spacedata.first; - if (sima->flag & SI_LIVE_UNWRAP) - ED_uvedit_live_unwrap_end(t->state == TRANS_CANCEL); + if (t->options & CTX_MASK) { + /* pass */ + } + else { + SpaceImage *sima = t->sa->spacedata.first; + if (sima->flag & SI_LIVE_UNWRAP) + ED_uvedit_live_unwrap_end(t->state == TRANS_CANCEL); + } } else if (t->spacetype == SPACE_VIEW3D) { View3D *v3d = t->sa->spacedata.first; @@ -1417,13 +1440,33 @@ void calculateCenterCursor2D(TransInfo *t) if (t->spacetype == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)t->sa->spacedata.first; /* only space supported right now but may change */ - ED_space_image_uv_aspect(sima, &aspx, &aspy); + if (t->options & CTX_MASK) { + ED_space_image_get_aspect(sima, &aspx, &aspy); + } + else { + ED_space_image_get_uv_aspect(sima, &aspx, &aspy); + } cursor = sima->cursor; } if (cursor) { - t->center[0] = cursor[0] * aspx; - t->center[1] = cursor[1] * aspy; + if (t->options & CTX_MASK) { + float co[2]; + float frame_size[2]; + SpaceImage *sima = (SpaceImage *)t->sa->spacedata.first; + ED_space_image_get_size_fl(sima, frame_size); + + BKE_mask_coord_from_frame(co, cursor, frame_size); + + ED_space_image_get_aspect(sima, &aspx, &aspy); + + t->center[0] = co[0] * aspx; + t->center[1] = co[1] * aspy; + } + else { + t->center[0] = cursor[0] * aspx; + t->center[1] = cursor[1] * aspy; + } } calculateCenter2D(t); diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 0ea48e81029..fcb857be4e0 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -206,10 +206,10 @@ void drawSnapping(const struct bContext *C, TransInfo *t) myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); glLoadIdentity(); - ED_space_image_aspect(t->sa->spacedata.first, &xuser_aspx, &yuser_asp); + ED_space_image_get_aspect(t->sa->spacedata.first, &xuser_aspx, &yuser_asp); ED_space_image_width(t->sa->spacedata.first, &wi, &hi); - w = (((float)wi) / 256.0f) * G.sima->zoom * xuser_asp; - h = (((float)hi) / 256.0f) * G.sima->zoom * yuser_asp; + w = (((float)wi) / IMG_SIZE_FALLBACK) * G.sima->zoom * xuser_asp; + h = (((float)hi) / IMG_SIZE_FALLBACK) * G.sima->zoom * yuser_asp; cpack(0xFFFFFF); glTranslatef(t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], 0.0f); @@ -246,13 +246,13 @@ void drawSnapping(const struct bContext *C, TransInfo *t) glColor4ubv(col); } - drawnodesnap(&ar->v2d, p->co, size, 0); + ED_node_draw_snap(&ar->v2d, p->co, size, 0); } if (t->tsnap.status & POINT_INIT) { glColor4ubv(activeCol); - drawnodesnap(&ar->v2d, t->tsnap.snapPoint, size, t->tsnap.snapNodeBorder); + ED_node_draw_snap(&ar->v2d, t->tsnap.snapPoint, size, t->tsnap.snapNodeBorder); } glDisable(GL_BLEND); @@ -927,7 +927,7 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec)) UI_view2d_region_to_view(&t->ar->v2d, t->mval[0], t->mval[1], co, co + 1); if (ED_uvedit_nearest_uv(t->scene, t->obedit, ima, co, t->tsnap.snapPoint)) { - ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); + ED_space_image_get_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); t->tsnap.snapPoint[0] *= aspx; t->tsnap.snapPoint[1] *= aspy; @@ -2135,7 +2135,12 @@ static void applyGrid(TransInfo *t, float *val, int max_index, float fac[3], Gea /* evil hack - snapping needs to be adapted for image aspect ratio */ if ((t->spacetype == SPACE_IMAGE) && (t->mode == TFM_TRANSLATION)) { - ED_space_image_uv_aspect(t->sa->spacedata.first, asp, asp + 1); + if (t->options & CTX_MASK) { + ED_space_image_get_aspect(t->sa->spacedata.first, asp, asp + 1); + } + else { + ED_space_image_get_uv_aspect(t->sa->spacedata.first, asp, asp + 1); + } } for (i = 0; i <= max_index; i++) { diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c index 0c2bfff3b57..65b92168842 100644 --- a/source/blender/editors/util/undo.c +++ b/source/blender/editors/util/undo.c @@ -141,7 +141,7 @@ static int ed_undo_step(bContext *C, int step, const char *undoname) if (sa && (sa->spacetype == SPACE_IMAGE)) { SpaceImage *sima = (SpaceImage *)sa->spacedata.first; - if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->flag & SI_DRAWTOOL)) { + if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) { if (!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname) && undoname) if (U.uiflag & USER_GLOBALUNDO) BKE_undo_name(C, undoname); @@ -238,7 +238,7 @@ int ED_undo_valid(const bContext *C, const char *undoname) if (sa && sa->spacetype == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)sa->spacedata.first; - if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->flag & SI_DRAWTOOL)) { + if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) { return 1; } } diff --git a/source/blender/editors/uvedit/uvedit_buttons.c b/source/blender/editors/uvedit/uvedit_buttons.c index ec645f86848..fa39a52444b 100644 --- a/source/blender/editors/uvedit/uvedit_buttons.c +++ b/source/blender/editors/uvedit/uvedit_buttons.c @@ -125,7 +125,7 @@ static void uvedit_vertex_buttons(const bContext *C, uiBlock *block) float center[2]; int imx, imy, step, digits; - ED_space_image_size(sima, &imx, &imy); + ED_space_image_get_size(sima, &imx, &imy); em = BMEdit_FromObject(obedit); @@ -168,7 +168,7 @@ static void do_uvedit_vertex(bContext *C, void *UNUSED(arg), int event) em = BMEdit_FromObject(obedit); - ED_space_image_size(sima, &imx, &imy); + ED_space_image_get_size(sima, &imx, &imy); uvedit_center(scene, em, ima, center); if (sima->flag & SI_COORDFLOATS) { diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 17c57b1f6e4..1f78bc6bddf 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -63,13 +63,13 @@ #include "uvedit_intern.h" -static void drawcursor_sima(SpaceImage *sima, ARegion *ar) +void draw_image_cursor(SpaceImage *sima, ARegion *ar) { float zoomx, zoomy, w, h; int width, height; - ED_space_image_size(sima, &width, &height); - ED_space_image_zoom(sima, ar, &zoomx, &zoomy); + ED_space_image_get_size(sima, &width, &height); + ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy); w = zoomx * width / 256.0f; h = zoomy * height / 256.0f; @@ -174,7 +174,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe float aspx, aspy, col[4], (*tf_uv)[2] = NULL, (*tf_uvorig)[2] = NULL; int i, j, nverts; - ED_space_image_uv_aspect(sima, &aspx, &aspy); + ED_space_image_get_uv_aspect(sima, &aspx, &aspy); switch (sima->dt_uvstretch) { case SI_UVDT_STRETCH_AREA: @@ -889,7 +889,7 @@ void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedi draw_uvs_texpaint(sima, scene, obact); if (show_uvedit && !(toolsettings->use_uv_sculpt)) - drawcursor_sima(sima, ar); + draw_image_cursor(sima, ar); } } diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 0510ae21326..67e06b1c33c 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -199,8 +199,8 @@ void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *im float prev_aspect[2], fprev_aspect; float aspect[2], faspect; - ED_image_uv_aspect(previma, prev_aspect, prev_aspect + 1); - ED_image_uv_aspect(ima, aspect, aspect + 1); + ED_image_get_uv_aspect(previma, prev_aspect, prev_aspect + 1); + ED_image_get_uv_aspect(ima, aspect, aspect + 1); fprev_aspect = prev_aspect[0]/prev_aspect[1]; faspect = aspect[0]/aspect[1]; @@ -224,7 +224,7 @@ void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *im else id_lib_extern(&ima->id); /* we also need to correct the aspect of uvs */ - if(tf->unwrap & TF_CORRECT_ASPECT) { + if (tf->unwrap & TF_CORRECT_ASPECT) { BMIter liter; BMLoop *l; @@ -292,11 +292,11 @@ static void uvedit_pixel_to_float(SpaceImage *sima, float *dist, float pixeldist int width, height; if (sima) { - ED_space_image_size(sima, &width, &height); + ED_space_image_get_size(sima, &width, &height); } else { - width = 256; - height = 256; + width = IMG_SIZE_FALLBACK; + height = IMG_SIZE_FALLBACK; } dist[0] = pixeldist / width; @@ -2604,8 +2604,8 @@ static int circle_select_exec(bContext *C, wmOperator *op) /* compute ellipse size and location, not a circle since we deal * with non square image. ellipse is normalized, r = 1.0. */ - ED_space_image_size(sima, &width, &height); - ED_space_image_zoom(sima, ar, &zoomx, &zoomy); + ED_space_image_get_size(sima, &width, &height); + ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy); ellipse[0] = width * zoomx / radius; ellipse[1] = height * zoomy / radius; @@ -2781,7 +2781,7 @@ static void snap_cursor_to_pixels(SpaceImage *sima) { int width = 0, height = 0; - ED_space_image_size(sima, &width, &height); + ED_space_image_get_size(sima, &width, &height); snap_uv_to_pixel(sima->cursor, width, height); } @@ -2936,7 +2936,7 @@ static int snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit) float w, h; short change = 0; - ED_space_image_size(sima, &width, &height); + ED_space_image_get_size(sima, &width, &height); w = (float)width; h = (float)height; @@ -3380,14 +3380,11 @@ static void UV_OT_reveal(wmOperatorType *ot) static int set_2d_cursor_exec(bContext *C, wmOperator *op) { SpaceImage *sima = CTX_wm_space_image(C); - float location[2]; if (!sima) return OPERATOR_CANCELLED; - RNA_float_get_array(op->ptr, "location", location); - sima->cursor[0] = location[0]; - sima->cursor[1] = location[1]; + RNA_float_get_array(op->ptr, "location", sima->cursor); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_IMAGE, NULL); diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index a2e276c09e3..39a78ea934b 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -660,10 +660,11 @@ static void p_flush_uvs(PHandle *handle, PChart *chart) } for (f = chart->faces; f; f = f->nextlink) { - if(f->unwrap_flag) { + if (f->unwrap_flag) { if (handle->do_aspect) { *f->unwrap_flag |= TF_CORRECT_ASPECT; - } else { + } + else { *f->unwrap_flag &= ~TF_CORRECT_ASPECT; } } @@ -3469,7 +3470,7 @@ static float p_chart_minimum_area_angle(PChart *chart) float rotated, minarea, minangle, area, len; float *angles, miny, maxy, v[2], a[4], mina; - int npoints, right, mini, maxi, i, idx[4], nextidx; + int npoints, right, i_min, i_max, i, idx[4], nextidx; PVert **points, *p1, *p2, *p3, *p4, *p1n; /* compute convex hull */ @@ -3479,7 +3480,7 @@ static float p_chart_minimum_area_angle(PChart *chart) /* find left/top/right/bottom points, and compute angle for each point */ angles = MEM_mallocN(sizeof(float) * npoints, "PMinAreaAngles"); - mini = maxi = 0; + i_min = i_max = 0; miny = 1e10; maxy = -1e10; @@ -3492,19 +3493,19 @@ static float p_chart_minimum_area_angle(PChart *chart) if (points[i]->uv[1] < miny) { miny = points[i]->uv[1]; - mini = i; + i_min = i; } if (points[i]->uv[1] > maxy) { maxy = points[i]->uv[1]; - maxi = i; + i_max = i; } } /* left, top, right, bottom */ idx[0] = 0; - idx[1] = maxi; + idx[1] = i_max; idx[2] = right; - idx[3] = mini; + idx[3] = i_min; v[0] = points[idx[0]]->uv[0]; v[1] = points[idx[0]]->uv[1] + 1.0f; @@ -3530,29 +3531,29 @@ static float p_chart_minimum_area_angle(PChart *chart) while (rotated <= (float)(M_PI / 2.0)) { /* INVESTIGATE: how far to rotate? */ /* rotate with the smallest angle */ - mini = 0; + i_min = 0; mina = 1e10; for (i = 0; i < 4; i++) if (a[i] < mina) { mina = a[i]; - mini = i; + i_min = i; } rotated += mina; - nextidx = (idx[mini] + 1) % npoints; + nextidx = (idx[i_min] + 1) % npoints; - a[mini] = angles[nextidx]; - a[(mini + 1) % 4] = a[(mini + 1) % 4] - mina; - a[(mini + 2) % 4] = a[(mini + 2) % 4] - mina; - a[(mini + 3) % 4] = a[(mini + 3) % 4] - mina; + a[i_min] = angles[nextidx]; + a[(i_min + 1) % 4] = a[(i_min + 1) % 4] - mina; + a[(i_min + 2) % 4] = a[(i_min + 2) % 4] - mina; + a[(i_min + 3) % 4] = a[(i_min + 3) % 4] - mina; /* compute area */ - p1 = points[idx[mini]]; + p1 = points[idx[i_min]]; p1n = points[nextidx]; - p2 = points[idx[(mini + 1) % 4]]; - p3 = points[idx[(mini + 2) % 4]]; - p4 = points[idx[(mini + 3) % 4]]; + p2 = points[idx[(i_min + 1) % 4]]; + p3 = points[idx[(i_min + 2) % 4]]; + p4 = points[idx[(i_min + 3) % 4]]; len = len_v2v2(p1->uv, p1n->uv); @@ -3570,7 +3571,7 @@ static float p_chart_minimum_area_angle(PChart *chart) } } - idx[mini] = nextidx; + idx[i_min] = nextidx; } /* try keeping rotation as small as possible */ diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 5c2e57cf27f..4e0e7944e84 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -118,6 +118,8 @@ typedef struct StitchState { char midpoints; /* editmesh, cached for use in modal handler */ BMEditMesh *em; + /* clear seams of stitched edges after stitch */ + char clear_seams; /* element map for getting info about uv connectivity */ UvElementMap *element_map; /* edge container */ @@ -833,6 +835,15 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) } } + /* clear seams of stitched edges */ + if (final && state->clear_seams) { + for (i = 0; i < state->total_boundary_edges; i++) { + UvEdge *edge = state->edges + i; + if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)) + BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM); + } + } + for (i = 0; i < state->selection_size; i++) { UvElement *element = state->selection_stack[i]; if (!island_stitch_data[element->island].use_edge_rotation) { @@ -1004,6 +1015,7 @@ static int stitch_init(bContext *C, wmOperator *op) state->snap_islands = RNA_boolean_get(op->ptr, "snap_islands"); state->static_island = RNA_int_get(op->ptr, "static_island"); state->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap"); + state->clear_seams = RNA_boolean_get(op->ptr, "clear_seams"); /* 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, 0, 1); @@ -1488,6 +1500,8 @@ void UV_OT_stitch(wmOperatorType *ot) "Island that stays in place when stitching islands", 0, INT_MAX); RNA_def_boolean(ot->srna, "midpoint_snap", 0, "Snap At Midpoint", "UVs are stitched at midpoint instead of at static island"); + RNA_def_boolean(ot->srna, "clear_seams", 1, "Clear Seams", + "Clear seams of stitched edges"); prop = RNA_def_collection_runtime(ot->srna, "selection", &RNA_SelectedUvElement, "Selection", ""); /* Selection should not be editable or viewed in toolbar */ RNA_def_property_flag(prop, PROP_HIDDEN); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 1def5caad87..4b6c0ef0e7b 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -198,7 +198,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em, float aspx, aspy; tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); - ED_image_uv_aspect(tf->tpage, &aspx, &aspy); + ED_image_get_uv_aspect(tf->tpage, &aspx, &aspy); if (aspx != aspy) param_aspect_ratio(handle, aspx, aspy); @@ -388,7 +388,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, BMEditMesh *e float aspx, aspy; tf = CustomData_bmesh_get(&em->bm->pdata, editFace->head.data, CD_MTEXPOLY); - ED_image_uv_aspect(tf->tpage, &aspx, &aspy); + ED_image_get_uv_aspect(tf->tpage, &aspx, &aspy); if (aspx != aspy) param_aspect_ratio(handle, aspx, aspy); @@ -1017,7 +1017,7 @@ static void correct_uv_aspect(BMEditMesh *em) MTexPoly *tf; tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); - ED_image_uv_aspect(tf->tpage, &aspx, &aspy); + ED_image_get_uv_aspect(tf->tpage, &aspx, &aspy); } if (aspx == aspy) diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index 59140b2be80..7a71f33d3d0 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -104,6 +104,7 @@ void GPU_render_text(struct MTFace *tface, int mode, * - these will free textures on changes */ void GPU_set_mipmap(int mipmap); +int GPU_get_mipmap(void); void GPU_set_linear_mipmap(int linear); void GPU_paint_set_mipmap(int mipmap); diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 7f5ae0ba2a1..a725ff4385d 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -173,6 +173,11 @@ typedef enum GPUDynamicType { GPU_DYNAMIC_SAMPLER_2DBUFFER = 12, GPU_DYNAMIC_SAMPLER_2DIMAGE = 13, GPU_DYNAMIC_SAMPLER_2DSHADOW = 14, + GPU_DYNAMIC_LAMP_DISTANCE = 15, + GPU_DYNAMIC_LAMP_ATT1 = 16, + GPU_DYNAMIC_LAMP_ATT2 = 17, + GPU_DYNAMIC_LAMP_SPOTSIZE = 18, + GPU_DYNAMIC_LAMP_SPOTBLEND = 19, } GPUDynamicType; typedef enum GPUDataType { @@ -231,6 +236,8 @@ void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp); void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4]); void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy); +void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2); +void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend); int GPU_lamp_shadow_layer(GPULamp *lamp); #ifdef __cplusplus diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index f4e1e0c1147..3c2d3e11197 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -268,7 +268,7 @@ void GPU_set_linear_mipmap(int linear) } } -static int gpu_get_mipmap(void) +int GPU_get_mipmap(void) { return GTS.domipmap && !GTS.texpaint; } @@ -640,7 +640,7 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float * frect, int /* scale if not a power of two. this is not strictly necessary for newer * GPUs (OpenGL version >= 2.0) since they support non-power-of-two-textures * Then don't bother scaling for hardware that supports NPOT textures! */ - if (!GLEW_ARB_texture_non_power_of_two && (!is_pow2_limit(rectw) || !is_pow2_limit(recth))) { + if (!GPU_non_power_of_two_support() && (!is_pow2_limit(rectw) || !is_pow2_limit(recth))) { rectw= smaller_pow2_limit(rectw); recth= smaller_pow2_limit(recth); @@ -662,7 +662,7 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float * frect, int glGenTextures(1, (GLuint *)bind); glBindTexture(GL_TEXTURE_2D, *bind); - if (!(gpu_get_mipmap() && mipmap)) { + if (!(GPU_get_mipmap() && mipmap)) { if (use_high_bit_depth) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect); else @@ -678,7 +678,8 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float * frect, int glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix); glGenerateMipmapEXT(GL_TEXTURE_2D); - } else { + } + else { if (use_high_bit_depth) gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA16, rectw, recth, GL_RGBA, GL_FLOAT, frect); else @@ -883,7 +884,7 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h, int mipmap) ibuf = BKE_image_get_ibuf(ima, NULL); - if (ima->repbind || (gpu_get_mipmap() && mipmap) || !ima->bindcode || !ibuf || + if (ima->repbind || (GPU_get_mipmap() && mipmap) || !ima->bindcode || !ibuf || (!is_power_of_2_i(ibuf->x) || !is_power_of_2_i(ibuf->y)) || (w == 0) || (h == 0)) { diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 0fad5e47445..bd25a042ee4 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -117,6 +117,7 @@ struct GPULamp { float dynimat[4][4]; float spotsi, spotbl, k; + float dyndist, dynatt1, dynatt2; float dist, att1, att2; float shadow_color[3]; @@ -413,13 +414,13 @@ static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNode case LA_FALLOFF_CONSTANT: break; case LA_FALLOFF_INVLINEAR: - GPU_link(mat, "lamp_falloff_invlinear", GPU_uniform(&lamp->dist), *dist, &visifac); + GPU_link(mat, "lamp_falloff_invlinear", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac); break; case LA_FALLOFF_INVSQUARE: - GPU_link(mat, "lamp_falloff_invsquare", GPU_uniform(&lamp->dist), *dist, &visifac); + GPU_link(mat, "lamp_falloff_invsquare", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac); break; case LA_FALLOFF_SLIDERS: - GPU_link(mat, "lamp_falloff_sliders", GPU_uniform(&lamp->dist), GPU_uniform(&lamp->att1), GPU_uniform(&lamp->att2), *dist, &visifac); + GPU_link(mat, "lamp_falloff_sliders", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), GPU_dynamic_uniform(&lamp->att1, GPU_DYNAMIC_LAMP_ATT1, lamp->ob), GPU_dynamic_uniform(&lamp->att2, GPU_DYNAMIC_LAMP_ATT2, lamp->ob), *dist, &visifac); break; case LA_FALLOFF_CURVE: { @@ -427,13 +428,13 @@ static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNode int size; curvemapping_table_RGBA(lamp->curfalloff, &array, &size); - GPU_link(mat, "lamp_falloff_curve", GPU_uniform(&lamp->dist), GPU_texture(size, array), *dist, &visifac); + GPU_link(mat, "lamp_falloff_curve", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), GPU_texture(size, array), *dist, &visifac); } break; } if (lamp->mode & LA_SPHERE) - GPU_link(mat, "lamp_visibility_sphere", GPU_uniform(&lamp->dist), *dist, visifac, &visifac); + GPU_link(mat, "lamp_visibility_sphere", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, visifac, &visifac); if (lamp->type == LA_SPOT) { if (lamp->mode & LA_SQUARE) { @@ -445,7 +446,7 @@ static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNode GPU_link(mat, "lamp_visibility_spot_circle", GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), *lv, &inpr); } - GPU_link(mat, "lamp_visibility_spot", GPU_uniform(&lamp->spotsi), GPU_uniform(&lamp->spotbl), inpr, visifac, &visifac); + GPU_link(mat, "lamp_visibility_spot", GPU_dynamic_uniform(&lamp->spotsi, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob), GPU_dynamic_uniform(&lamp->spotbl, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob), inpr, visifac, &visifac); } GPU_link(mat, "lamp_visibility_clamp", visifac, &visifac); @@ -1347,6 +1348,7 @@ static void do_material_tex(GPUShadeInput *shi) void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi) { float hard = ma->har; + float one = 1.0f; memset(shi, 0, sizeof(*shi)); @@ -1356,7 +1358,12 @@ void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi) GPU_link(mat, "set_rgb", GPU_uniform(&ma->r), &shi->rgb); GPU_link(mat, "set_rgb", GPU_uniform(&ma->specr), &shi->specrgb); GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &shi->vn); - GPU_link(mat, "set_value", GPU_uniform(&ma->alpha), &shi->alpha); + + if (ma->mode & MA_TRANSP) + GPU_link(mat, "set_value", GPU_uniform(&ma->alpha), &shi->alpha); + else + GPU_link(mat, "set_value", GPU_uniform(&one), &shi->alpha); + GPU_link(mat, "set_value", GPU_uniform(&ma->ref), &shi->refl); GPU_link(mat, "set_value", GPU_uniform(&ma->spec), &shi->spec); GPU_link(mat, "set_value", GPU_uniform(&ma->emit), &shi->emit); @@ -1570,6 +1577,19 @@ void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float ener lamp->col[2]= b* lamp->energy; } +void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2) +{ + lamp->dist = distance; + lamp->att1 = att1; + lamp->att2 = att2; +} + +void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend) +{ + lamp->spotsi= cos(M_PI*spotsize/360.0); + lamp->spotbl= (1.0f - lamp->spotsi)*spotblend; +} + static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp) { float temp, angle, pixsize, wsize; diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c index 21d50e4a71d..af15333ece5 100644 --- a/source/blender/ikplugin/intern/iksolver_plugin.c +++ b/source/blender/ikplugin/intern/iksolver_plugin.c @@ -334,9 +334,10 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree) IK_SetStiffness(seg, IK_Z, pchan->stiffness[2]); if (tree->stretch && (pchan->ikstretch > 0.0f)) { - float ikstretch = pchan->ikstretch * pchan->ikstretch; - IK_SetStiffness(seg, IK_TRANS_Y, MIN2(1.0f - ikstretch, 0.99f)); - IK_SetLimit(seg, IK_TRANS_Y, 0.001, 1e10); + const float ikstretch = pchan->ikstretch * pchan->ikstretch; + /* this function does its own clamping */ + IK_SetStiffness(seg, IK_TRANS_Y, 1.0f - ikstretch); + IK_SetLimit(seg, IK_TRANS_Y, IK_STRETCH_STIFF_MIN, IK_STRETCH_STIFF_MAX); } } diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp index 652b16a7c65..7a53fe247fe 100644 --- a/source/blender/ikplugin/intern/itasc_plugin.cpp +++ b/source/blender/ikplugin/intern/itasc_plugin.cpp @@ -1254,8 +1254,9 @@ static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan) joint = bone->name; joint += ":TY"; ret = arm->addSegment(joint, parent, KDL::Joint::TransY, rot[ikchan->ndof - 1]); - float ikstretch = pchan->ikstretch * pchan->ikstretch; - weight[1] = (1.0 - MIN2(1.0 - ikstretch, 0.99)); + const float ikstretch = pchan->ikstretch * pchan->ikstretch; + /* why invert twice here? */ + weight[1] = (1.0 - minf(1.0 - ikstretch, 1.0f - 0.001f)); weights.push_back(weight[1]); } if (!ret) diff --git a/source/blender/imbuf/intern/IMB_indexer.h b/source/blender/imbuf/intern/IMB_indexer.h index dc16b4d7e36..16d10a5c41c 100644 --- a/source/blender/imbuf/intern/IMB_indexer.h +++ b/source/blender/imbuf/intern/IMB_indexer.h @@ -63,7 +63,7 @@ struct anim_index { char name[1024]; int num_entries; - struct anim_index_entry * entries; + struct anim_index_entry *entries; }; struct anim_index_builder; @@ -77,9 +77,9 @@ typedef struct anim_index_builder { void (*delete_priv_data)(struct anim_index_builder * idx); void (*proc_frame)(struct anim_index_builder * idx, - unsigned char * buffer, + unsigned char *buffer, int data_size, - struct anim_index_entry * entry); + struct anim_index_entry *entry); } anim_index_builder; anim_index_builder * IMB_index_builder_create(const char * name); @@ -99,15 +99,15 @@ void IMB_index_builder_proc_frame( void IMB_index_builder_finish(anim_index_builder * fp, int rollback); -struct anim_index * IMB_indexer_open(const char * name); +struct anim_index *IMB_indexer_open(const char * name); unsigned long long IMB_indexer_get_seek_pos( - struct anim_index * idx, int frameno_index); + struct anim_index *idx, int frameno_index); unsigned long long IMB_indexer_get_seek_pos_dts( - struct anim_index * idx, int frameno_index); + struct anim_index *idx, int frameno_index); int IMB_indexer_get_frame_index(struct anim_index * idx, int frameno); -unsigned long long IMB_indexer_get_pts(struct anim_index * idx, - int frame_index); +unsigned long long IMB_indexer_get_pts(struct anim_index *idx, + int frame_index); int IMB_indexer_get_duration(struct anim_index * idx); int IMB_indexer_can_scan(struct anim_index * idx, @@ -118,12 +118,12 @@ void IMB_indexer_close(struct anim_index * idx); void IMB_free_indices(struct anim * anim); int IMB_anim_index_get_frame_index( - struct anim * anim, IMB_Timecode_Type tc, int position); + struct anim *anim, IMB_Timecode_Type tc, int position); -struct anim * IMB_anim_open_proxy( - struct anim * anim, IMB_Proxy_Size preview_size); +struct anim *IMB_anim_open_proxy( + struct anim *anim, IMB_Proxy_Size preview_size); struct anim_index * IMB_anim_open_index( - struct anim * anim, IMB_Timecode_Type tc); + struct anim *anim, IMB_Timecode_Type tc); int IMB_proxy_size_to_array_index(IMB_Proxy_Size pr_size); int IMB_timecode_to_array_index(IMB_Timecode_Type tc); diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index a27aae815da..9367511522d 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -394,7 +394,9 @@ static ImBuf *avi_fetchibuf(struct anim *anim, int position) int *tmp; int y; - if (anim == NULL) return (NULL); + if (anim == NULL) { + return NULL; + } #if defined(_WIN32) && !defined(FREE_WINDOWS) if (anim->avistreams) { @@ -418,7 +420,7 @@ static ImBuf *avi_fetchibuf(struct anim *anim, int position) AVI_get_stream(anim->avi, AVIST_VIDEO, 0)); if (tmp == NULL) { - printf("Error reading frame from AVI"); + printf("Error reading frame from AVI: '%s'\n", anim->name); IMB_freeImBuf(ibuf); return NULL; } diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c index 1b68c520336..54903c83835 100644 --- a/source/blender/imbuf/intern/divers.c +++ b/source/blender/imbuf/intern/divers.c @@ -199,7 +199,6 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from, BLI_assert(profile_to != IB_PROFILE_NONE); BLI_assert(profile_from != IB_PROFILE_NONE); - BLI_init_srgb_conversion(); if (dither) di = create_dither_context(width, dither); @@ -335,8 +334,6 @@ void IMB_buffer_float_from_byte(float *rect_to, const uchar *rect_from, BLI_assert(profile_to != IB_PROFILE_NONE); BLI_assert(profile_from != IB_PROFILE_NONE); - BLI_init_srgb_conversion(); - /* RGBA input */ for (y = 0; y < height; y++) { const uchar *from = rect_from + stride_from * y * 4; @@ -755,7 +752,7 @@ void IMB_buffer_float_clamp(float *buf, int width, int height) { int i, total = width * height * 4; for (i = 0; i < total; i++) { - buf[i] = MIN2(1.0, buf[i]); + buf[i] = minf(1.0, buf[i]); } } diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c index a0434691807..7804ee1fdf1 100644 --- a/source/blender/imbuf/intern/filter.c +++ b/source/blender/imbuf/intern/filter.c @@ -211,6 +211,10 @@ void IMB_filterN(ImBuf *out, ImBuf *in) rowlen = in->x; + /* generate 32-bit version for float images if it is not already generated by other space */ + if (in->rect == NULL) + IMB_rect_from_float(in); + for (y = 0; y < in->y; y++) { /* setup rows */ row2 = (char *)(in->rect + y * rowlen); diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index 5c389925274..e0483f70e72 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -88,7 +88,7 @@ static void pixel_from_buffer(struct ImBuf *ibuf, unsigned char **outI, float ** *outI = (unsigned char *)ibuf->rect + offset; if (ibuf->rect_float) - *outF = (float *)ibuf->rect_float + offset; + *outF = ibuf->rect_float + offset; } /************************************************************************** @@ -258,16 +258,16 @@ void bilinear_interpolation_color(struct ImBuf *in, unsigned char *outI, float * if (outF) { /* sample including outside of edges of image */ if (x1 < 0 || y1 < 0) row1 = empty; - else row1 = (float *)in->rect_float + in->x * y1 * 4 + 4 * x1; + else row1 = in->rect_float + in->x * y1 * 4 + 4 * x1; if (x1 < 0 || y2 > in->y - 1) row2 = empty; - else row2 = (float *)in->rect_float + in->x * y2 * 4 + 4 * x1; + else row2 = in->rect_float + in->x * y2 * 4 + 4 * x1; if (x2 > in->x - 1 || y1 < 0) row3 = empty; - else row3 = (float *)in->rect_float + in->x * y1 * 4 + 4 * x2; + else row3 = in->rect_float + in->x * y1 * 4 + 4 * x2; if (x2 > in->x - 1 || y2 > in->y - 1) row4 = empty; - else row4 = (float *)in->rect_float + in->x * y2 * 4 + 4 * x2; + else row4 = in->rect_float + in->x * y2 * 4 + 4 * x2; a = u - floorf(u); b = v - floorf(v); @@ -338,10 +338,10 @@ void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char *outI, fl if (outF) { /* sample including outside of edges of image */ - row1 = (float *)in->rect_float + in->x * y1 * 4 + 4 * x1; - row2 = (float *)in->rect_float + in->x * y2 * 4 + 4 * x1; - row3 = (float *)in->rect_float + in->x * y1 * 4 + 4 * x2; - row4 = (float *)in->rect_float + in->x * y2 * 4 + 4 * x2; + row1 = in->rect_float + in->x * y1 * 4 + 4 * x1; + row2 = in->rect_float + in->x * y2 * 4 + 4 * x1; + row3 = in->rect_float + in->x * y1 * 4 + 4 * x2; + row4 = in->rect_float + in->x * y2 * 4 + 4 * x2; a = u - floorf(u); b = v - floorf(v); diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c index aea120cd841..d49080d8741 100644 --- a/source/blender/imbuf/intern/jpeg.c +++ b/source/blender/imbuf/intern/jpeg.c @@ -200,7 +200,7 @@ static void memory_source(j_decompress_ptr cinfo, unsigned char *buffer, size_t #define MAKESTMT(stuff) do { stuff } while (0) #define INPUT_VARS(cinfo) \ - struct jpeg_source_mgr * datasrc = (cinfo)->src; \ + struct jpeg_source_mgr *datasrc = (cinfo)->src; \ const JOCTET * next_input_byte = datasrc->next_input_byte; \ size_t bytes_in_buffer = datasrc->bytes_in_buffer diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c index 2ba1ebf90b5..4cd50484a64 100644 --- a/source/blender/imbuf/intern/radiance_hdr.c +++ b/source/blender/imbuf/intern/radiance_hdr.c @@ -213,7 +213,7 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, size_t size, int flags) /* read in and decode the actual data */ sline = (RGBE *)MEM_mallocN(sizeof(RGBE) * width, "radhdr_read_tmpscan"); - rect_float = (float *)ibuf->rect_float; + rect_float = ibuf->rect_float; for (y = 0; y < height; y++) { ptr = freadcolrs(sline, ptr, width); diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c index 810cb88c06e..a57926f0202 100644 --- a/source/blender/imbuf/intern/scaling.c +++ b/source/blender/imbuf/intern/scaling.c @@ -1313,7 +1313,7 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy) rect += 2 * skipx; } if (do_float) { - rectf = ((float *)ibuf->rect_float) + 4 * (x - 1); + rectf = ibuf->rect_float + 4 * (x - 1); newrectf = _newrectf + 4 * (x - 1); val_af = rectf[0]; diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index fe2e218637a..a769ce742c9 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -86,7 +86,7 @@ typedef struct IDProperty { #define IDP_STRING_SUB_UTF8 0 /* default */ #define IDP_STRING_SUB_BYTE 1 /* arbitrary byte array, _not_ null terminated */ /*->flag*/ -#define IDP_FLAG_GHOST (1<<7) /* this means the propery is set but RNA will return +#define IDP_FLAG_GHOST (1<<7) /* this means the property is set but RNA will return * false when checking 'RNA_property_is_set', * currently this is a runtime flag */ @@ -238,11 +238,11 @@ typedef struct PreviewImage { #define LIB_LOCAL 0 #define LIB_EXTERN 1 #define LIB_INDIRECT 2 -#define LIB_TEST 8 -#define LIB_TESTEXT (LIB_TEST | LIB_EXTERN) -#define LIB_TESTIND (LIB_TEST | LIB_INDIRECT) +#define LIB_NEED_EXPAND 8 +#define LIB_TESTEXT (LIB_NEED_EXPAND | LIB_EXTERN) +#define LIB_TESTIND (LIB_NEED_EXPAND | LIB_INDIRECT) #define LIB_READ 16 -#define LIB_NEEDLINK 32 +#define LIB_NEED_LINK 32 #define LIB_NEW 256 #define LIB_FAKEUSER 512 diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index 60bc3ee0ffc..e7322263a6b 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -173,7 +173,8 @@ enum { MASK_BLEND_DARKEN = 3, MASK_BLEND_MUL = 4, MASK_BLEND_REPLACE = 5, - MASK_BLEND_DIFFERENCE = 6 + MASK_BLEND_DIFFERENCE = 6, + MASK_BLEND_MERGE = 7 }; /* masklay->blend_flag */ diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index 2b3719a10b5..940c5c5f30b 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -154,7 +154,7 @@ typedef struct Material { struct bNodeTree *nodetree; struct Ipo *ipo DNA_DEPRECATED; /* old animation system, deprecated for 2.5 */ struct Group *group; /* light group */ - struct PreviewImage * preview; + struct PreviewImage *preview; /* dynamic properties */ float friction, fh, reflect; diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index a7f854f603c..731f44d2564 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -211,6 +211,11 @@ typedef struct bNode { /* automatic flag for nodes included in transforms */ #define NODE_TRANSFORM (1<<13) /* node is active texture */ + + /* note: take care with this flag since its possible it gets + * `stuck` inside/outside the active group - which makes buttons + * window texture not update, we try to avoid it by clearing the + * flag when toggling group editing - Campbell */ #define NODE_ACTIVE_TEXTURE (1<<14) /* use a custom color for the node */ #define NODE_CUSTOM_COLOR (1<<15) @@ -370,8 +375,13 @@ enum { }; enum { - CMP_NODEFLAG_MASK_AA = (1 << 0), - CMP_NODEFLAG_MASK_NO_FEATHER = (1 << 1) + CMP_NODEFLAG_MASK_AA = (1 << 0), + CMP_NODEFLAG_MASK_NO_FEATHER = (1 << 1), + CMP_NODEFLAG_MASK_MOTION_BLUR = (1 << 2), + + /* we may want multiple aspect options, exposed as an rna enum */ + CMP_NODEFLAG_MASK_FIXED = (1 << 8), + CMP_NODEFLAG_MASK_FIXED_SCENE = (1 << 9) }; enum { @@ -579,6 +589,10 @@ typedef struct NodeDilateErode { char pad[7]; } NodeDilateErode; +typedef struct NodeMask { + int size_x, size_y; +} NodeMask; + typedef struct NodeTexBase { TexMapping tex_mapping; ColorMapping color_mapping; @@ -748,4 +762,6 @@ typedef struct NodeTrackPosData { #define CMP_NODE_BLUR_ASPECT_Y 1 #define CMP_NODE_BLUR_ASPECT_X 2 +#define CMP_NODE_MASK_MBLUR_SAMPLES_MAX 64 + #endif diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 02a7d0da325..489e1c936c0 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -288,7 +288,7 @@ typedef struct ImageFormatData { #define R_IMF_IMTYPE_AVIRAW 15 #define R_IMF_IMTYPE_AVIJPEG 16 #define R_IMF_IMTYPE_PNG 17 -#define R_IMF_IMTYPE_AVICODEC 18 +/* #define R_IMF_IMTYPE_AVICODEC 18 */ /* avicodec is nomore */ #define R_IMF_IMTYPE_QUICKTIME 19 #define R_IMF_IMTYPE_BMP 20 #define R_IMF_IMTYPE_RADHDR 21 diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 7e1094ef93b..b9603e2cdb1 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -513,6 +513,15 @@ typedef enum eSpaceSeq_Proxy_RenderSize { SEQ_PROXY_RENDER_SIZE_FULL = 100 } eSpaceSeq_Proxy_RenderSize; +typedef struct MaskSpaceInfo +{ + /* **** mask editing **** */ + struct Mask *mask; + /* draw options */ + char draw_flag; + char draw_type; + char pad3[6]; +} MaskSpaceInfo; /* File Selector ========================================== */ @@ -669,7 +678,7 @@ typedef struct SpaceImage { struct Image *image; struct ImageUser iuser; - struct CurveMapping *cumap; + struct CurveMapping *cumap; struct Scopes scopes; /* histogram waveform and vectorscope */ struct Histogram sample_line_hist; /* sample line histogram */ @@ -681,14 +690,17 @@ typedef struct SpaceImage { float zoom; /* user defined zoom level */ float centx, centy; /* storage for offset while render drawing */ - short curtile; /* the currently active tile of the image when tile is enabled, is kept in sync with the active faces tile */ + char mode; /* view/paint/mask */ + char pin; short pad; + short curtile; /* the currently active tile of the image when tile is enabled, is kept in sync with the active faces tile */ short lock; - short pin; char dt_uv; /* UV draw type */ char sticky; /* sticky selection type */ char dt_uvstretch; char around; + + MaskSpaceInfo mask_info; } SpaceImage; @@ -706,6 +718,13 @@ typedef enum eSpaceImage_UVDT_Stretch { SI_UVDT_STRETCH_AREA = 1, } eSpaceImage_UVDT_Stretch; +/* SpaceImage->mode */ +typedef enum eSpaceImage_Mode { + SI_MODE_VIEW = 0, + SI_MODE_PAINT = 1, + SI_MODE_MASK = 2 /* note: mesh edit mode overrides mask */ +} eSpaceImage_Mode; + /* SpaceImage->sticky * Note DISABLE should be 0, however would also need to re-arrange icon order, * also, sticky loc is the default mode so this means we don't need to 'do_versons' */ @@ -717,15 +736,15 @@ typedef enum eSpaceImage_Sticky { /* SpaceImage->flag */ typedef enum eSpaceImage_Flag { - SI_BE_SQUARE = (1 << 0), - SI_EDITTILE = (1 << 1), +/* SI_BE_SQUARE = (1 << 0), */ /* deprecated */ + SI_EDITTILE = (1 << 1), /* XXX - not used but should be? */ SI_CLIP_UV = (1 << 2), - SI_DRAWTOOL = (1 << 3), +/* SI_DRAWTOOL = (1 << 3), */ /* deprecated */ SI_NO_DRAWFACES = (1 << 4), SI_DRAWSHADOW = (1 << 5), -/* SI_SELACTFACE = (1 << 6), */ /* deprecated */ - SI_DEPRECATED2 = (1 << 7), - SI_DEPRECATED3 = (1 << 8), /* stick UV selection to mesh vertex (UVs wont always be touching) */ +/* SI_SELACTFACE = (1 << 6), */ /* deprecated */ +/* SI_DEPRECATED2 = (1 << 7), */ /* deprecated */ +/* SI_DEPRECATED3 = (1 << 8), */ /* deprecated */ SI_COORDFLOATS = (1 << 9), SI_PIXELSNAP = (1 << 10), SI_LIVE_UNWRAP = (1 << 11), @@ -737,8 +756,8 @@ typedef enum eSpaceImage_Flag { SI_PREVSPACE = (1 << 15), SI_FULLWINDOW = (1 << 16), - SI_DEPRECATED4 = (1 << 17), - SI_DEPRECATED5 = (1 << 18), +/* SI_DEPRECATED4 = (1 << 17), */ /* deprecated */ +/* SI_DEPRECATED5 = (1 << 18), */ /* deprecated */ /* this means that the image is drawn until it reaches the view edge, * in the image view, its unrelated to the 'tile' mode for texface @@ -746,7 +765,7 @@ typedef enum eSpaceImage_Flag { SI_DRAW_TILE = (1 << 19), SI_SMOOTH_UV = (1 << 20), SI_DRAW_STRETCH = (1 << 21), -/* SI_DISPGP = (1 << 22), */ /* DEPRECATED */ +/* SI_DISPGP = (1 << 22), */ /* deprecated */ SI_DRAW_OTHER = (1 << 23), SI_COLOR_CORRECTION = (1 << 24), @@ -884,6 +903,7 @@ typedef enum eSpaceNode_Flag { SNODE_SHOW_B = (1 << 9), SNODE_AUTO_RENDER = (1 << 5), SNODE_SHOW_HIGHLIGHT = (1 << 6), + SNODE_USE_HIDDEN_PREVIEW = (1 << 10), } eSpaceNode_Flag; /* snode->texfrom */ @@ -1012,12 +1032,7 @@ typedef struct SpaceClip { int around, pad4; /* pivot point for transforms */ - /* **** mask editing **** */ - struct Mask *mask; - /* draw options */ - char mask_draw_flag; - char mask_draw_type; - char pad3[6]; + MaskSpaceInfo mask_info; } SpaceClip; /* SpaceClip->flag */ @@ -1101,4 +1116,6 @@ typedef enum eSpace_Type { SPACEICONMAX = SPACE_CLIP } eSpace_Type; +#define IMG_SIZE_FALLBACK 256 + #endif diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 5257fb6e2cf..9fdd9216549 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -244,7 +244,7 @@ typedef struct Tex { struct Image *ima; struct ColorBand *coba; struct EnvMap *env; - struct PreviewImage * preview; + struct PreviewImage *preview; struct PointDensity *pd; struct VoxelData *vd; struct OceanTex *ot; diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 4e9ec0da092..7f52956d1e0 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -215,7 +215,7 @@ typedef struct ThemeSpace { char extra_edge_len[4], extra_face_angle[4], extra_face_area[4], pad3[4]; char normal[4]; char vertex_normal[4]; - char bone_solid[4], bone_pose[4]; + char bone_solid[4], bone_pose[4], bone_pose_active[4]; char strip[4], strip_select[4]; char cframe[4]; @@ -264,8 +264,6 @@ typedef struct ThemeSpace { char skin_root[4]; /* Skin modifier root color */ - int pad4; - /* NLA */ char anim_active[4]; /* Active Action + Summary Channel */ char anim_non_active[4]; /* Active Action = NULL */ diff --git a/source/blender/makesdna/DNA_vfont_types.h b/source/blender/makesdna/DNA_vfont_types.h index 299a6540f40..3cccfe6a19f 100644 --- a/source/blender/makesdna/DNA_vfont_types.h +++ b/source/blender/makesdna/DNA_vfont_types.h @@ -45,7 +45,7 @@ typedef struct VFont { char name[1024]; /* 1024 = FILE_MAX */ struct VFontData *data; - struct PackedFile * packedfile; + struct PackedFile *packedfile; } VFont; /* *************** FONT ****************** */ diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 6436d04f54f..a4d9261ad5a 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -291,7 +291,7 @@ static int add_name(const char *str) if (str[0] == '(' && str[1] == '*') { /* we handle function pointer and special array cases here, e.g. * void (*function)(...) and float (*array)[..]. the array case - * name is still converted to (array*)() though because it is that + * name is still converted to (array *)() though because it is that * way in old dna too, and works correct with elementsize() */ int isfuncptr = (strchr(str + 1, '(')) != NULL; diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 7f851c939d2..897e784c8e4 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -76,6 +76,7 @@ EnumPropertyItem id_type_items[] = { #ifdef RNA_RUNTIME +#include "BKE_font.h" #include "BKE_idprop.h" #include "BKE_library.h" #include "BKE_animsys.h" @@ -109,12 +110,12 @@ static int rna_ID_name_editable(PointerRNA *ptr) ID *id = (ID *)ptr->data; if (GS(id->name) == ID_VF) { - VFont *vf = (VFont *)id; - if (strcmp(vf->name, FO_BUILTIN_NAME) == 0) - return 0; + VFont *vfont = (VFont *)id; + if (BKE_vfont_is_builtin(vfont)) + return FALSE; } - return 1; + return TRUE; } short RNA_type_to_ID_code(StructRNA *type) diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 8e9c0dbc4c4..5b5367654eb 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -2590,7 +2590,7 @@ void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr PointerRNA RNA_property_pointer_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop)) { - /*PointerPropertyRNA *pprop = (PointerPropertyRNA*)prop; */ + /*PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop; */ /* BLI_assert(RNA_property_type(prop) == PROP_POINTER); */ @@ -2729,7 +2729,7 @@ int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop) void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr) { IDProperty *idprop; -/* CollectionPropertyRNA *cprop = (CollectionPropertyRNA*)prop; */ +/* CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop; */ BLI_assert(RNA_property_type(prop) == PROP_COLLECTION); @@ -2788,7 +2788,7 @@ void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key) { IDProperty *idprop; -/* CollectionPropertyRNA *cprop = (CollectionPropertyRNA*)prop; */ +/* CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop; */ BLI_assert(RNA_property_type(prop) == PROP_COLLECTION); @@ -3035,11 +3035,11 @@ int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, Proper #define RAW_GET(dtype, var, raw, a) \ { \ switch (raw.type) { \ - case PROP_RAW_CHAR: var = (dtype)((char*)raw.array)[a]; break; \ - case PROP_RAW_SHORT: var = (dtype)((short*)raw.array)[a]; break; \ - case PROP_RAW_INT: var = (dtype)((int*)raw.array)[a]; break; \ - case PROP_RAW_FLOAT: var = (dtype)((float*)raw.array)[a]; break; \ - case PROP_RAW_DOUBLE: var = (dtype)((double*)raw.array)[a]; break; \ + case PROP_RAW_CHAR: var = (dtype)((char *)raw.array)[a]; break; \ + case PROP_RAW_SHORT: var = (dtype)((short *)raw.array)[a]; break; \ + case PROP_RAW_INT: var = (dtype)((int *)raw.array)[a]; break; \ + case PROP_RAW_FLOAT: var = (dtype)((float *)raw.array)[a]; break; \ + case PROP_RAW_DOUBLE: var = (dtype)((double *)raw.array)[a]; break; \ default: var = (dtype)0; \ } \ } (void)0 @@ -3047,11 +3047,11 @@ int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, Proper #define RAW_SET(dtype, raw, a, var) \ { \ switch (raw.type) { \ - case PROP_RAW_CHAR: ((char*)raw.array)[a] = (char)var; break; \ - case PROP_RAW_SHORT: ((short*)raw.array)[a] = (short)var; break; \ - case PROP_RAW_INT: ((int*)raw.array)[a] = (int)var; break; \ - case PROP_RAW_FLOAT: ((float*)raw.array)[a] = (float)var; break; \ - case PROP_RAW_DOUBLE: ((double*)raw.array)[a] = (double)var; break; \ + case PROP_RAW_CHAR: ((char *)raw.array)[a] = (char)var; break; \ + case PROP_RAW_SHORT: ((short *)raw.array)[a] = (short)var; break; \ + case PROP_RAW_INT: ((int *)raw.array)[a] = (int)var; break; \ + case PROP_RAW_FLOAT: ((float *)raw.array)[a] = (float)var; break; \ + case PROP_RAW_DOUBLE: ((double *)raw.array)[a] = (double)var; break; \ default: break; \ } \ } (void)0 diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c index 3b4f87d8b95..5f1ce4f2773 100644 --- a/source/blender/makesrna/intern/rna_cloth.c +++ b/source/blender/makesrna/intern/rna_cloth.c @@ -58,7 +58,7 @@ static void rna_cloth_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerR static void rna_cloth_pinning_changed(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { Object *ob = (Object *)ptr->id.data; -/* ClothSimSettings *settings = (ClothSimSettings*)ptr->data; */ +/* ClothSimSettings *settings = (ClothSimSettings *)ptr->data; */ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); cloth_free_modifier(clmd); diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index c333c56a6b8..b2a2bab0f4b 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -155,56 +155,38 @@ static StructRNA *rna_Curve_refine(PointerRNA *ptr) static void rna_BezTriple_handle1_get(PointerRNA *ptr, float *values) { - BezTriple *bt = (BezTriple *)ptr->data; - - values[0] = bt->vec[0][0]; - values[1] = bt->vec[0][1]; - values[2] = bt->vec[0][2]; + BezTriple *bezt = (BezTriple *)ptr->data; + copy_v3_v3(values, bezt->vec[0]); } static void rna_BezTriple_handle1_set(PointerRNA *ptr, const float *values) { - BezTriple *bt = (BezTriple *)ptr->data; - - bt->vec[0][0] = values[0]; - bt->vec[0][1] = values[1]; - bt->vec[0][2] = values[2]; + BezTriple *bezt = (BezTriple *)ptr->data; + copy_v3_v3(bezt->vec[0], values); } static void rna_BezTriple_handle2_get(PointerRNA *ptr, float *values) { - BezTriple *bt = (BezTriple *)ptr->data; - - values[0] = bt->vec[2][0]; - values[1] = bt->vec[2][1]; - values[2] = bt->vec[2][2]; + BezTriple *bezt = (BezTriple *)ptr->data; + copy_v3_v3(values, bezt->vec[2]); } static void rna_BezTriple_handle2_set(PointerRNA *ptr, const float *values) { - BezTriple *bt = (BezTriple *)ptr->data; - - bt->vec[2][0] = values[0]; - bt->vec[2][1] = values[1]; - bt->vec[2][2] = values[2]; + BezTriple *bezt = (BezTriple *)ptr->data; + copy_v3_v3(bezt->vec[2], values); } static void rna_BezTriple_ctrlpoint_get(PointerRNA *ptr, float *values) { - BezTriple *bt = (BezTriple *)ptr->data; - - values[0] = bt->vec[1][0]; - values[1] = bt->vec[1][1]; - values[2] = bt->vec[1][2]; + BezTriple *bezt = (BezTriple *)ptr->data; + copy_v3_v3(values, bezt->vec[1]); } static void rna_BezTriple_ctrlpoint_set(PointerRNA *ptr, const float *values) { - BezTriple *bt = (BezTriple *)ptr->data; - - bt->vec[1][0] = values[0]; - bt->vec[1][1] = values[1]; - bt->vec[1][2] = values[2]; + BezTriple *bezt = (BezTriple *)ptr->data; + copy_v3_v3(bezt->vec[1], values); } static void rna_Curve_texspace_set(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c index 6739e5b71fa..4f9f2009a14 100644 --- a/source/blender/makesrna/intern/rna_dynamicpaint.c +++ b/source/blender/makesrna/intern/rna_dynamicpaint.c @@ -170,7 +170,7 @@ static PointerRNA rna_PaintSurface_active_get(PointerRNA *ptr) static void rna_DynamicPaint_surfaces_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { DynamicPaintCanvasSettings *canvas = (DynamicPaintCanvasSettings *)ptr->data; - /*rna_iterator_array_begin(iter, (void*)canvas->surfaces, sizeof(PaintSurface), canvas->totsur, 0, 0); */ + /*rna_iterator_array_begin(iter, (void *)canvas->surfaces, sizeof(PaintSurface), canvas->totsur, 0, 0); */ rna_iterator_listbase_begin(iter, &canvas->surfaces, NULL); } diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c index c98e1f3312b..96c5ff991f6 100644 --- a/source/blender/makesrna/intern/rna_main.c +++ b/source/blender/makesrna/intern/rna_main.c @@ -255,7 +255,7 @@ static void rna_Main_movieclips_begin(CollectionPropertyIterator *iter, PointerR static void rna_Main_masks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { - Main *bmain = (Main*)ptr->data; + Main *bmain = (Main *)ptr->data; rna_iterator_listbase_begin(iter, &bmain->mask, NULL); } diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index 2987057aeb6..9ee2bb99b4e 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -108,21 +108,21 @@ static void rna_Mask_update_parent(Main *bmain, Scene *scene, PointerRNA *ptr) /* note: this function exists only to avoid id refcounting */ static void rna_MaskParent_id_set(PointerRNA *ptr, PointerRNA value) { - MaskParent *mpar = (MaskParent*) ptr->data; + MaskParent *mpar = (MaskParent *) ptr->data; mpar->id = value.data; } static StructRNA *rna_MaskParent_id_typef(PointerRNA *ptr) { - MaskParent *mpar = (MaskParent*) ptr->data; + MaskParent *mpar = (MaskParent *) ptr->data; return ID_code_to_RNA_type(mpar->id_type); } static void rna_MaskParent_id_type_set(PointerRNA *ptr, int value) { - MaskParent *mpar = (MaskParent*) ptr->data; + MaskParent *mpar = (MaskParent *) ptr->data; /* change ID-type to the new type */ mpar->id_type = value; @@ -248,67 +248,49 @@ static void rna_MaskLayer_active_spline_point_set(PointerRNA *ptr, PointerRNA va static void rna_MaskSplinePoint_handle1_get(PointerRNA *ptr, float *values) { - MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + MaskSplinePoint *point = (MaskSplinePoint *) ptr->data; BezTriple *bezt = &point->bezt; - - values[0] = bezt->vec[0][0]; - values[1] = bezt->vec[0][1]; - values[2] = bezt->vec[0][2]; + copy_v2_v2(values, bezt->vec[0]); } static void rna_MaskSplinePoint_handle1_set(PointerRNA *ptr, const float *values) { - MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + MaskSplinePoint *point = (MaskSplinePoint *) ptr->data; BezTriple *bezt = &point->bezt; - - bezt->vec[0][0] = values[0]; - bezt->vec[0][1] = values[1]; - bezt->vec[0][2] = values[2]; + copy_v2_v2(bezt->vec[0], values); } static void rna_MaskSplinePoint_handle2_get(PointerRNA *ptr, float *values) { - MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + MaskSplinePoint *point = (MaskSplinePoint *) ptr->data; BezTriple *bezt = &point->bezt; - - values[0] = bezt->vec[2][0]; - values[1] = bezt->vec[2][1]; - values[2] = bezt->vec[2][2]; + copy_v2_v2(values, bezt->vec[2]); } static void rna_MaskSplinePoint_handle2_set(PointerRNA *ptr, const float *values) { - MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + MaskSplinePoint *point = (MaskSplinePoint *) ptr->data; BezTriple *bezt = &point->bezt; - - bezt->vec[2][0] = values[0]; - bezt->vec[2][1] = values[1]; - bezt->vec[2][2] = values[2]; + copy_v2_v2(bezt->vec[2], values); } static void rna_MaskSplinePoint_ctrlpoint_get(PointerRNA *ptr, float *values) { - MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + MaskSplinePoint *point = (MaskSplinePoint *) ptr->data; BezTriple *bezt = &point->bezt; - - values[0] = bezt->vec[1][0]; - values[1] = bezt->vec[1][1]; - values[2] = bezt->vec[1][2]; + copy_v2_v2(values, bezt->vec[1]); } static void rna_MaskSplinePoint_ctrlpoint_set(PointerRNA *ptr, const float *values) { - MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + MaskSplinePoint *point = (MaskSplinePoint *) ptr->data; BezTriple *bezt = &point->bezt; - - bezt->vec[1][0] = values[0]; - bezt->vec[1][1] = values[1]; - bezt->vec[1][2] = values[2]; + copy_v2_v2(bezt->vec[1], values); } static int rna_MaskSplinePoint_handle_type_get(PointerRNA *ptr) { - MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + MaskSplinePoint *point = (MaskSplinePoint *) ptr->data; BezTriple *bezt = &point->bezt; return bezt->h1; @@ -316,7 +298,7 @@ static int rna_MaskSplinePoint_handle_type_get(PointerRNA *ptr) static void rna_MaskSplinePoint_handle_type_set(PointerRNA *ptr, int value) { - MaskSplinePoint *point = (MaskSplinePoint*) ptr->data; + MaskSplinePoint *point = (MaskSplinePoint *) ptr->data; BezTriple *bezt = &point->bezt; bezt->h1 = bezt->h2 = value; @@ -324,7 +306,7 @@ static void rna_MaskSplinePoint_handle_type_set(PointerRNA *ptr, int value) /* ** API ** */ -static MaskLayer *rna_Mask_layer_new(Mask *mask, const char *name) +static MaskLayer *rna_Mask_layers_new(Mask *mask, const char *name) { MaskLayer *masklay = BKE_mask_layer_new(mask, name); @@ -333,16 +315,28 @@ static MaskLayer *rna_Mask_layer_new(Mask *mask, const char *name) return masklay; } -void rna_Mask_layer_remove(Mask *mask, MaskLayer *masklay) +void rna_Mask_layers_remove(Mask *mask, ReportList *reports, MaskLayer *masklay) { + if (BLI_findindex(&mask->masklayers, masklay) == -1) { + BKE_reportf(reports, RPT_ERROR, "MaskLayer '%s' not found in mask '%s'", masklay->name, mask->id.name + 2); + return; + } + BKE_mask_layer_remove(mask, masklay); WM_main_add_notifier(NC_MASK | NA_EDITED, mask); } +static void rna_Mask_layers_clear(Mask *mask) +{ + BKE_mask_layer_free_list(&mask->masklayers); + + WM_main_add_notifier(NC_MASK | NA_EDITED, mask); +} + static void rna_MaskLayer_spline_add(ID *id, MaskLayer *masklay, int number) { - Mask *mask = (Mask*) id; + Mask *mask = (Mask *) id; int i; for (i = 0; i < number; i++) @@ -467,19 +461,19 @@ static void rna_def_maskSplinePoint(BlenderRNA *brna) /* Vector values */ prop = RNA_def_property(srna, "handle_left", PROP_FLOAT, PROP_TRANSLATION); - RNA_def_property_array(prop, 3); + RNA_def_property_array(prop, 2); RNA_def_property_float_funcs(prop, "rna_MaskSplinePoint_handle1_get", "rna_MaskSplinePoint_handle1_set", NULL); RNA_def_property_ui_text(prop, "Handle 1", "Coordinates of the first handle"); RNA_def_property_update(prop, 0, "rna_Mask_update_data"); prop = RNA_def_property(srna, "co", PROP_FLOAT, PROP_TRANSLATION); - RNA_def_property_array(prop, 3); + RNA_def_property_array(prop, 2); RNA_def_property_float_funcs(prop, "rna_MaskSplinePoint_ctrlpoint_get", "rna_MaskSplinePoint_ctrlpoint_set", NULL); RNA_def_property_ui_text(prop, "Control Point", "Coordinates of the control point"); RNA_def_property_update(prop, 0, "rna_Mask_update_data"); prop = RNA_def_property(srna, "handle_right", PROP_FLOAT, PROP_TRANSLATION); - RNA_def_property_array(prop, 3); + RNA_def_property_array(prop, 2); RNA_def_property_float_funcs(prop, "rna_MaskSplinePoint_handle2_get", "rna_MaskSplinePoint_handle2_set", NULL); RNA_def_property_ui_text(prop, "Handle 2", "Coordinates of the second handle"); RNA_def_property_update(prop, 0, "rna_Mask_update_data"); @@ -579,6 +573,7 @@ static void rna_def_maskSpline(BlenderRNA *brna) static void rna_def_mask_layer(BlenderRNA *brna) { static EnumPropertyItem masklay_blend_mode_items[] = { + {MASK_BLEND_MERGE, "MERGE", 0, "Merge", ""}, {MASK_BLEND_ADD, "ADD", 0, "Add", ""}, {MASK_BLEND_SUBTRACT, "SUBTRACT", 0, "Subtract", ""}, {MASK_BLEND_LIGHTEN, "LIGHTEN", 0, "Lighten", ""}, @@ -680,16 +675,21 @@ static void rna_def_masklayers(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_struct_sdna(srna, "Mask"); RNA_def_struct_ui_text(srna, "Mask Layers", "Collection of layers used by mask"); - func = RNA_def_function(srna, "new", "rna_Mask_layer_new"); + func = RNA_def_function(srna, "new", "rna_Mask_layers_new"); RNA_def_function_ui_description(func, "Add layer to this mask"); RNA_def_string(func, "name", "", 0, "Name", "Name of new layer"); parm = RNA_def_pointer(func, "layer", "MaskLayer", "", "New mask layer"); RNA_def_function_return(func, parm); - func = RNA_def_function(srna, "remove", "rna_Mask_layer_remove"); + func = RNA_def_function(srna, "remove", "rna_Mask_layers_remove"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove layer from this mask"); RNA_def_pointer(func, "layer", "MaskLayer", "", "Shape to be removed"); + /* clear all layers */ + func = RNA_def_function(srna, "clear", "rna_Mask_layers_clear"); + RNA_def_function_ui_description(func, "Remove all mask layers"); + /* active layer */ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MaskLayer"); @@ -731,7 +731,7 @@ static void rna_def_mask(BlenderRNA *brna) RNA_def_property_int_funcs(prop, NULL, "rna_Mask_start_frame_set", NULL); RNA_def_property_range(prop, MINFRAME, MAXFRAME); RNA_def_property_ui_text(prop, "Start Frame", "First frame of the mask (used for sequencer)"); - RNA_def_property_update(prop, NC_SCENE | ND_FRAME_RANGE, NULL); + RNA_def_property_update(prop, NC_MASK | ND_DRAW, NULL); prop = RNA_def_property(srna, "frame_end", PROP_INT, PROP_TIME); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); @@ -739,7 +739,7 @@ static void rna_def_mask(BlenderRNA *brna) RNA_def_property_int_funcs(prop, NULL, "rna_Mask_end_frame_set", NULL); RNA_def_property_range(prop, MINFRAME, MAXFRAME); RNA_def_property_ui_text(prop, "End Frame", "Final frame of the mask (used for sequencer)"); - RNA_def_property_update(prop, NC_SCENE | ND_FRAME_RANGE, NULL); + RNA_def_property_update(prop, NC_MASK | ND_DRAW, NULL); /* pointers */ rna_def_animdata_common(srna); diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c index 573e27b52c2..8b2b741b83e 100644 --- a/source/blender/makesrna/intern/rna_movieclip.c +++ b/source/blender/makesrna/intern/rna_movieclip.c @@ -287,7 +287,7 @@ static void rna_def_movieclip(BlenderRNA *brna) RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* start_frame */ - prop = RNA_def_property(srna, "start_frame", PROP_INT, PROP_NONE); + prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "start_frame"); RNA_def_property_ui_text(prop, "Start Frame", "Global scene frame number at which this movie starts playing " "(affects all data associated with a clip)"); diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index b47f957ac76..16753961852 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -362,7 +362,7 @@ static void rna_NlaStrip_remove(NlaTrack *track, bContext *C, ReportList *report */ void rna_NlaTrack_solo_set(PointerRNA *ptr, int value) { - NlaTrack *data = (NlaTrack*)ptr->data; + NlaTrack *data = (NlaTrack *)ptr->data; AnimData *adt = BKE_animdata_from_id(ptr->id.data); NlaTrack *nt; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 055c8dcbebb..472b0693ae5 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -24,7 +24,6 @@ * \ingroup RNA */ - #include <stdlib.h> #include <string.h> @@ -225,7 +224,8 @@ static StructRNA *rna_Node_refine(struct PointerRNA *ptr) return &RNA_NodeWhileLoop; case NODE_FRAME: return &RNA_NodeFrame; - + case NODE_REROUTE: + return &RNA_NodeReroute; default: return &RNA_Node; } @@ -1054,11 +1054,11 @@ static void init(void) #include "rna_nodetree_types.h" - reg_node(NODE_GROUP, Category_GroupNode, "GROUP", "NodeGroup", "Node", "Group", ""); - reg_node(NODE_FORLOOP, Category_LoopNode, "FORLOOP", "NodeForLoop", "Node", "ForLoop", ""); - reg_node(NODE_WHILELOOP, Category_LoopNode, "WHILELOOP", "NodeWhileLoop", "Node", "WhileLoop", ""); - reg_node(NODE_FRAME, Category_LayoutNode, "FRAME", "NodeFrame", "Node", "Frame", ""); - reg_node(NODE_REROUTE, Category_LayoutNode, "REROUTE", "NodeReroute", "Node", "Reroute", ""); + reg_node(NODE_GROUP, Category_GroupNode, "GROUP", "NodeGroup", "SpecialNode", "Group", ""); + reg_node(NODE_FORLOOP, Category_LoopNode, "FORLOOP", "NodeForLoop", "SpecialNode", "ForLoop", ""); + reg_node(NODE_WHILELOOP, Category_LoopNode, "WHILELOOP", "NodeWhileLoop", "SpecialNode", "WhileLoop", ""); + reg_node(NODE_FRAME, Category_LayoutNode, "FRAME", "NodeFrame", "SpecialNode", "Frame", ""); + reg_node(NODE_REROUTE, Category_LayoutNode, "REROUTE", "NodeReroute", "SpecialNode", "Reroute", ""); } static StructRNA *def_node(BlenderRNA *brna, int node_id) @@ -3137,6 +3137,13 @@ static void def_cmp_mask(StructRNA *srna) { PropertyRNA *prop; + static EnumPropertyItem aspect_type_items[] = { + {0, "SCENE", 0, "Scene Size", ""}, + {CMP_NODEFLAG_MASK_FIXED, "FIXED", 0, "Fixed", "Use pixel size for the buffer"}, + {CMP_NODEFLAG_MASK_FIXED_SCENE, "FIXED_SCENE", 0, "Fixed/Scene", "Pixel size scaled by scene percentage"}, + {0, NULL, 0, NULL, NULL} + }; + prop = RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "id"); RNA_def_property_struct_type(prop, "Mask"); @@ -3152,6 +3159,43 @@ static void def_cmp_mask(StructRNA *srna) RNA_def_property_boolean_negative_sdna(prop, NULL, "custom1", CMP_NODEFLAG_MASK_NO_FEATHER); RNA_def_property_ui_text(prop, "Feather", "Use feather information from the mask"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "use_motion_blur", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "custom1", CMP_NODEFLAG_MASK_MOTION_BLUR); + RNA_def_property_ui_text(prop, "Motion Blur", "Use feather information from the mask"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "motion_blur_samples", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "custom2"); + RNA_def_property_range(prop, 1, CMP_NODE_MASK_MBLUR_SAMPLES_MAX); + RNA_def_property_ui_text(prop, "Samples", "Number of motion blur samples"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "custom3"); + RNA_def_property_range(prop, 0.0, 1.0f); + RNA_def_property_ui_text(prop, "Shutter", "Exposure for motion blur as a factor of FPS"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + + prop = RNA_def_property(srna, "size_source", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, aspect_type_items); + RNA_def_property_ui_text(prop, "Size Source", "Where to get the mask size from for aspect/size information"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + + RNA_def_struct_sdna_from(srna, "NodeMask", "storage"); + + prop = RNA_def_property(srna, "size_x", PROP_INT, PROP_NONE); + RNA_def_property_range(prop, 1.0f, 10000.0f); + RNA_def_property_ui_text(prop, "X", ""); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "size_y", PROP_INT, PROP_NONE); + RNA_def_property_range(prop, 1.0f, 10000.0f); + RNA_def_property_ui_text(prop, "Y", ""); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } static void dev_cmd_transform(StructRNA *srna) @@ -3662,6 +3706,13 @@ static void def_cmp_trackpos(StructRNA *srna) { PropertyRNA *prop; + static EnumPropertyItem position_items[] = { + {0, "ABSOLUTE", 0, "Absolute", "Output absolute position of a marker"}, + {1, "RELATIVE_START", 0, "Relative Start", "Output position of a marker relative to first marker of a track"}, + {2, "RELATIVE_FRAME", 0, "Relative Frame", "Output position of a marker relative to marker at given frame number"}, + {0, NULL, 0, NULL, NULL} + }; + prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "id"); RNA_def_property_struct_type(prop, "MovieClip"); @@ -3669,9 +3720,15 @@ static void def_cmp_trackpos(StructRNA *srna) RNA_def_property_ui_text(prop, "Movie Clip", ""); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); - prop = RNA_def_property(srna, "use_relative", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1); - RNA_def_property_ui_text(prop, "Relative", "Return relative position to first track's marker"); + prop = RNA_def_property(srna, "position", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, position_items); + RNA_def_property_ui_text(prop, "Position", "Which marker position to use for output"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "relative_frame", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "custom2"); + RNA_def_property_ui_text(prop, "Frame", "Frame to be used for relative position"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); RNA_def_struct_sdna_from(srna, "NodeTrackPosData", "storage"); @@ -3807,6 +3864,30 @@ static void rna_def_texture_node(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Type", ""); } +static void rna_def_special_node(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem specific_node_type_items[] = { + {NODE_GROUP, "GROUP", ICON_NODE, "Group", ""}, + {NODE_FORLOOP, "FORLOOP", ICON_NODE, "For Loop", ""}, + {NODE_WHILELOOP, "WHILELOOP", ICON_NODE, "While Loop", ""}, + {NODE_FRAME, "FRAME", ICON_NODE, "Frame", ""}, + {NODE_REROUTE, "REROUTE", ICON_NODE, "Reroute", ""}, + {0, NULL, 0, NULL, NULL} + }; + + srna = RNA_def_struct(brna, "SpecialNode", "Node"); + RNA_def_struct_ui_text(srna, "Special Node", ""); + RNA_def_struct_sdna(srna, "bNode"); + + prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_enum_items(prop, specific_node_type_items); + RNA_def_property_ui_text(prop, "Type", ""); +} + /* -------------------------------------------------------------------------- */ static void rna_def_nodetree_link_api(BlenderRNA *brna, PropertyRNA *cprop) @@ -4365,7 +4446,7 @@ static void rna_def_texture_nodetree(BlenderRNA *brna) static void define_specific_node(BlenderRNA *brna, int id, void (*func)(StructRNA *)) { StructRNA *srna = def_node(brna, id); - + if (func) func(srna); } @@ -4392,6 +4473,7 @@ void RNA_def_nodetree(BlenderRNA *brna) rna_def_shader_node(brna); rna_def_compositor_node(brna); rna_def_texture_node(brna); + rna_def_special_node(brna); rna_def_composite_nodetree(brna); rna_def_shader_nodetree(brna); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index ce6b028beb5..7aedbf40eba 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1759,7 +1759,7 @@ static void rna_def_object_modifiers(BlenderRNA *brna, PropertyRNA *cprop) /* RNA_def_property_collection_active(prop, prop_act); */ #endif - /* add target */ + /* add modifier */ func = RNA_def_function(srna, "new", "rna_Object_modifier_new"); RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Add a new modifier"); @@ -1772,11 +1772,11 @@ static void rna_def_object_modifiers(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_pointer(func, "modifier", "Modifier", "", "Newly created modifier"); RNA_def_function_return(func, parm); - /* remove target */ + /* remove modifier */ func = RNA_def_function(srna, "remove", "rna_Object_modifier_remove"); RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove an existing modifier from the object"); - /* target to remove*/ + /* modifier to remove */ parm = RNA_def_pointer(func, "modifier", "Modifier", "", "Modifier to remove"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index ae8c331bf1e..5cabc328778 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -87,6 +87,10 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ case OB_SURF: { ListBase dispbase = {NULL, NULL}; DerivedMesh *derivedFinal = NULL; + int uv_from_orco; + + int (*orco_index)[4] = NULL; + float (*orco)[3] = NULL; /* copies object and modifiers (but not the data) */ tmpobj = BKE_object_copy(ob); @@ -114,7 +118,37 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ tmpobj->derivedFinal = derivedFinal; - BKE_mesh_from_nurbs_displist(tmpobj, &dispbase); + uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0; + + if (uv_from_orco) { + /* before curve conversion */ + orco = (float (*)[3])BKE_curve_make_orco(sce, tmpobj); + } + + /* convert object type to mesh */ + BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco ? (int **)&orco_index : NULL); + + tmpmesh = tmpobj->data; + + if (uv_from_orco && orco && orco_index) { + const char *uvname = "Orco"; + /* add UV's */ + MTexPoly *mtpoly = CustomData_add_layer_named(&tmpmesh->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, tmpmesh->totpoly, uvname); + MLoopUV *mloopuvs = CustomData_add_layer_named(&tmpmesh->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, tmpmesh->totloop, uvname); + + BKE_mesh_nurbs_to_mdata_orco(tmpmesh->mpoly, tmpmesh->totpoly, + tmpmesh->mloop, mloopuvs, + orco, orco_index); + + (void)mtpoly; + } + + if (orco_index) { + MEM_freeN(orco_index); + } + if (orco) { + MEM_freeN(orco); + } BKE_displist_free(&dispbase); @@ -124,7 +158,7 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ BKE_report(reports, RPT_ERROR, "cant convert curve to mesh. Does the curve have any segments?"); return NULL; } - tmpmesh = tmpobj->data; + BKE_libblock_free_us(&G.main->object, tmpobj); break; } diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index aab3483e29b..db309ed8f1f 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -526,7 +526,7 @@ static int rna_Property_readonly_get(PointerRNA *ptr) { PropertyRNA *prop = (PropertyRNA *)ptr->data; - /* don't use this becaure it will call functions that check the internal + /* don't use this because it will call functions that check the internal * data for introspection we only need to know if it can be edited so the * flag is better for this */ /* return RNA_property_editable(ptr, prop); */ @@ -829,7 +829,7 @@ static void rna_EnumProperty_items_begin(CollectionPropertyIterator *iter, Point int totitem, free = 0; rna_idproperty_check(&prop, ptr); - /* eprop= (EnumPropertyRNA*)prop; */ + /* eprop= (EnumPropertyRNA *)prop; */ RNA_property_enum_items(NULL, ptr, prop, &item, &totitem, &free); rna_iterator_array_begin(iter, (void *)item, sizeof(EnumPropertyItem), totitem, free, rna_enum_check_separator); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 070db8d23d8..9b91729b5d7 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -37,6 +37,7 @@ #include "DNA_particle_types.h" #include "DNA_scene_types.h" #include "DNA_userdef_types.h" +#include "DNA_world_types.h" #include "BLI_math.h" @@ -145,7 +146,7 @@ EnumPropertyItem snap_node_element_items[] = { }; -/* workaround for duplice enums, +/* workaround for duplicate enums, * have each enum line as a defne then conditionally set it or not */ @@ -237,10 +238,6 @@ EnumPropertyItem image_type_items[] = { IMAGE_TYPE_ITEMS_IMAGE_ONLY {0, "", 0, N_("Movie"), NULL}, -#ifdef _WIN32 - /* XXX Missing codec menu */ - {R_IMF_IMTYPE_AVICODEC, "AVICODEC", ICON_FILE_MOVIE, "AVI Codec", "Output video in AVI format"}, -#endif {R_IMF_IMTYPE_AVIJPEG, "AVI_JPEG", ICON_FILE_MOVIE, "AVI JPEG", "Output video in AVI JPEG format"}, {R_IMF_IMTYPE_AVIRAW, "AVI_RAW", ICON_FILE_MOVIE, "AVI Raw", "Output video in AVI Raw format"}, #ifdef WITH_FRAMESERVER @@ -771,7 +768,7 @@ static EnumPropertyItem *rna_ImageFormatSettings_color_mode_itemf(bContext *C, P #ifdef WITH_FFMPEG /* a WAY more crappy case than B&W flag: depending on codec, file format MIGHT support * alpha channel. for example MPEG format with h264 codec can't do alpha channel, but - * the same MPEG format with QTRLE codec can easily handle alpga channel. + * the same MPEG format with QTRLE codec can easily handle alpha channel. * not sure how to deal with such cases in a nicer way (sergey) */ if (is_render) { Scene *scene = ptr->id.data; @@ -1105,7 +1102,7 @@ static void rna_RenderSettings_color_management_update(Main *bmain, Scene *UNUSE if (ntree && scene->use_nodes) { /* images are freed here, stop render and preview threads, until - * Image is threadsafe. when we are changing this propery from a + * Image is threadsafe. when we are changing this property from a * python script in the render thread, don't stop own thread */ if (BLI_thread_is_main()) WM_jobs_stop_all(bmain->wm.first); @@ -2635,13 +2632,13 @@ static void rna_def_scene_game_data(BlenderRNA *brna) /* mode */ prop = RNA_def_property(srna, "use_occlusion_culling", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", (1 << 5)); /*XXX mode hardcoded *//* WO_DBVT_CULLING */ + RNA_def_property_boolean_sdna(prop, NULL, "mode", WO_DBVT_CULLING); RNA_def_property_ui_text(prop, "DBVT culling", "Use optimized Bullet DBVT tree for view frustum and occlusion culling"); /* not used *//* deprecated !!!!!!!!!!!!! */ prop = RNA_def_property(srna, "use_activity_culling", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", (1 << 3)); /*XXX mode hardcoded */ + RNA_def_property_boolean_sdna(prop, NULL, "mode", WO_ACTIVITY_CULLING); RNA_def_property_ui_text(prop, "Activity Culling", "Activity culling is enabled"); /* not used *//* deprecated !!!!!!!!!!!!! */ @@ -3046,21 +3043,21 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "video_bitrate", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "video_bitrate"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_range(prop, 1, 14000); + RNA_def_property_range(prop, 1, 64000); RNA_def_property_ui_text(prop, "Bitrate", "Video bitrate (kb/s)"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); prop = RNA_def_property(srna, "minrate", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "rc_min_rate"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_range(prop, 0, 9000); + RNA_def_property_range(prop, 0, 48000); RNA_def_property_ui_text(prop, "Min Rate", "Rate control: min rate (kb/s)"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); prop = RNA_def_property(srna, "maxrate", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "rc_max_rate"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_range(prop, 1, 14000); + RNA_def_property_range(prop, 1, 96000); RNA_def_property_ui_text(prop, "Max Rate", "Rate control: max rate (kb/s)"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 4473a9ef0f6..793eb2b7185 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -123,7 +123,7 @@ EnumPropertyItem clip_editor_mode_items[] = { {SC_MODE_RECONSTRUCTION, "RECONSTRUCTION", ICON_SNAP_FACE, "Reconstruction", "Show tracking/reconstruction tools"}, {SC_MODE_DISTORTION, "DISTORTION", ICON_GRID, "Distortion", "Show distortion tools"}, - {SC_MODE_MASKEDIT, "MASKEDIT", ICON_MOD_MASK, "Mask editing", "Show mask editing tools"}, + {SC_MODE_MASKEDIT, "MASK", ICON_MOD_MASK, "Mask", "Show mask editing tools"}, {0, NULL, 0, NULL, NULL} }; @@ -529,11 +529,14 @@ static PointerRNA rna_SpaceImageEditor_uvedit_get(PointerRNA *ptr) return rna_pointer_inherit_refine(ptr, &RNA_SpaceUVEditor, ptr->data); } -static void rna_SpaceImageEditor_paint_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr)) +static void rna_SpaceImageEditor_mode_update(Main *bmain, Scene *scene, PointerRNA *ptr) { - paint_init(&scene->toolsettings->imapaint.paint, PAINT_CURSOR_TEXTURE_PAINT); + SpaceImage *sima = (SpaceImage *)(ptr->data); + if (sima->mode == SI_MODE_PAINT) { + BKE_paint_init(&scene->toolsettings->imapaint.paint, PAINT_CURSOR_TEXTURE_PAINT); - ED_space_image_paint_update(bmain->wm.first, scene->toolsettings); + ED_space_image_paint_update(bmain->wm.first, scene->toolsettings); + } } static int rna_SpaceImageEditor_show_render_get(PointerRNA *ptr) @@ -555,6 +558,13 @@ static int rna_SpaceImageEditor_show_uvedit_get(PointerRNA *ptr) return ED_space_image_show_uvedit(sima, sc->scene->obedit); } +static int rna_SpaceImageEditor_show_maskedit_get(PointerRNA *ptr) +{ + SpaceImage *sima = (SpaceImage *)(ptr->data); + bScreen *sc = (bScreen *)ptr->id.data; + return ED_space_image_check_show_maskedit(sc->scene, sima); +} + static void rna_SpaceImageEditor_image_set(PointerRNA *ptr, PointerRNA value) { SpaceImage *sima = (SpaceImage *)(ptr->data); @@ -563,6 +573,13 @@ static void rna_SpaceImageEditor_image_set(PointerRNA *ptr, PointerRNA value) ED_space_image_set(sima, sc->scene, sc->scene->obedit, (Image *)value.data); } +static void rna_SpaceImageEditor_mask_set(PointerRNA *ptr, PointerRNA value) +{ + SpaceImage *sima = (SpaceImage *)(ptr->data); + + ED_space_image_set_mask(NULL, sima, (Mask *)value.data); +} + static EnumPropertyItem *rna_SpaceImageEditor_draw_channels_itemf(bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free) { @@ -610,7 +627,7 @@ static void rna_SpaceImageEditor_zoom_get(PointerRNA *ptr, float *values) sa = rna_area_from_space(ptr); /* can be NULL */ ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); if (ar) { - ED_space_image_zoom(sima, ar, &values[0], &values[1]); + ED_space_image_get_zoom(sima, ar, &values[0], &values[1]); } } @@ -623,7 +640,7 @@ static void rna_SpaceImageEditor_cursor_location_get(PointerRNA *ptr, float *val } else { int w, h; - ED_space_image_size(sima, &w, &h); + ED_space_image_get_size(sima, &w, &h); values[0] = sima->cursor[0] * w; values[1] = sima->cursor[1] * h; @@ -639,7 +656,7 @@ static void rna_SpaceImageEditor_cursor_location_set(PointerRNA *ptr, const floa } else { int w, h; - ED_space_image_size(sima, &w, &h); + ED_space_image_get_size(sima, &w, &h); sima->cursor[0] = values[0] / w; sima->cursor[1] = values[1] / h; @@ -1103,6 +1120,31 @@ static void rna_def_space(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Type", "Space data type"); } +/* for all spaces that use a mask */ +void rna_def_space_mask_info(StructRNA *srna, int noteflag, const char *mask_set_func) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "mask_info.mask"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Mask", "Mask displayed and edited in this space"); + RNA_def_property_pointer_funcs(prop, NULL, mask_set_func, NULL, NULL); + RNA_def_property_update(prop, noteflag, NULL); + + /* mask drawing */ + prop = RNA_def_property(srna, "mask_draw_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "mask_info.draw_type"); + RNA_def_property_enum_items(prop, dt_uv_items); + RNA_def_property_ui_text(prop, "Edge Draw Type", "Draw type for mask splines"); + RNA_def_property_update(prop, noteflag, NULL); + + prop = RNA_def_property(srna, "show_mask_smooth", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "mask_info.draw_flag", MASK_DRAWFLAG_SMOOTH); + RNA_def_property_ui_text(prop, "Draw Smooth Splines", ""); + RNA_def_property_update(prop, noteflag, NULL); +} + static void rna_def_space_image_uv(BlenderRNA *brna) { StructRNA *srna; @@ -1928,6 +1970,13 @@ static void rna_def_space_buttons(BlenderRNA *brna) static void rna_def_space_image(BlenderRNA *brna) { + static EnumPropertyItem image_space_mode_items[] = { + {SI_MODE_VIEW, "VIEW", ICON_FILE_IMAGE, "View", "View the image and UV edit in mesh editmode"}, + {SI_MODE_PAINT, "PAINT", ICON_TPAINT_HLT, "Paint", "2D image painting mode"}, + {SI_MODE_MASK, "MASK", ICON_MOD_MASK, "Mask", "Mask editing"}, + {0, NULL, 0, NULL, NULL} + }; + StructRNA *srna; PropertyRNA *prop; @@ -1997,12 +2046,12 @@ static void rna_def_space_image(BlenderRNA *brna) RNA_def_property_pointer_funcs(prop, "rna_SpaceImageEditor_uvedit_get", NULL, NULL, NULL); RNA_def_property_ui_text(prop, "UV Editor", "UV editor settings"); - /* paint */ - prop = RNA_def_property(srna, "use_image_paint", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_DRAWTOOL); - RNA_def_property_ui_text(prop, "Image Painting", "Enable image painting mode"); - RNA_def_property_ui_icon(prop, ICON_TPAINT_HLT, 0); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, "rna_SpaceImageEditor_paint_update"); + /* mode */ + prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "mode"); + RNA_def_property_enum_items(prop, image_space_mode_items); + RNA_def_property_ui_text(prop, "Mode", "Editing context being displayed"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, "rna_SpaceImageEditor_mode_update"); /* grease pencil */ prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); @@ -2035,7 +2084,15 @@ static void rna_def_space_image(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Show UV Editor", "Show UV editing related properties"); + prop = RNA_def_property(srna, "show_maskedit", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_SpaceImageEditor_show_maskedit_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Show Mask Editor", "Show Mask editing related properties"); + rna_def_space_image_uv(brna); + + /* mask */ + rna_def_space_mask_info(srna, NC_SPACE | ND_SPACE_IMAGE, "rna_SpaceImageEditor_mask_set"); } static void rna_def_space_sequencer(BlenderRNA *brna) @@ -2944,6 +3001,11 @@ static void rna_def_space_node(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_SHOW_HIGHLIGHT); RNA_def_property_ui_text(prop, "Highlight", "Highlight nodes that are being calculated"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL); + + prop = RNA_def_property(srna, "use_hidden_preview", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_USE_HIDDEN_PREVIEW); + RNA_def_property_ui_text(prop, "Hide Preview", "Hide preview for newly creating nodes"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL); } static void rna_def_space_logic(BlenderRNA *brna) @@ -3064,24 +3126,7 @@ static void rna_def_space_clip(BlenderRNA *brna) RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); /* mask */ - prop = RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Mask", "Mask displayed and edited in this space"); - RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceClipEditor_mask_set", NULL, NULL); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); - - /* mask drawing */ - prop = RNA_def_property(srna, "mask_draw_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "mask_draw_type"); - RNA_def_property_enum_items(prop, dt_uv_items); - RNA_def_property_ui_text(prop, "Edge Draw Type", "Draw type for mask splines"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); - - prop = RNA_def_property(srna, "show_mask_smooth", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mask_draw_flag", MASK_DRAWFLAG_SMOOTH); - RNA_def_property_ui_text(prop, "Draw Smooth Splines", ""); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); - + rna_def_space_mask_info(srna, NC_SPACE | ND_SPACE_CLIP, "rna_SpaceClipEditor_mask_set"); /* mode */ prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 63e650d5867..0898ba5608f 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -382,6 +382,17 @@ static void rna_tracking_markerSearch_update(Main *UNUSED(bmain), Scene *UNUSED( BKE_tracking_marker_clamp(marker, CLAMP_SEARCH_DIM); } +static void rna_tracking_markerPattern_boundbox_get(PointerRNA *ptr, float *values) +{ + MovieTrackingMarker *marker = (MovieTrackingMarker *)ptr->data; + float min[2], max[2]; + + BKE_tracking_marker_pattern_minmax(marker, min, max); + + copy_v2_v2(values, min); + copy_v2_v2(values + 2, max); +} + static void rna_trackingDopesheet_tagUpdate(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr) { MovieClip *clip = (MovieClip *)ptr->id.data; @@ -443,9 +454,12 @@ void rna_trackingObject_remove(MovieTracking *tracking, MovieTrackingObject *obj WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL); } -static MovieTrackingMarker *rna_trackingMarkers_find_frame(MovieTrackingTrack *track, int framenr) +static MovieTrackingMarker *rna_trackingMarkers_find_frame(MovieTrackingTrack *track, int framenr, int exact) { - return BKE_tracking_marker_get_exact(track, framenr); + if (exact) + return BKE_tracking_marker_get_exact(track, framenr); + else + return BKE_tracking_marker_get(track, framenr); } static MovieTrackingMarker *rna_trackingMarkers_insert_frame(MovieTrackingTrack *track, int framenr, float *co) @@ -646,19 +660,19 @@ static void rna_def_trackingSettings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Motion model", "Default motion model to use for tracking"); /* default_use_brute */ - prop = RNA_def_property(srna, "default_use_brute", PROP_BOOLEAN, PROP_NONE); + prop = RNA_def_property(srna, "use_default_brute", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_BRUTE); RNA_def_property_ui_text(prop, "Prepass", "Use a brute-force translation-only initialization when tracking"); RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* default_use_brute */ - prop = RNA_def_property(srna, "default_use_mask", PROP_BOOLEAN, PROP_NONE); + prop = RNA_def_property(srna, "use_default_mask", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_MASK); RNA_def_property_ui_text(prop, "Use Mask", "Use a grease pencil datablock as a mask to use only specified areas of pattern when tracking"); RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); /* default_use_normalization */ - prop = RNA_def_property(srna, "default_use_normalization", PROP_BOOLEAN, PROP_NONE); + prop = RNA_def_property(srna, "use_default_normalization", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_NORMALIZATION); RNA_def_property_ui_text(prop, "Normalize", "Normalize light intensities while tracking (slower)"); RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); @@ -814,6 +828,8 @@ static void rna_def_trackingMarker(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + static int boundbox_dimsize[] = {2, 2}; + srna = RNA_def_struct(brna, "MovieTrackingMarker", NULL); RNA_def_struct_ui_text(srna, "Movie tracking marker data", "Match-moving marker data for tracking"); @@ -849,6 +865,12 @@ static void rna_def_trackingMarker(BlenderRNA *brna) "normalized coordinates relative to marker position"); RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_tracking_markerPattern_update"); + prop = RNA_def_property(srna, "pattern_bound_box", PROP_FLOAT, PROP_NONE); + RNA_def_property_multi_array(prop, 2, boundbox_dimsize); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_float_funcs(prop, "rna_tracking_markerPattern_boundbox_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Pattern Bounding Box", "Pattern area bounding box in normalized coordinates"); + /* search */ prop = RNA_def_property(srna, "search_min", PROP_FLOAT, PROP_TRANSLATION); RNA_def_property_array(prop, 2); @@ -887,6 +909,8 @@ static void rna_def_trackingMarkers(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to find marker for", MINFRAME, MAXFRAME); RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_boolean(func, "exact", TRUE, "Exact", + "Get marker at exact frame number rather than get estimated marker"); parm = RNA_def_pointer(func, "marker", "MovieTrackingMarker", "", "Marker for specified frame"); RNA_def_function_return(func, parm); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index ce23a5f7ae0..5820de3a7e2 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -1183,6 +1183,11 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Bone Pose", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); + prop = RNA_def_property(srna, "bone_pose_active", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Bone Pose Active", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + prop = RNA_def_property(srna, "frame_current", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "cframe"); RNA_def_property_array(prop, 3); @@ -2981,6 +2986,7 @@ static void rna_def_userdef_system(BlenderRNA *brna) { 8, "FRENCH", 0, "French (Français)", "fr_FR"}, { 4, "ITALIAN", 0, "Italian (Italiano)", "it_IT"}, { 2, "JAPANESE", 0, "Japanese (日本語)", "ja_JP"}, + {12, "PORTUGUESE", 0, "Portuguese (Português)", "pt"}, {15, "RUSSIAN", 0, "Russian (Русский)", "ru_RU"}, {13, "SIMPLIFIED_CHINESE", 0, "Simplified Chinese (简体中文)", "zh_CN"}, { 9, "SPANISH", 0, "Spanish (Español)", "es"}, @@ -3004,7 +3010,6 @@ static void rna_def_userdef_system(BlenderRNA *brna) /* using the utf8 flipped form of Persian (فارسی) */ {26, "PERSIAN", 0, "Persian (ﯽﺳﺭﺎﻓ)", "fa_IR"}, {19, "POLISH", 0, "Polish (Polski)", "pl_PL"}, - {12, "BRAZILIAN_PORTUGUESE", 0, "Portuguese (Português)", "pt"}, /* {20, "ROMANIAN", 0, "Romanian (Român)", "ro_RO"}, */ /* XXX No po's yet. */ {17, "SERBIAN", 0, "Serbian (Српски)", "sr_RS"}, {28, "SERBIAN_LATIN", 0, "Serbian latin (Srpski latinica)", "sr_RS@latin"}, diff --git a/source/blender/makesrna/intern/rna_vfont.c b/source/blender/makesrna/intern/rna_vfont.c index aca25252d2e..ff9469550d9 100644 --- a/source/blender/makesrna/intern/rna_vfont.c +++ b/source/blender/makesrna/intern/rna_vfont.c @@ -24,7 +24,6 @@ * \ingroup RNA */ - #include <stdlib.h> #include "RNA_define.h" @@ -33,8 +32,37 @@ #include "DNA_vfont_types.h" +#include "WM_types.h" + + #ifdef RNA_RUNTIME +#include "BKE_font.h" +#include "BKE_depsgraph.h" +#include "DNA_object_types.h" + +#include "WM_api.h" + +/* matching fnction in rna_ID.c */ +static int rna_VectorFont_filepath_editable(PointerRNA *ptr) +{ + VFont *vfont = ptr->id.data; + if (BKE_vfont_is_builtin(vfont)) { + return FALSE; + } + return TRUE; +} + +static void rna_VectorFont_reload_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + VFont *vf = ptr->id.data; + BKE_vfont_free_data(vf); + + /* update */ + WM_main_add_notifier(NC_GEOM | ND_DATA, NULL); + DAG_id_tag_update(&vf->id, OB_RECALC_OB | OB_RECALC_DATA); +} + #else void RNA_def_vfont(BlenderRNA *brna) @@ -48,9 +76,10 @@ void RNA_def_vfont(BlenderRNA *brna) RNA_def_struct_ui_icon(srna, ICON_FILE_FONT); prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_string_sdna(prop, NULL, "name"); + RNA_def_property_editable_func(prop, "rna_VectorFont_filepath_editable"); RNA_def_property_ui_text(prop, "File Path", ""); + RNA_def_property_update(prop, NC_GEOM | ND_DATA, "rna_VectorFont_reload_update"); prop = RNA_def_property(srna, "packed_file", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "packedfile"); @@ -58,4 +87,3 @@ void RNA_def_vfont(BlenderRNA *brna) } #endif - diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c index 6cd8745f5d9..fb9788fb278 100644 --- a/source/blender/modifiers/intern/MOD_boolean.c +++ b/source/blender/modifiers/intern/MOD_boolean.c @@ -127,7 +127,19 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, if (!bmd->object) return derivedData; - dm = bmd->object->derivedFinal; + + /* 2.63 used this... */ + /* dm = bmd->object->derivedFinal; */ + + /* but we want to make sure we can get the object + * in some cases the depsgraph fails us - especially for objects + * in other scenes when compositing */ + if (bmd->object != ob) { + dm = mesh_get_derived_final(md->scene, bmd->object, CD_MASK_MESH); + } + else { + dm = NULL; + } if (dm) { DerivedMesh *result; diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index dfbfbd22475..21836453eed 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -242,13 +242,13 @@ static void dm_get_bounds(DerivedMesh *dm, float *sx, float *sy, float *ox, floa copy_v3_v3(max, mvert->co); for (v = 1; v < totvert; v++, mvert++) { - min[0] = MIN2(min[0], mvert->co[0]); - min[1] = MIN2(min[1], mvert->co[1]); - min[2] = MIN2(min[2], mvert->co[2]); + min[0] = minf(min[0], mvert->co[0]); + min[1] = minf(min[1], mvert->co[1]); + min[2] = minf(min[2], mvert->co[2]); - max[0] = MAX2(max[0], mvert->co[0]); - max[1] = MAX2(max[1], mvert->co[1]); - max[2] = MAX2(max[2], mvert->co[2]); + max[0] = maxf(max[0], mvert->co[0]); + max[1] = maxf(max[1], mvert->co[1]); + max[2] = maxf(max[2], mvert->co[2]); } sub_v3_v3v3(delta, max, min); diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index 0cf36677807..ecdc5b53460 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -176,6 +176,7 @@ static void deformVerts(ModifierData *md, Object *ob, psmd->dm->needsFree = 0; /* report change in mesh structure */ + DM_ensure_tessface(psmd->dm); if (psmd->dm->getNumVerts(psmd->dm) != psmd->totdmvert || psmd->dm->getNumEdges(psmd->dm) != psmd->totdmedge || psmd->dm->getNumTessFaces(psmd->dm) != psmd->totdmface) diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index 14735810cad..bf5f6cd095e 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -161,7 +161,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object if (smd->limit[0] < 0.0f) smd->limit[0] = 0.0f; if (smd->limit[0] > 1.0f) smd->limit[0] = 1.0f; - smd->limit[0] = MIN2(smd->limit[0], smd->limit[1]); /* Upper limit >= than lower limit */ + smd->limit[0] = minf(smd->limit[0], smd->limit[1]); /* Upper limit >= than lower limit */ //Calculate matrixs do convert between coordinate spaces if (smd->origin) { @@ -190,8 +190,8 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object if (transf) space_transform_apply(transf, tmp); - lower = MIN2(lower, tmp[limit_axis]); - upper = MAX2(upper, tmp[limit_axis]); + lower = minf(lower, tmp[limit_axis]); + upper = maxf(upper, tmp[limit_axis]); } diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index 50e7a3e6da9..222f13185ea 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -69,6 +69,7 @@ #include "BLI_heap.h" #include "BLI_listbase.h" #include "BLI_math.h" +#include "BLI_stack.h" #include "BLI_string.h" #include "BKE_cdderivedmesh.h" @@ -354,7 +355,7 @@ static void merge_frame_corners(Frame **frames, int totframe) BLI_assert(frames[i] != frames[k]); side_b = frame_len(frames[k]); - thresh = MIN2(side_a, side_b) / 2.0f; + thresh = minf(side_a, side_b) / 2.0f; /* Compare with each corner of all other frames... */ for (l = 0; l < 4; l++) { @@ -634,71 +635,107 @@ static void calc_edge_mat(float mat[3][3], const float a[3], const float b[3]) } } -static void build_emats_rec(int *visited_e, EMat *emat, - const MeshElemMap *emap, const MEdge *medge, - const MVertSkin *vs, const MVert *mvert, - int parent_v, float parent_mat[3][3]) +typedef struct { + float mat[3][3]; + int parent_v; + int e; +} EdgeStackElem; + +static void build_emats_stack(BLI_Stack *stack, int *visited_e, EMat *emat, + const MeshElemMap *emap, const MEdge *medge, + const MVertSkin *vs, const MVert *mvert) { + EdgeStackElem stack_elem; float axis[3], angle; - int i, e, v, parent_is_branch; + int i, e, v, parent_v, parent_is_branch; - parent_is_branch = ((emap[parent_v].count > 2) || - (vs[parent_v].flag & MVERT_SKIN_ROOT)); + BLI_stack_pop(stack, &stack_elem); + parent_v = stack_elem.parent_v; + e = stack_elem.e; - for (i = 0; i < emap[parent_v].count; i++) { - e = emap[parent_v].indices[i]; + /* Skip if edge already visited */ + if (visited_e[e]) + return; - /* Ignore edge if already visited */ - if (visited_e[e]) continue; - visited_e[e] = 1; + /* Mark edge as visited */ + visited_e[e] = TRUE; + + /* Process edge */ - v = BKE_mesh_edge_other_vert(&medge[e], parent_v); - emat[e].origin = parent_v; + parent_is_branch = ((emap[parent_v].count > 2) || + (vs[parent_v].flag & MVERT_SKIN_ROOT)); - /* If parent is a branch node, start a new edge chain */ - if (parent_is_branch) { - calc_edge_mat(emat[e].mat, mvert[parent_v].co, - mvert[v].co); - } - else { - /* Build edge matrix guided by parent matrix */ - sub_v3_v3v3(emat[e].mat[0], mvert[v].co, mvert[parent_v].co); - normalize_v3(emat[e].mat[0]); - angle = angle_normalized_v3v3(parent_mat[0], emat[e].mat[0]); - cross_v3_v3v3(axis, parent_mat[0], emat[e].mat[0]); - normalize_v3(axis); - rotate_normalized_v3_v3v3fl(emat[e].mat[1], parent_mat[1], axis, angle); - rotate_normalized_v3_v3v3fl(emat[e].mat[2], parent_mat[2], axis, angle); - } + v = BKE_mesh_edge_other_vert(&medge[e], parent_v); + emat[e].origin = parent_v; + + /* If parent is a branch node, start a new edge chain */ + if (parent_is_branch) { + calc_edge_mat(emat[e].mat, mvert[parent_v].co, + mvert[v].co); + } + else { + /* Build edge matrix guided by parent matrix */ + sub_v3_v3v3(emat[e].mat[0], mvert[v].co, mvert[parent_v].co); + normalize_v3(emat[e].mat[0]); + angle = angle_normalized_v3v3(stack_elem.mat[0], emat[e].mat[0]); + cross_v3_v3v3(axis, stack_elem.mat[0], emat[e].mat[0]); + normalize_v3(axis); + rotate_normalized_v3_v3v3fl(emat[e].mat[1], stack_elem.mat[1], axis, angle); + rotate_normalized_v3_v3v3fl(emat[e].mat[2], stack_elem.mat[2], axis, angle); + } - build_emats_rec(visited_e, emat, emap, medge, - vs, mvert, v, emat[e].mat); + /* Add neighbors to stack */ + for (i = 0; i < emap[v].count; i++) { + /* Add neighbors to stack */ + memcpy(stack_elem.mat, emat[e].mat, sizeof(float) * 3 * 3); + stack_elem.e = emap[v].indices[i]; + stack_elem.parent_v = v; + BLI_stack_push(stack, &stack_elem); } } -static EMat *build_edge_mats(MVertSkin *vs, MVert *mvert, int totvert, - MEdge *medge, MeshElemMap *emap, int totedge) +static EMat *build_edge_mats(const MVertSkin *vs, + const MVert *mvert, + int totvert, + const MEdge *medge, + const MeshElemMap *emap, + int totedge) { + BLI_Stack *stack; EMat *emat; - float mat[3][3]; - int *visited_e, v; + EdgeStackElem stack_elem; + int *visited_e, i, v; + + stack = BLI_stack_new(sizeof(stack_elem), "build_edge_mats.stack"); visited_e = MEM_callocN(sizeof(int) * totedge, "build_edge_mats.visited_e"); emat = MEM_callocN(sizeof(EMat) * totedge, "build_edge_mats.emat"); - /* Build edge matrices recursively from the root nodes */ + /* Edge matrices are built from the root nodes, add all roots with + * children to the stack */ for (v = 0; v < totvert; v++) { if (vs[v].flag & MVERT_SKIN_ROOT) { if (emap[v].count >= 1) { const MEdge *e = &medge[emap[v].indices[0]]; - calc_edge_mat(mat, mvert[v].co, + calc_edge_mat(stack_elem.mat, mvert[v].co, mvert[BKE_mesh_edge_other_vert(e, v)].co); - build_emats_rec(visited_e, emat, emap, medge, vs, mvert, v, mat); + stack_elem.parent_v = v; + + /* Add adjacent edges to stack */ + for (i = 0; i < emap[v].count; i++) { + stack_elem.e = emap[v].indices[i]; + BLI_stack_push(stack, &stack_elem); + } } } } + while (!BLI_stack_empty(stack)) { + build_emats_stack(stack, visited_e, emat, emap, medge, vs, mvert); + } + MEM_freeN(visited_e); + BLI_stack_free(stack); return emat; } diff --git a/source/blender/nodes/composite/nodes/node_composite_common.c b/source/blender/nodes/composite/nodes/node_composite_common.c index f3e0edfc691..3a3f94f05cc 100644 --- a/source/blender/nodes/composite/nodes/node_composite_common.c +++ b/source/blender/nodes/composite/nodes/node_composite_common.c @@ -114,7 +114,7 @@ static void move_stack(bNodeStack *to, bNodeStack *from) static void *group_initexec(bNode *node) { - bNodeTree *ngroup= (bNodeTree*)node->id; + bNodeTree *ngroup= (bNodeTree *)node->id; bNodeTreeExec *exec; bNodeSocket *sock; bNodeStack *ns; @@ -138,7 +138,7 @@ static void *group_initexec(bNode *node) static void group_freeexec(bNode *UNUSED(node), void *nodedata) { - bNodeTreeExec *gexec= (bNodeTreeExec*)nodedata; + bNodeTreeExec *gexec= (bNodeTreeExec *)nodedata; if (gexec) ntreeCompositEndExecTree(gexec, 0); @@ -193,7 +193,7 @@ static void group_free_internal(bNodeTreeExec *gexec) static void group_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out) { - bNodeTreeExec *exec= (bNodeTreeExec*)nodedata; + bNodeTreeExec *exec= (bNodeTreeExec *)nodedata; if (!exec) return; @@ -265,7 +265,7 @@ static void loop_iteration_reset(bNodeTree *ngroup, bNodeStack *gstack) static void forloop_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out) { - bNodeTreeExec *exec= (bNodeTreeExec*)nodedata; + bNodeTreeExec *exec= (bNodeTreeExec *)nodedata; int totiterations= (int)in[0]->vec[0]; bNodeSocket *sock; bNodeStack *ns; @@ -323,7 +323,7 @@ void register_node_type_cmp_forloop(bNodeTreeType *ttype) #if 0 /* XXX loop nodes don't work nicely with current trees */ static void whileloop_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out) { - bNodeTreeExec *exec= (bNodeTreeExec*)nodedata; + bNodeTreeExec *exec= (bNodeTreeExec *)nodedata; int condition= (in[0]->vec[0] > 0.0f); bNodeSocket *sock; bNodeStack *ns; diff --git a/source/blender/nodes/composite/nodes/node_composite_defocus.c b/source/blender/nodes/composite/nodes/node_composite_defocus.c index 2ae3cd6ba56..d9ee067efe3 100644 --- a/source/blender/nodes/composite/nodes/node_composite_defocus.c +++ b/source/blender/nodes/composite/nodes/node_composite_defocus.c @@ -587,8 +587,8 @@ static void defocus_blur(bNode *node, CompBuf *new, CompBuf *img, CompBuf *zbuf, // n-agonal int ov, nv; float mind, maxd, lwt; - ys = MAX2((int)floor(bkh_b[2]*ct_crad + y), 0); - ye = MIN2((int)ceil(bkh_b[3]*ct_crad + y), new->y - 1); + ys = maxi((int)floor(bkh_b[2] * ct_crad + y), 0); + ye = mini((int)ceil(bkh_b[3] * ct_crad + y), new->y - 1); for (sy=ys; sy<=ye; sy++) { float fxs = 1e10f, fxe = -1e10f; float yf = (sy - y)/ct_crad; diff --git a/source/blender/nodes/composite/nodes/node_composite_mask.c b/source/blender/nodes/composite/nodes/node_composite_mask.c index 3cd3a732829..f4cbd1b7f6f 100644 --- a/source/blender/nodes/composite/nodes/node_composite_mask.c +++ b/source/blender/nodes/composite/nodes/node_composite_mask.c @@ -38,8 +38,6 @@ #include "node_composite_util.h" -#include "../../../../intern/raskter/raskter.h" - /* **************** Translate ******************** */ static bNodeSocketTemplate cmp_node_mask_out[] = { @@ -51,6 +49,7 @@ static void exec(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack ** { if (node->id) { Mask *mask = (Mask *)node->id; + MaskRasterHandle *mr_handle; CompBuf *stackbuf; RenderData *rd = data; float *res; @@ -70,18 +69,32 @@ static void exec(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack ** stackbuf = alloc_compbuf(sx, sy, CB_VAL, TRUE); res = stackbuf->rect; - BKE_mask_rasterize(mask, sx, sy, res, TRUE, - (node->custom1 & CMP_NODEFLAG_MASK_AA) != 0, - (node->custom1 & CMP_NODEFLAG_MASK_NO_FEATHER) == 0); + /* mask raster begin */ + mr_handle = BKE_maskrasterize_handle_new(); + BKE_maskrasterize_handle_init(mr_handle, mask, + sx, sy, + TRUE, + (node->custom1 & CMP_NODEFLAG_MASK_AA) != 0, + (node->custom1 & CMP_NODEFLAG_MASK_NO_FEATHER) == 0); + BKE_maskrasterize_buffer(mr_handle, sx, sy, res); + BKE_maskrasterize_handle_free(mr_handle); + /* mask raster end */ - if (node->custom1) { - PLX_antialias_buffer(res,sx,sy); - } /* pass on output and free */ out[0]->data = stackbuf; } } +static void node_composit_init_mask(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) +{ + NodeMask *data = MEM_callocN(sizeof(NodeMask), STRINGIFY(NodeMask)); + data->size_x = data->size_y = 256; + node->storage = data; + + node->custom2 = 16; /* samples */ + node->custom3 = 0.5f; /* shutter */ +} + void register_node_type_cmp_mask(bNodeTreeType *ttype) { static bNodeType ntype; @@ -89,7 +102,10 @@ void register_node_type_cmp_mask(bNodeTreeType *ttype) node_type_base(ttype, &ntype, CMP_NODE_MASK, "Mask", NODE_CLASS_INPUT, NODE_OPTIONS); node_type_socket_templates(&ntype, NULL, cmp_node_mask_out); node_type_size(&ntype, 140, 100, 320); + node_type_init(&ntype, node_composit_init_mask); node_type_exec(&ntype, exec); + node_type_storage(&ntype, "NodeMask", node_free_standard_storage, node_copy_standard_storage); + nodeRegisterType(ttype, &ntype); } diff --git a/source/blender/nodes/composite/nodes/node_composite_outputFile.c b/source/blender/nodes/composite/nodes/node_composite_outputFile.c index fcc8ed4a128..fd312d71f2c 100644 --- a/source/blender/nodes/composite/nodes/node_composite_outputFile.c +++ b/source/blender/nodes/composite/nodes/node_composite_outputFile.c @@ -123,6 +123,8 @@ bNodeSocket *ntreeCompositOutputFileAddSocket(bNodeTree *ntree, bNode *node, con sockdata->format.imtype= R_IMF_IMTYPE_OPENEXR; } } + else + BKE_imformat_defaults(&sockdata->format); /* use node data format by default */ sockdata->use_node_format = TRUE; @@ -174,9 +176,14 @@ static void init_output_file(bNodeTree *ntree, bNode* node, bNodeTemplate *ntemp RenderData *rd = &ntemp->scene->r; BLI_strncpy(nimf->base_path, rd->pic, sizeof(nimf->base_path)); nimf->format = rd->im_format; + if (BKE_imtype_is_movie(nimf->format.imtype)) { + nimf->format.imtype= R_IMF_IMTYPE_OPENEXR; + } - format = &rd->im_format; + format = &nimf->format; } + else + BKE_imformat_defaults(&nimf->format); /* add one socket by default */ ntreeCompositOutputFileAddSocket(ntree, node, "Image", format); diff --git a/source/blender/nodes/shader/nodes/node_shader_particle_info.c b/source/blender/nodes/shader/nodes/node_shader_particle_info.c index beefc0b6eae..5be8925b556 100644 --- a/source/blender/nodes/shader/nodes/node_shader_particle_info.c +++ b/source/blender/nodes/shader/nodes/node_shader_particle_info.c @@ -28,9 +28,10 @@ #include "../node_shader_util.h" static bNodeSocketTemplate outputs[] = { - { SOCK_FLOAT, 0, "Age" }, - { SOCK_FLOAT, 0, "Lifetime" }, - { -1, 0, "" } + { SOCK_FLOAT, 0, "Index" }, + { SOCK_FLOAT, 0, "Age" }, + { SOCK_FLOAT, 0, "Lifetime" }, + { -1, 0, "" } }; /* node type definition */ diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index a82562d4445..9270aec8d95 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -2083,6 +2083,199 @@ static PyObject *bpy_bmelemseq_index_update(BPy_BMElemSeq *self) Py_RETURN_NONE; } +PyDoc_STRVAR(bpy_bmelemseq_sort_doc, +".. method:: sort(key=None, reverse=False)\n" +"\n" +" Sort the elements of this sequence, using an optional custom sort key.\n" +" Indices of elements are not changed, BMElemeSeq.index_update() can be used for that.\n" +"\n" +" :arg key: The key that sets the ordering of the elements.\n" +" :type key: :function: returning a number\n" +" :arg reverse: Reverse the order of the elements\n" +" :type reverse: :boolean:\n" +"\n" +" .. note::\n" +"\n" +" When the 'key' argument is not provided, the elements are reordered following their current index value.\n" +" In particular this can be used by setting indices manually before calling this method.\n" +"\n" +); + +/* Use a static variable here because there is the need to sort some array + * doing comparisons on elements of another array, qsort_r would have been + * wonderful to use here, but unfortunately it is not standard and it's not + * portable across different platforms. + * + * If a portable alternative to qsort_r becomes available, remove this static + * var hack! + * + * Note: the functions below assumes the keys array has been allocated and it + * has enough elements to complete the task. + */ +static double *keys = NULL; + +static int bpy_bmelemseq_sort_cmp_by_keys_ascending(const void *index1_v, const void *index2_v) +{ + const int *index1 = (int *)index1_v; + const int *index2 = (int *)index2_v; + + if (keys[*index1] < keys[*index2]) return -1; + else if (keys[*index1] > keys[*index2]) return 1; + else return 0; +} + +static int bpy_bmelemseq_sort_cmp_by_keys_descending(const void *index1_v, const void *index2_v) +{ + return -bpy_bmelemseq_sort_cmp_by_keys_ascending(index1_v, index2_v); +} + +static PyObject *bpy_bmelemseq_sort(BPy_BMElemSeq *self, PyObject *args, PyObject *kw) +{ + static const char *kwlist[] = {"key", "reverse", NULL}; + PyObject *keyfunc = NULL; /* optional */ + int reverse = FALSE; /* optional */ + + const char htype = bm_iter_itype_htype_map[self->itype]; + int n_elem; + + BMIter iter; + BMElem *ele; + + int *elem_idx; + int *elem_map_idx; + int (*elem_idx_compare_by_keys)(const void *, const void *); + + int *vert_idx = NULL; + int *edge_idx = NULL; + int *face_idx = NULL; + int i; + + BMesh *bm = self->bm; + + BPY_BM_CHECK_OBJ(self); + + if (args != NULL) { + if (!PyArg_ParseTupleAndKeywords(args, kw, + "|Oi:BMElemSeq.sort", + (char **)kwlist, + &keyfunc, &reverse)) + return NULL; + } + + if (keyfunc != NULL && !PyCallable_Check(keyfunc)) { + PyErr_SetString(PyExc_TypeError, + "the 'key' argument is not a callable object"); + return NULL; + } + + n_elem = BM_mesh_elem_count(bm, htype); + if (n_elem <= 1) { + /* 0 or 1 elements: sorted already */ + Py_RETURN_NONE; + } + + keys = PyMem_MALLOC(sizeof(*keys) * n_elem); + if (keys == NULL) { + PyErr_NoMemory(); + return NULL; + } + + i = 0; + BM_ITER_BPY_BM_SEQ (ele, &iter, self) { + if (keyfunc != NULL) { + PyObject *py_elem; + PyObject *index; + + py_elem = BPy_BMElem_CreatePyObject(self->bm, (BMHeader *)ele); + index = PyObject_CallFunctionObjArgs(keyfunc, py_elem, NULL); + Py_DECREF(py_elem); + if (index == NULL) { + /* No need to set the exception here, + * PyObject_CallFunctionObjArgs() does that */ + PyMem_FREE(keys); + return NULL; + } + + if ((keys[i] = PyFloat_AsDouble(index)) == -1 && PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "the value returned by the 'key' function is not a number"); + Py_DECREF(index); + PyMem_FREE(keys); + return NULL; + } + + Py_DECREF(index); + } + else { + /* If the 'key' function is not provided we sort + * according to the current index values */ + keys[i] = ele->head.index; + } + + i++; + } + + elem_idx = PyMem_MALLOC(sizeof(*elem_idx) * n_elem); + if (elem_idx == NULL) { + PyErr_NoMemory(); + PyMem_FREE(keys); + return NULL; + } + + /* Initialize the element index array */ + range_vn_i(elem_idx, n_elem, 0); + + /* Sort the index array according to the order of the 'keys' array */ + if (reverse) + elem_idx_compare_by_keys = bpy_bmelemseq_sort_cmp_by_keys_descending; + else + elem_idx_compare_by_keys = bpy_bmelemseq_sort_cmp_by_keys_ascending; + + qsort(elem_idx, n_elem, sizeof(*elem_idx), elem_idx_compare_by_keys); + + elem_map_idx = PyMem_MALLOC(sizeof(*elem_map_idx) * n_elem); + if (elem_map_idx == NULL) { + PyErr_NoMemory(); + PyMem_FREE(elem_idx); + PyMem_FREE(keys); + return NULL; + } + + /* Initialize the map array + * + * We need to know the index such that if used as the new_index in + * BM_mesh_remap() will give the order of the sorted keys like in + * elem_idx */ + for (i = 0; i < n_elem; i++) { + elem_map_idx[elem_idx[i]] = i; + } + + switch ((BMIterType)self->itype) { + case BM_VERTS_OF_MESH: + vert_idx = elem_map_idx; + break; + case BM_EDGES_OF_MESH: + edge_idx = elem_map_idx; + break; + case BM_FACES_OF_MESH: + face_idx = elem_map_idx; + break; + default: + PyErr_Format(PyExc_TypeError, "element type %d not supported", self->itype); + PyMem_FREE(elem_map_idx); + PyMem_FREE(elem_idx); + PyMem_FREE(keys); + return NULL; + } + + BM_mesh_remap(bm, vert_idx, edge_idx, face_idx); + + PyMem_FREE(elem_map_idx); + PyMem_FREE(elem_idx); + PyMem_FREE(keys); + + Py_RETURN_NONE; +} static struct PyMethodDef bpy_bmesh_methods[] = { /* utility */ @@ -2175,6 +2368,7 @@ static struct PyMethodDef bpy_bmvertseq_methods[] = { /* odd function, initializes index values */ {"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, bpy_bmelemseq_index_update_doc}, + {"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, bpy_bmelemseq_sort_doc}, {NULL, NULL, 0, NULL} }; @@ -2186,6 +2380,7 @@ static struct PyMethodDef bpy_bmedgeseq_methods[] = { /* odd function, initializes index values */ {"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, bpy_bmelemseq_index_update_doc}, + {"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, bpy_bmelemseq_sort_doc}, {NULL, NULL, 0, NULL} }; @@ -2197,12 +2392,14 @@ static struct PyMethodDef bpy_bmfaceseq_methods[] = { /* odd function, initializes index values */ {"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, bpy_bmelemseq_index_update_doc}, + {"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, bpy_bmelemseq_sort_doc}, {NULL, NULL, 0, NULL} }; static struct PyMethodDef bpy_bmloopseq_methods[] = { /* odd function, initializes index values */ /* no: index_update() function since we cant iterate over loops */ + /* no: sort() function since we cant iterate over loops */ {NULL, NULL, 0, NULL} }; diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c index d4158210cc8..b9ef4b056ad 100644 --- a/source/blender/python/generic/bpy_internal_import.c +++ b/source/blender/python/generic/bpy_internal_import.c @@ -157,7 +157,8 @@ PyObject *bpy_text_import_name(const char *name, int *found) } /* we know this cant be importable, the name is too long for blender! */ - if (namelen >= (MAX_ID_NAME - 2) - 3) return NULL; + if (namelen >= (MAX_ID_NAME - 2) - 3) + return NULL; memcpy(txtname, name, namelen); memcpy(&txtname[namelen], ".py", 4); diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 93f49fd72c9..aa9d81389da 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -639,7 +639,7 @@ void BPY_modules_load_user(bContext *C) bpy_context_set(C, &gilstate); - for (text = CTX_data_main(C)->text.first; text; text = text->id.next) { + for (text = bmain->text.first; text; text = text->id.next) { if (text->flags & TXT_ISSCRIPT && BLI_testextensie(text->id.name + 2, ".py")) { if (!(G.f & G_SCRIPT_AUTOEXEC)) { printf("scripts disabled for \"%s\", skipping '%s'\n", bmain->name, text->id.name + 2); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 609c549dfcb..03e20322a59 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -6736,20 +6736,24 @@ static int rna_function_arg_count(FunctionRNA *func) return count; } -static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_function) +static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, void *py_data, int *have_function) { const ListBase *lb; Link *link; FunctionRNA *func; PropertyRNA *prop; - StructRNA *srna = dummyptr->type; const char *class_type = RNA_struct_identifier(srna); + StructRNA *srna_base = RNA_struct_base(srna); PyObject *py_class = (PyObject *)py_data; PyObject *base_class = RNA_struct_py_type_get(srna); PyObject *item; int i, flag, arg_count, func_arg_count; const char *py_class_name = ((PyTypeObject *)py_class)->tp_name; // __name__ + if (srna_base) { + if (bpy_class_validate_recursive(dummyptr, srna_base, py_data, have_function) != 0) + return -1; + } if (base_class) { if (!PyObject_IsSubclass(py_class, base_class)) { @@ -6884,6 +6888,11 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun return 0; } +static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_function) +{ + return bpy_class_validate_recursive(dummyptr, dummyptr->type, py_data, have_function); +} + /* TODO - multiple return values like with rna functions */ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms) { diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c index 5ac1214409f..40c0215ffd1 100644 --- a/source/blender/python/mathutils/mathutils_Quaternion.c +++ b/source/blender/python/mathutils/mathutils_Quaternion.c @@ -1085,12 +1085,15 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw return NULL; break; case 2: - if (mathutils_array_parse(quat, 3, 3, seq, "mathutils.Quaternion()") == -1) + { + float axis[3]; + if (mathutils_array_parse(axis, 3, 3, seq, "mathutils.Quaternion()") == -1) return NULL; angle = angle_wrap_rad(angle); /* clamp because of precision issues */ - axis_angle_to_quat(quat, quat, angle); + axis_angle_to_quat(quat, axis, angle); break; /* PyArg_ParseTuple assures no more then 2 */ + } } return Quaternion_CreatePyObject(quat, Py_NEW, type); } diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 8ca229c1a1b..d474dc14df8 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -153,7 +153,6 @@ typedef struct RenderStats { /* calling a new render with same name, frees automatic existing render */ struct Render *RE_NewRender (const char *name); struct Render *RE_GetRender(const char *name); -struct Render *RE_GetRender_FromData(const struct RenderData *rd); /* returns 1 while render is working (or renders called from within render) */ int RE_RenderInProgress(struct Render *re); diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h index 9d7393f9414..604cd940fab 100644 --- a/source/blender/render/extern/include/RE_render_ext.h +++ b/source/blender/render/extern/include/RE_render_ext.h @@ -58,7 +58,7 @@ void texture_rgb_blend(float in[3], const float tex[3], const float out[3], floa float texture_value_blend(float tex, float out, float fact, float facg, int blendtype); /* node_composite.c */ -void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result); +void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, float result[4]); void antialias_tagbuf(int xsize, int ysize, char *rectmove); /* dynamicpaint.c */ diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h index 1c8a2552482..e8f171fe383 100644 --- a/source/blender/render/intern/include/texture.h +++ b/source/blender/render/intern/include/texture.h @@ -78,7 +78,7 @@ void render_realtime_texture(struct ShadeInput *shi, struct Image *ima); int imagewraposa(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, const float texvec[3], const float dxt[3], const float dyt[3], struct TexResult *texres); int imagewrap(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, const float texvec[3], struct TexResult *texres); -void image_sample(struct Image *ima, float fx, float fy, float dx, float dy, float *result); +void image_sample(struct Image *ima, float fx, float fy, float dx, float dy, float result[4]); #endif /* __TEXTURE_H__ */ diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h index 99bde3fe02b..e4ee19d8ed2 100644 --- a/source/blender/render/intern/include/zbuf.h +++ b/source/blender/render/intern/include/zbuf.h @@ -55,7 +55,7 @@ int testclip(const float v[3]); void zbuffer_shadow(struct Render *re, float winmat[][4], struct LampRen *lar, int *rectz, int size, float jitx, float jity); void zbuffer_abuf_shadow(struct Render *re, struct LampRen *lar, float winmat[][4], struct APixstr *APixbuf, struct APixstrand *apixbuf, struct ListBase *apsmbase, int size, int samples, float (*jit)[2]); -void zbuffer_solid(struct RenderPart *pa, struct RenderLayer *rl, void (*fillfunc)(struct RenderPart*, struct ZSpan*, int, void*), void *data); +void zbuffer_solid(struct RenderPart *pa, struct RenderLayer *rl, void (*fillfunc)(struct RenderPart *, struct ZSpan *, int, void*), void *data); unsigned short *zbuffer_transp_shade(struct RenderPart *pa, struct RenderLayer *rl, float *pass, struct ListBase *psmlist); void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(void*, int, int, int, int, int)); diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index 9318e1758a6..103c04a590f 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -88,8 +88,8 @@ static inline int rayobject_bb_intersect_test(const Isect *isec, const float *_b RE_RC_COUNT(isec->raycounter->bb.test); - if (t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return 0; - if (t2x < 0.0 || t2y < 0.0 || t2z < 0.0) return 0; + if (t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return 0; + if (t2x < 0.0f || t2y < 0.0f || t2z < 0.0f) return 0; if (t1x > isec->dist || t1y > isec->dist || t1z > isec->dist) return 0; RE_RC_COUNT(isec->raycounter->bb.hit); @@ -133,7 +133,7 @@ static void bvh_bb(Tree *obj, float *min, float *max) template<class Tree> static float bvh_cost(Tree *obj) { - assert(obj->cost >= 0.0); + assert(obj->cost >= 0.0f); return obj->cost; } diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp index ca74367dd37..6f14c6153f9 100644 --- a/source/blender/render/intern/raytrace/rayobject.cpp +++ b/source/blender/render/intern/raytrace/rayobject.cpp @@ -369,12 +369,12 @@ int RE_rayobject_raycast(RayObject *r, Isect *isec) /* setup vars used on raycast */ for (i = 0; i < 3; i++) { - isec->idot_axis[i] = 1.0f / isec->dir[i]; + isec->idot_axis[i] = 1.0f / isec->dir[i]; - isec->bv_index[2 * i] = isec->idot_axis[i] < 0.0 ? 1 : 0; + isec->bv_index[2 * i] = isec->idot_axis[i] < 0.0f ? 1 : 0; isec->bv_index[2 * i + 1] = 1 - isec->bv_index[2 * i]; - isec->bv_index[2 * i] = i + 3 * isec->bv_index[2 * i]; + isec->bv_index[2 * i] = i + 3 * isec->bv_index[2 * i]; isec->bv_index[2 * i + 1] = i + 3 * isec->bv_index[2 * i + 1]; } diff --git a/source/blender/render/intern/raytrace/rayobject_instance.cpp b/source/blender/render/intern/raytrace/rayobject_instance.cpp index bfbc1c64133..c3e761ae069 100644 --- a/source/blender/render/intern/raytrace/rayobject_instance.cpp +++ b/source/blender/render/intern/raytrace/rayobject_instance.cpp @@ -118,7 +118,7 @@ static int RE_rayobject_instance_intersect(RayObject *o, Isect *isec) for (i = 0; i < 3; i++) { isec->idot_axis[i] = 1.0f / isec->dir[i]; - isec->bv_index[2 * i] = isec->idot_axis[i] < 0.0 ? 1 : 0; + isec->bv_index[2 * i] = isec->idot_axis[i] < 0.0f ? 1 : 0; isec->bv_index[2 * i + 1] = 1 - isec->bv_index[2 * i]; isec->bv_index[2 * i] = i + 3 * isec->bv_index[2 * i]; @@ -161,7 +161,7 @@ static int RE_rayobject_instance_intersect(RayObject *o, Isect *isec) // restore bv_index for (i = 0; i < 3; i++) { - isec->bv_index[2 * i] = isec->idot_axis[i] < 0.0 ? 1 : 0; + isec->bv_index[2 * i] = isec->idot_axis[i] < 0.0f ? 1 : 0; isec->bv_index[2 * i + 1] = 1 - isec->bv_index[2 * i]; isec->bv_index[2 * i] = i + 3 * isec->bv_index[2 * i]; diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp index 538c5493282..5ae716ac942 100644 --- a/source/blender/render/intern/raytrace/rayobject_octree.cpp +++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp @@ -649,9 +649,9 @@ static void RE_rayobject_octree_done(RayObject *tree) t02 = oc->max[2] - oc->min[2]; /* this minus 0.1 is old safety... seems to be needed? */ - oc->ocfacx = (oc->ocres - 0.1) / t00; - oc->ocfacy = (oc->ocres - 0.1) / t01; - oc->ocfacz = (oc->ocres - 0.1) / t02; + oc->ocfacx = (oc->ocres - 0.1f) / t00; + oc->ocfacy = (oc->ocres - 0.1f) / t01; + oc->ocfacz = (oc->ocres - 0.1f) / t02; oc->ocsize = sqrt(t00 * t00 + t01 * t01 + t02 * t02); /* global, max size octree */ diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index a6f6458392f..ee7372d9848 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -232,7 +232,7 @@ void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void), obr= RE_addRenderObject(re, NULL, NULL, 0, 0, 0); for (x = sx, fx = sx * stargrid; x <= ex; x++, fx += stargrid) { - for (y = sy, fy = sy * stargrid; y <= ey ; y++, fy += stargrid) { + for (y = sy, fy = sy * stargrid; y <= ey; y++, fy += stargrid) { for (z = sz, fz = sz * stargrid; z <= ez; z++, fz += stargrid) { BLI_srand((hash[z & 0xff] << 24) + (hash[y & 0xff] << 16) + (hash[x & 0xff] << 8)); diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 5879a9bd66d..26bd482af69 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -476,7 +476,7 @@ static void render_envmap(Render *re, EnvMap *env) ibuf->profile = IB_PROFILE_LINEAR_RGB; /* envmap renders without alpha */ - alpha = ((float *)ibuf->rect_float) + 3; + alpha = ibuf->rect_float + 3; for (y = ibuf->x * ibuf->y - 1; y >= 0; y--, alpha += 4) *alpha = 1.0; diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 3e6d0f281fd..0a90a55b3bc 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -980,9 +980,9 @@ static void alpha_clip_aniso(ImBuf *ibuf, float minx, float miny, float maxx, fl rf.ymin = miny*(ibuf->y); rf.ymax = maxy*(ibuf->y); - alphaclip = clipx_rctf(&rf, 0.0, (float)(ibuf->x)); - alphaclip*= clipy_rctf(&rf, 0.0, (float)(ibuf->y)); - alphaclip= MAX2(alphaclip, 0.0f); + alphaclip = clipx_rctf(&rf, 0.0, (float)(ibuf->x)); + alphaclip *= clipy_rctf(&rf, 0.0, (float)(ibuf->y)); + alphaclip = maxf(alphaclip, 0.0f); if (alphaclip!=1.0f) { /* premul it all */ @@ -1236,8 +1236,8 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex float fProbes; a *= ff; b *= ff; - a = MAX2(a, 1.f); - b = MAX2(b, 1.f); + a = maxf(a, 1.0f); + b = maxf(b, 1.0f); fProbes = 2.f*(a / b) - 1.f; AFD.iProbes = (int)floorf(fProbes + 0.5f); AFD.iProbes = MIN2(AFD.iProbes, tex->afmax); @@ -1253,8 +1253,8 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex if (ecc > (float)tex->afmax) b = a / (float)tex->afmax; b *= ff; } - maxd = MAX2(b, 1e-8f); - levf = ((float)M_LOG2E)*logf(maxd); + maxd = maxf(b, 1e-8f); + levf = ((float)M_LOG2E) * logf(maxd); curmap = 0; maxlev = 1; @@ -1338,8 +1338,8 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex imp2radangle(A, B, C, F, &a, &b, &th, &ecc); a *= ff; b *= ff; - a = MAX2(a, 1.f); - b = MAX2(b, 1.f); + a = maxf(a, 1.0f); + b = maxf(b, 1.0f); fProbes = 2.f*(a / b) - 1.f; /* no limit to number of Probes here */ AFD.iProbes = (int)floorf(fProbes + 0.5f); @@ -1622,12 +1622,12 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const ImBuf *previbuf, *curibuf; float bumpscale; - dx= minx; - dy= miny; - maxd= MAX2(dx, dy); - if (maxd>0.5f) maxd= 0.5f; + dx = minx; + dy = miny; + maxd = maxf(dx, dy); + if (maxd > 0.5f) maxd = 0.5f; - pixsize = 1.0f/ (float) MIN2(ibuf->x, ibuf->y); + pixsize = 1.0f / (float) MIN2(ibuf->x, ibuf->y); bumpscale= pixsize/maxd; if (bumpscale>1.0f) bumpscale= 1.0f; @@ -1779,11 +1779,8 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const } /* de-premul, this is being premulled in shade_input_do_shade() */ - if (texres->ta!=1.0f && texres->ta>1e-4f) { - fx= 1.0f/texres->ta; - texres->tr*= fx; - texres->tg*= fx; - texres->tb*= fx; + if (texres->ta != 1.0f && texres->ta > 1e-4f) { + mul_v3_fl(&texres->tr, 1.0f / texres->ta); } BRICONTRGB; @@ -1791,25 +1788,22 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const return retval; } -void image_sample(Image *ima, float fx, float fy, float dx, float dy, float *result) +void image_sample(Image *ima, float fx, float fy, float dx, float dy, float result[4]) { TexResult texres; ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); - if (ibuf==NULL) { - result[0]= result[1]= result[2]= result[3]= 0.0f; + if (UNLIKELY(ibuf == NULL)) { + zero_v4(result); return; } if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) ibuf->rect+= (ibuf->x*ibuf->y); - texres.talpha= 1; /* boxsample expects to be initialized */ - boxsample(ibuf, fx, fy, fx+dx, fy+dy, &texres, 0, 1); - result[0]= texres.tr; - result[1]= texres.tg; - result[2]= texres.tb; - result[3]= texres.ta; + texres.talpha = TRUE; /* boxsample expects to be initialized */ + boxsample(ibuf, fx, fy, fx + dx, fy + dy, &texres, 0, 1); + copy_v4_v4(result, &texres.tr); if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) ibuf->rect-= (ibuf->x*ibuf->y); @@ -1817,15 +1811,11 @@ void image_sample(Image *ima, float fx, float fy, float dx, float dy, float *res ima->flag|= IMA_USED_FOR_RENDER; } -void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result) +void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float result[4]) { - TexResult texres; + TexResult texres = {0}; afdata_t AFD; - - if (ibuf==NULL) { - return; - } - + AFD.dxt[0] = dx; AFD.dxt[1] = dx; AFD.dyt[0] = dy; AFD.dyt[1] = dy; //copy_v2_v2(AFD.dxt, dx); @@ -1833,13 +1823,8 @@ void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float *res AFD.intpol = 1; AFD.extflag = TXC_EXTD; - - memset(&texres, 0, sizeof(texres)); + ewa_eval(&texres, ibuf, fx, fy, &AFD); - - result[0]= texres.tr; - result[1]= texres.tg; - result[2]= texres.tb; - result[3]= texres.ta; + copy_v4_v4(result, &texres.tr); } diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 77f75caa36a..dc75cf58654 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -245,18 +245,6 @@ Render *RE_GetRender(const char *name) return re; } -Render *RE_GetRender_FromData(const RenderData *rd) -{ - Render *re; - - /* search for existing renders */ - for (re = RenderGlobal.renderlist.first; re; re = re->next) - if (&re->r == rd) - break; - - return re; -} - /* if you want to know exactly what has been done */ RenderResult *RE_AcquireResultRead(Render *re) { @@ -1827,8 +1815,11 @@ static int node_tree_has_composite_output(bNodeTree *ntree) return TRUE; } else if (node->type == NODE_GROUP) { - if (node_tree_has_composite_output((bNodeTree *)node->id)) - return TRUE; + if (node->id) { + if (node_tree_has_composite_output((bNodeTree *)node->id)) { + return TRUE; + } + } } } diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index cb7122c834c..aa35d73f3b5 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -1515,7 +1515,7 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr) if (!(shi->combinedflag & SCE_PASS_REFRACT)) sub_v3_v3v3(diff, diff, shr->refr); - shr->alpha= MIN2(1.0f, tracol[3]); + shr->alpha = minf(1.0f, tracol[3]); } if (do_mir) { diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 3703f819b3b..e5bbb212def 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -1733,7 +1733,7 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, if (mtex->texco == TEXCO_UV) { /* for the uv case, use the same value for both du/dv, * since individually scaling the normal derivatives makes them useless... */ - du = MIN2(du, dv); + du = minf(du, dv); idu = (du < 1e-5f) ? bf : (bf/du); /* +u val */ @@ -3636,7 +3636,7 @@ void RE_sample_material_color(Material *mat, float color[3], float *alpha, const float *uv1, *uv2, *uv3; float l; CustomData *data = &orcoDm->faceData; - MTFace *tface = (MTFace*) data->layers[layer_index+i].data; + MTFace *tface = (MTFace *) data->layers[layer_index+i].data; float uv[3]; /* point layer name from actual layer data */ shi.uv[i].name = data->layers[i].name; diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 63aa6cdd139..a6b2c98f9d3 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -1541,8 +1541,7 @@ static void shade_sample_sss(ShadeSample *ssamp, Material *mat, ObjectInstanceRe copy_v3_v3(shi->facenor, nor); shade_input_set_viewco(shi, x, y, sx, sy, z); - *area= len_v3(shi->dxco)*len_v3(shi->dyco); - *area= MIN2(*area, 2.0f*orthoarea); + *area = minf(len_v3(shi->dxco) * len_v3(shi->dyco), 2.0f * orthoarea); shade_input_set_uv(shi); shade_input_set_normals(shi); diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index 7dc77d3632a..4c90c3b4a6f 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -322,8 +322,8 @@ static void compress_deepshadowbuf(Render *re, ShadBuf *shb, APixstr *apixbuf, A shsample= MEM_callocN(sizeof(ShadSampleBuf), "shad sample buf"); BLI_addtail(&shb->buffers, shsample); - shsample->totbuf= MEM_callocN(sizeof(int)*size*size, "deeptotbuf"); - shsample->deepbuf= MEM_callocN(sizeof(DeepSample*)*size*size, "deepbuf"); + shsample->totbuf = MEM_callocN(sizeof(int) * size * size, "deeptotbuf"); + shsample->deepbuf = MEM_callocN(sizeof(DeepSample *) * size * size, "deepbuf"); ap= apixbuf; aps= apixbufstrand; @@ -1391,7 +1391,7 @@ float shadow_halo(LampRen *lar, const float p1[3], const float p2[3]) } } - labda= MIN2(labdax, labday); + labda = minf(labdax, labday); if (labda==labdao || labda>=1.0f) break; zf= zf1 + labda*(zf2-zf1); diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c index 46d52e83eda..69e738e840d 100644 --- a/source/blender/render/intern/source/sss.c +++ b/source/blender/render/intern/source/sss.c @@ -305,7 +305,7 @@ ScatterSettings *scatter_settings_new(float refl, float radius, float ior, float ss->Fdr= -1.440f/ior*ior + 0.710f/ior + 0.668f + 0.0636f*ior; ss->A= (1.0f + ss->Fdr)/(1.0f - ss->Fdr); ss->ld= radius; - ss->ro= MIN2(refl, 0.999f); + ss->ro= minf(refl, 0.999f); ss->color= ss->ro*reflfac + (1.0f-reflfac); ss->alpha_= compute_reduced_albedo(ss); @@ -747,8 +747,8 @@ ScatterTree *scatter_tree_new(ScatterSettings *ss[3], float scale, float error, tree->ss[1]= ss[1]; tree->ss[2]= ss[2]; - points= MEM_callocN(sizeof(ScatterPoint)*totpoint, "ScatterPoints"); - refpoints= MEM_callocN(sizeof(ScatterPoint*)*totpoint, "ScatterRefPoints"); + points = MEM_callocN(sizeof(ScatterPoint) * totpoint, "ScatterPoints"); + refpoints = MEM_callocN(sizeof(ScatterPoint *) * totpoint, "ScatterRefPoints"); tree->points= points; tree->refpoints= refpoints; @@ -777,8 +777,8 @@ void scatter_tree_build(ScatterTree *tree) float mid[3], size[3]; int totpoint= tree->totpoint; - newpoints= MEM_callocN(sizeof(ScatterPoint)*totpoint, "ScatterPoints"); - tmppoints= MEM_callocN(sizeof(ScatterPoint*)*totpoint, "ScatterTmpPoints"); + newpoints = MEM_callocN(sizeof(ScatterPoint) * totpoint, "ScatterPoints"); + tmppoints = MEM_callocN(sizeof(ScatterPoint *) * totpoint, "ScatterTmpPoints"); tree->tmppoints= tmppoints; tree->arena= BLI_memarena_new(0x8000 * sizeof(ScatterNode), "sss tree arena"); diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index e09529fd8ac..8d228473de7 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -149,8 +149,8 @@ static void zbuf_add_to_span(ZSpan *zspan, const float *v1, const float *v2) xs0= dx0*(minv[1]-my2) + minv[0]; } else { - dx0= 0.0f; - xs0= MIN2(minv[0], maxv[0]); + dx0 = 0.0f; + xs0 = minf(minv[0], maxv[0]); } /* empty span */ @@ -3874,7 +3874,7 @@ static int addtosamp_shr(ShadeResult *samp_shr, ShadeSample *ssamp, int addpassf addAlphaUnderFloat(samp_shr->combined, shr->combined); - samp_shr->z= MIN2(samp_shr->z, shr->z); + samp_shr->z = minf(samp_shr->z, shr->z); if (addpassflag & SCE_PASS_VECTOR) { copy_v4_v4(samp_shr->winspeed, shr->winspeed); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 5011c785e90..60efc3b3541 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -310,15 +310,15 @@ int WM_jobs_test(struct wmWindowManager *wm, void *owner); float WM_jobs_progress(struct wmWindowManager *wm, void *owner); char *WM_jobs_name(struct wmWindowManager *wm, void *owner); -int WM_jobs_is_running(struct wmJob *); -void* WM_jobs_get_customdata(struct wmJob *); -void WM_jobs_customdata(struct wmJob *, void *customdata, void (*free)(void *)); -void WM_jobs_timer(struct wmJob *, double timestep, unsigned int note, unsigned int endnote); -void WM_jobs_callbacks(struct wmJob *, - void (*startjob)(void *, short *, short *, float *), - void (*initjob)(void *), - void (*update)(void *), - void (*endjob)(void *)); +int WM_jobs_is_running(struct wmJob *); +void * WM_jobs_get_customdata(struct wmJob *); +void WM_jobs_customdata(struct wmJob *, void *customdata, void (*free)(void *)); +void WM_jobs_timer(struct wmJob *, double timestep, unsigned int note, unsigned int endnote); +void WM_jobs_callbacks(struct wmJob *, + void (*startjob)(void *, short *, short *, float *), + void (*initjob)(void *), + void (*update)(void *), + void (*endjob)(void *)); void WM_jobs_start(struct wmWindowManager *wm, struct wmJob *); void WM_jobs_stop(struct wmWindowManager *wm, void *owner, void *startjob); diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 8652870e280..66bb321e832 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -45,10 +45,11 @@ #include "BLI_utildefines.h" #include "BLI_math_base.h" +#include "BIF_gl.h" + #include "BKE_context.h" #include "BKE_global.h" - #include "GHOST_C-api.h" #include "ED_screen.h" @@ -505,8 +506,8 @@ static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple) /* wmOrtho for the screen has this same offset */ ratiox = sizex; ratioy = sizey; - halfx = 0.375f; - halfy = 0.375f; + halfx = GLA_PIXEL_OFS; + halfy = GLA_PIXEL_OFS; /* texture rectangle has unnormalized coordinates */ if (triple->target == GL_TEXTURE_2D) { diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 202a9d46f33..2c641b217a8 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -648,7 +648,8 @@ int WM_operator_repeat_check(const bContext *UNUSED(C), wmOperator *op) return op->type->exec != NULL; } -static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot, PointerRNA *properties, ReportList *reports) +static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot, + PointerRNA *properties, ReportList *reports) { /* XXX operatortype names are static still. for debug */ wmOperator *op = MEM_callocN(sizeof(wmOperator), ot->idname); @@ -824,7 +825,8 @@ int WM_operator_last_properties_store(wmOperator *UNUSED(op)) #endif -static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, PointerRNA *properties, ReportList *reports, short poll_only) +static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, + PointerRNA *properties, ReportList *reports, short poll_only) { wmWindowManager *wm = CTX_wm_manager(C); int retval = OPERATOR_PASS_THROUGH; @@ -843,7 +845,8 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P } if ((G.debug & G_DEBUG_EVENTS) && event && event->type != MOUSEMOVE) { - printf("%s: handle evt %d win %d op %s\n", __func__, event ? event->type : 0, CTX_wm_screen(C)->subwinactive, ot->idname); + printf("%s: handle evt %d win %d op %s\n", + __func__, event ? event->type : 0, CTX_wm_screen(C)->subwinactive, ot->idname); } if (op->type->invoke && event) { @@ -1082,7 +1085,8 @@ int WM_operator_name_call(bContext *C, const char *opstring, short context, Poin * - poll() must be called by python before this runs. * - reports can be passed to this function (so python can report them as exceptions) */ -int WM_operator_call_py(bContext *C, wmOperatorType *ot, short context, PointerRNA *properties, ReportList *reports, short is_undo) +int WM_operator_call_py(bContext *C, wmOperatorType *ot, short context, + PointerRNA *properties, ReportList *reports, short is_undo) { int retval = OPERATOR_CANCELLED; @@ -1664,22 +1668,40 @@ static int wm_action_not_handled(int action) static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) { +#ifndef NDEBUG + const int do_debug_handler = (G.debug & G_DEBUG_EVENTS); +#endif wmWindowManager *wm = CTX_wm_manager(C); wmEventHandler *handler, *nexthandler; int action = WM_HANDLER_CONTINUE; int always_pass; - if (handlers == NULL) return action; + if (handlers == NULL) { + return action; + } + +#ifndef NDEBUG + if (do_debug_handler) { + printf("%s: handling event\n", __func__); + WM_event_print(event); + } +#endif + + /* modal handlers can get removed in this loop, we keep the loop this way + * + * note: check 'handlers->first' because in rare cases the handlers can be cleared + * by the event thats called, for eg: + * + * Calling a python script which changes the area.type, see [#32232] */ + for (handler = handlers->first; handler && handlers->first; handler = nexthandler) { - /* modal handlers can get removed in this loop, we keep the loop this way */ - for (handler = handlers->first; handler; handler = nexthandler) { - nexthandler = handler->next; /* during this loop, ui handlers for nested menus can tag multiple handlers free */ - if (handler->flag & WM_HANDLER_DO_FREE) ; - /* optional boundbox */ - else if (handler_boundbox_test(handler, event)) { + if (handler->flag & WM_HANDLER_DO_FREE) { + /* pass */ + } + else if (handler_boundbox_test(handler, event)) { /* optional boundbox */ /* in advance to avoid access to freed event on window close */ always_pass = wm_event_always_pass(event); @@ -1690,20 +1712,60 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) if (handler->keymap) { wmKeyMap *keymap = WM_keymap_active(wm, handler->keymap); wmKeyMapItem *kmi; - + +#ifndef NDEBUG + if (do_debug_handler) { + printf("%s: checking '%s' ...", __func__, keymap->idname); + } +#endif + if (!keymap->poll || keymap->poll(C)) { + +#ifndef NDEBUG + if (do_debug_handler) { + printf("pass\n"); + } +#endif + for (kmi = keymap->items.first; kmi; kmi = kmi->next) { if (wm_eventmatch(event, kmi)) { +#ifndef NDEBUG + if (do_debug_handler) { + printf("%s: item matched '%s'\n", __func__, kmi->idname); + } +#endif + /* weak, but allows interactive callback to not use rawkey */ event->keymap_idname = kmi->idname; action |= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr); - if (action & WM_HANDLER_BREAK) /* not always_pass here, it denotes removed handler */ + if (action & WM_HANDLER_BREAK) { + /* not always_pass here, it denotes removed handler */ +#ifndef NDEBUG + if (do_debug_handler) { + printf("%s: handled! '%s'...", __func__, kmi->idname); + } +#endif break; + } + else { +#ifndef NDEBUG + if (do_debug_handler) { + printf("%s: un-handled '%s'...", __func__, kmi->idname); + } +#endif + } } } } + else { +#ifndef NDEBUG + if (do_debug_handler) { + printf("fail\n"); + } +#endif + } } else if (handler->ui_handle) { action |= wm_handler_ui_call(C, handler, event, always_pass); @@ -1965,7 +2027,9 @@ void wm_event_do_handlers(bContext *C) CTX_wm_screen_set(C, win->screen); CTX_data_scene_set(C, scene); - if (((playing == 1) && (!ED_screen_animation_playing(wm))) || ((playing == 0) && (ED_screen_animation_playing(wm)))) { + if (((playing == 1) && (!ED_screen_animation_playing(wm))) || + ((playing == 0) && (ED_screen_animation_playing(wm)))) + { ED_screen_animation_play(C, -1, 1); } diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index cb0f9c226b4..d4b55677af1 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -77,6 +77,7 @@ #include "BKE_global.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_multires.h" #include "BKE_packedFile.h" #include "BKE_report.h" #include "BKE_sound.h" @@ -379,6 +380,8 @@ void WM_read_file(bContext *C, const char *filepath, ReportList *reports) /* assume automated tasks with background, don't write recent file list */ const int do_history = (G.background == FALSE) && (CTX_wm_manager(C)->op_undo_depth == 0); + BKE_vfont_free_global_ttf(); + /* put aside screens to match with persistent windows later */ /* also exit screens and editors */ wm_window_match_init(C, &wmbase); @@ -488,7 +491,7 @@ int WM_read_homefile(bContext *C, ReportList *UNUSED(reports), short from_memory char tstr[FILE_MAX]; int success = 0; - BKE_vfont_free_global_ttf(); /* still weird... what does it here? */ + BKE_vfont_free_global_ttf(); G.relbase_valid = 0; if (!from_memory) { @@ -930,6 +933,7 @@ void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(w wmEventHandler *handler; char filepath[FILE_MAX]; int fileflags; + Scene *scene = CTX_data_scene(C); WM_event_remove_timer(wm, NULL, wm->autosavetimer); @@ -942,7 +946,14 @@ void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(w } } } - + + if (scene) { + Object *ob = OBACT; + + if (ob && ob->mode & OB_MODE_SCULPT) + multires_force_update(ob); + } + wm_autosave_location(filepath); /* force save as regular blend file */ diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 7a885d60bff..a03c9aa70c4 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -32,6 +32,10 @@ #include <stdio.h> #include <string.h> +#if WIN32 +#include <Windows.h> +#endif + #include "MEM_guardedalloc.h" #include "MEM_CacheLimiterC-Api.h" @@ -54,6 +58,7 @@ #include "BKE_library.h" #include "BKE_main.h" #include "BKE_mball.h" +#include "BKE_node.h" #include "BKE_report.h" #include "BKE_packedFile.h" @@ -62,6 +67,7 @@ #include "BKE_tracking.h" /* free tracking clipboard */ #include "BLI_listbase.h" +#include "BLI_math_color.h" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -137,10 +143,14 @@ void WM_init(bContext *C, int argc, const char **argv) ED_spacetypes_init(); /* editors/space_api/spacetype.c */ ED_file_init(); /* for fsmenu */ - ED_init_node_butfuncs(); + ED_node_init_butfuncs(); BLF_init(11, U.dpi); /* Please update source/gamengine/GamePlayer/GPG_ghost.cpp if you change this */ BLF_lang_init(); + + /* initialize color stuff */ + BLI_init_srgb_conversion(); + /* get the default database, plus a wm */ WM_read_homefile(C, NULL, G.factory_startup); @@ -325,10 +335,33 @@ static void free_openrecent(void) /* bad stuff*/ // XXX copy/paste buffer stuff... -extern void free_anim_copybuf(void); -extern void free_anim_drivers_copybuf(void); -extern void free_fmodifiers_copybuf(void); -extern void free_posebuf(void); +extern void free_anim_copybuf(void); +extern void free_anim_drivers_copybuf(void); +extern void free_fmodifiers_copybuf(void); +extern void free_posebuf(void); + +#if WIN32 +/* Read console events until there is a key event. Also returns on any error. */ +static void wait_for_console_key(void) +{ + HANDLE hConsoleInput = GetStdHandle(STD_INPUT_HANDLE); + + if (!ELEM(hConsoleInput, NULL, INVALID_HANDLE_VALUE) && FlushConsoleInputBuffer(hConsoleInput)) { + for (;;) { + INPUT_RECORD buffer; + DWORD ignored; + + if (!ReadConsoleInput(hConsoleInput, &buffer, 1, &ignored)) { + break; + } + + if (buffer.EventType == KEY_EVENT) { + break; + } + } + } +} +#endif /* called in creator.c even... tsk, split this! */ /* note, doesnt run exit() call WM_exit() for that */ @@ -387,6 +420,7 @@ void WM_exit_ext(bContext *C, const short do_python) free_anim_drivers_copybuf(); free_fmodifiers_copybuf(); free_posebuf(); + BKE_node_clipboard_clear(); BLF_exit(); @@ -452,10 +486,10 @@ void WM_exit_ext(bContext *C, const short do_python) printf("\nBlender quit\n"); #ifdef WIN32 - /* ask user to press enter when in debug mode */ + /* ask user to press a key when in debug mode */ if (G.debug & G_DEBUG) { - printf("press enter key to exit...\n\n"); - getchar(); + printf("Press any key to exit . . .\n\n"); + wait_for_console_key(); } #endif } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index a55efc0b216..78495f9b874 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1862,9 +1862,9 @@ static void WM_OT_link_append(wmOperatorType *ot) ot->flag |= OPTYPE_UNDO; WM_operator_properties_filesel( - ot, FOLDERFILE | BLENDERFILE, FILE_LOADLIB, FILE_OPENFILE, - WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILENAME | WM_FILESEL_RELPATH | WM_FILESEL_FILES, - FILE_DEFAULTDISPLAY); + ot, FOLDERFILE | BLENDERFILE, FILE_LOADLIB, FILE_OPENFILE, + WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILENAME | WM_FILESEL_RELPATH | WM_FILESEL_FILES, + FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, "link", 1, "Link", "Link the objects or datablocks rather than appending"); RNA_def_boolean(ot->srna, "autoselect", 1, "Select", "Select the linked objects"); @@ -1945,20 +1945,21 @@ static void WM_OT_recover_auto_save(wmOperatorType *ot) ot->invoke = wm_recover_auto_save_invoke; ot->poll = WM_operator_winactive; - WM_operator_properties_filesel(ot, BLENDERFILE, FILE_BLENDER, FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_LONGDISPLAY); + WM_operator_properties_filesel(ot, BLENDERFILE, FILE_BLENDER, FILE_OPENFILE, + WM_FILESEL_FILEPATH, FILE_LONGDISPLAY); } /* *************** save file as **************** */ -static void untitled(char *name) +static void untitled(char *filepath) { - if (G.save_over == 0 && strlen(name) < FILE_MAX - 16) { - char *c = BLI_last_slash(name); + if (G.save_over == 0 && strlen(filepath) < FILE_MAX - 16) { + char *c = BLI_last_slash(filepath); if (c) strcpy(&c[1], "untitled.blend"); else - strcpy(name, "untitled.blend"); + strcpy(filepath, "untitled.blend"); } } @@ -2065,8 +2066,8 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot) ot->check = blend_save_check; /* ommit window poll so this can work in background mode */ - WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH, - FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_SAVE, + WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file"); RNA_def_boolean(ot->srna, "relative_remap", 1, "Remap Relative", "Remap relative paths when saving in a different directory"); @@ -2137,7 +2138,8 @@ static void WM_OT_save_mainfile(wmOperatorType *ot) ot->check = blend_save_check; /* ommit window poll so this can work in background mode */ - WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); + WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_SAVE, + WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file"); RNA_def_boolean(ot->srna, "relative_remap", 0, "Remap Relative", "Remap relative paths when saving in a different directory"); } diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index 0b9dc441227..529910d220e 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -141,7 +141,7 @@ void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[][4]) int width, height; wm_subwindow_getsize(win, swin->swinid, &width, &height); - orthographic_m4(mat, -0.375f, (float)width - 0.375f, -0.375f, (float)height - 0.375f, -100, 100); + orthographic_m4(mat, -GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS, -100, 100); } else glGetFloatv(GL_PROJECTION_MATRIX, (float *)mat); @@ -175,7 +175,7 @@ int wm_subwindow_open(wmWindow *win, rcti *winrct) /* extra service */ wm_subwindow_getsize(win, swin->swinid, &width, &height); - wmOrtho2(-0.375f, (float)width - 0.375f, -0.375f, (float)height - 0.375f); + wmOrtho2(-GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS); glLoadIdentity(); return swin->swinid; @@ -229,7 +229,7 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct) /* extra service */ wmSubWindowSet(win, swinid); wm_subwindow_getsize(win, swinid, &width, &height); - wmOrtho2(-0.375f, (float)width - 0.375f, -0.375f, (float)height - 0.375f); + wmOrtho2(-GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS); } else { printf("%s: Internal error, bad winid: %d\n", __func__, swinid); @@ -268,7 +268,7 @@ void wmSubWindowScissorSet(wmWindow *win, int swinid, rcti *srct) else glScissor(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height); - wmOrtho2(-0.375f, (float)width - 0.375f, -0.375f, (float)height - 0.375f); + wmOrtho2(-GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS); glLoadIdentity(); glFlush(); diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt index 720d68ef00d..1c44ae77937 100644 --- a/source/blenderplayer/CMakeLists.txt +++ b/source/blenderplayer/CMakeLists.txt @@ -178,7 +178,7 @@ endif() list(APPEND BLENDER_SORTED_LIBS bf_intern_moto) endif() - if(WITH_CARVE) + if(WITH_MOD_BOOLEAN) list(APPEND BLENDER_SORTED_LIBS extern_carve) endif() diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 53f3dacbffa..69cb0dc619b 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -64,6 +64,7 @@ struct LOD_Decimation_Info; struct MCol; struct MTex; struct Main; +struct Mask; struct Material; struct MenuType; struct Mesh; @@ -229,6 +230,7 @@ void ED_space_image_uv_sculpt_update(struct wmWindowManager *wm, struct ToolSett void ED_screen_set_scene(struct bContext *C, struct Scene *scene) {} void ED_space_clip_set_clip(struct bContext *C, struct SpaceClip *sc, struct MovieClip *clip) {} void ED_space_clip_set_mask(struct bContext *C, struct SpaceClip *sc, struct Mask *mask) {} +void ED_space_image_set_mask(struct bContext *C, struct SpaceImage *sima, struct Mask *mask) {} void ED_area_tag_redraw_regiontype(struct ScrArea *sa, int regiontype) {} void ED_render_engine_changed(struct Main *bmain) {} @@ -271,7 +273,7 @@ short ANIM_add_driver(struct ID *id, const char rna_path[], int array_index, sho short ANIM_remove_driver(struct ID *id, const char rna_path[], int array_index, short flag) {return 0;} void ED_space_image_release_buffer(struct SpaceImage *sima, void *lock) {} struct ImBuf *ED_space_image_acquire_buffer(struct SpaceImage *sima, void **lock_r) {return (struct ImBuf *) NULL;} -void ED_space_image_zoom(struct SpaceImage *sima, struct ARegion *ar, float *zoomx, float *zoomy) {} +void ED_space_image_get_zoom(struct SpaceImage *sima, struct ARegion *ar, float *zoomx, float *zoomy) {} char *ED_info_stats_string(struct Scene *scene) {return (char *) NULL;} void ED_area_tag_redraw(struct ScrArea *sa) {} void ED_area_tag_refresh(struct ScrArea *sa) {} @@ -345,7 +347,8 @@ intptr_t mesh_octree_table(struct Object *ob, struct BMEditMesh *em, float *co, void ED_sequencer_update_view(struct bContext *C, int view) {} float ED_rollBoneToVector(struct EditBone *bone, float new_up_axis[3]) {return 0.0f;} -void ED_space_image_size(struct SpaceImage *sima, int *width, int *height) {} +void ED_space_image_get_size(struct SpaceImage *sima, int *width, int *height) {} +int ED_space_image_check_show_maskedit(struct Scene *scene, struct SpaceImage *sima) {return 0;}; void ED_nurb_set_spline_type(struct Nurb *nu, int type) {} diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 9571153d037..056c6e32ec2 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -475,15 +475,15 @@ elseif(WIN32) endif() if(WITH_PYTHON) - set_lib_path(PYLIB "python/lib") + set_lib_path(PYLIB "python") install( - FILES ${PYLIB}/python32.dll + FILES ${PYLIB}/lib/python32.dll DESTINATION ${TARGETDIR} CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel ) install( - FILES ${PYLIB}/python32_d.dll + FILES ${PYLIB}/lib/python32_d.dll DESTINATION ${TARGETDIR} CONFIGURATIONS Debug ) @@ -627,10 +627,10 @@ elseif(WIN32) if(WITH_OPENIMAGEIO) if(NOT MINGW) - set_lib_path(OIIOBIN "openimageio/bin") + set_lib_path(OIIOBIN "openimageio") install( FILES - ${OIIOBIN}/OpenImageIO.dll + ${OIIOBIN}/bin/OpenImageIO.dll DESTINATION ${TARGETDIR} ) endif() @@ -943,7 +943,7 @@ endif() list(APPEND BLENDER_SORTED_LIBS bf_quicktime) endif() - if(WITH_CARVE) + if(WITH_MOD_BOOLEAN) list(APPEND BLENDER_SORTED_LIBS extern_carve) endif() diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index cab6d0fc376..92d04115f10 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -145,7 +145,6 @@ void BL_ActionActuator::SetLocalTime(float curtime) case ACT_ACTION_PLAY: // Clamp m_localtime = m_endframe; - ((KX_GameObject*)GetParent())->StopAction(m_layer); break; case ACT_ACTION_LOOP_END: // Put the time back to the beginning @@ -339,7 +338,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame) } } - return m_flag & ACT_FLAG_ATTEMPT_PLAY; + return m_flag & ACT_FLAG_ACTIVE; } #ifdef WITH_PYTHON diff --git a/source/gameengine/Converter/BL_ArmatureObject.h b/source/gameengine/Converter/BL_ArmatureObject.h index ced6b94e6fd..6274e770409 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.h +++ b/source/gameengine/Converter/BL_ArmatureObject.h @@ -83,7 +83,7 @@ public: bool SetActiveAction(class BL_ActionActuator *act, short priority, double curtime); - struct bArmature * GetArmature() { return m_armature; } + struct bArmature *GetArmature() { return m_armature; } const struct bArmature * GetArmature() const { return m_armature; } const struct Scene * GetScene() const { return m_scene; } diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index 9bbf07a3ed2..47cba81798d 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -238,6 +238,7 @@ void BL_SkinDeformer::BGEDeformVerts() MDeformVert *dverts = m_bmesh->dvert; bDeformGroup *dg; int defbase_tot = BLI_countlist(&m_objMesh->defbase); + Eigen::Matrix4f pre_mat, post_mat, chan_mat, norm_chan_mat; if (!dverts) return; @@ -257,15 +258,18 @@ void BL_SkinDeformer::BGEDeformVerts() } } + post_mat = Eigen::Matrix4f::Map((float*)m_obmat).inverse() * Eigen::Matrix4f::Map((float*)m_armobj->GetArmatureObject()->obmat); + pre_mat = post_mat.inverse(); + MDeformVert *dv= dverts; + MDeformWeight *dw; for (int i=0; i<m_bmesh->totvert; ++i, dv++) { - float contrib = 0.f, weight, max_weight=0.f; + float contrib = 0.f, weight, max_weight=-1.f; bPoseChannel *pchan=NULL; - Eigen::Map<Eigen::Vector3f> norm(m_transnors[i]); + Eigen::Map<Eigen::Vector3f> norm = Eigen::Vector3f::Map(m_transnors[i]); Eigen::Vector4f vec(0, 0, 0, 1); - Eigen::Matrix4f norm_chan_mat; Eigen::Vector4f co(m_transverts[i][0], m_transverts[i][1], m_transverts[i][2], @@ -274,7 +278,9 @@ void BL_SkinDeformer::BGEDeformVerts() if (!dv->totweight) continue; - MDeformWeight *dw= dv->dw; + co = pre_mat * co; + + dw= dv->dw; for (unsigned int j= dv->totweight; j != 0; j--, dw++) { @@ -286,12 +292,10 @@ void BL_SkinDeformer::BGEDeformVerts() if (weight) { - Eigen::Vector4f cop(co); - Eigen::Matrix4f chan_mat = Eigen::Matrix4f::Map((float*)pchan->chan_mat); + chan_mat = Eigen::Matrix4f::Map((float*)pchan->chan_mat); // Update Vertex Position - cop = chan_mat*cop; - vec += (cop - co)*weight; + vec.noalias() += (chan_mat*co - co)*weight; // Save the most influential channel so we can use it to update the vertex normal if (weight > max_weight) @@ -304,16 +308,14 @@ void BL_SkinDeformer::BGEDeformVerts() } } } - // Update Vertex Normal norm = norm_chan_mat.topLeftCorner<3, 3>()*norm; - - if (contrib > 0.0001f) - { - vec *= 1.f/contrib; - co += vec; - } + + co.noalias() += vec/contrib; + co[3] = 1.f; // Make sure we have a 1 for the w component! + + co = post_mat * co; m_transverts[i][0] = co[0]; m_transverts[i][1] = co[1]; diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 3961e6554a7..1c3352454a2 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -988,8 +988,7 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha load_datablocks(main_newlib, bpy_openlib, path, idcode); - if (idcode==ID_SCE) { - /* assume we want text blocks too */ + if (idcode==ID_SCE && options & LIB_LOAD_LOAD_SCRIPTS) { load_datablocks(main_newlib, bpy_openlib, path, ID_TXT); } @@ -1044,9 +1043,11 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha delete other; } +#ifdef WITH_PYTHON /* Handle any text datablocks */ - - addImportMain(main_newlib); + if (options & LIB_LOAD_LOAD_SCRIPTS) + addImportMain(main_newlib); +#endif /* Now handle all the actions */ if (options & LIB_LOAD_LOAD_ACTIONS) { @@ -1340,8 +1341,11 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie) } } - /* make sure this maggie is removed from the import list if it's there (this operation is safe if it isn't in the list) */ +#ifdef WITH_PYTHON + /* make sure this maggie is removed from the import list if it's there + * (this operation is safe if it isn't in the list) */ removeImportMain(maggie); +#endif free_main(maggie); diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h index 906e3fed111..b51c2f21ca7 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.h +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h @@ -182,6 +182,7 @@ public: { LIB_LOAD_LOAD_ACTIONS = 1, LIB_LOAD_VERBOSE = 2, + LIB_LOAD_LOAD_SCRIPTS = 4, }; diff --git a/source/gameengine/Ketsji/BL_Action.cpp b/source/gameengine/Ketsji/BL_Action.cpp index fbeb34b70b4..a21c3965be9 100644 --- a/source/gameengine/Ketsji/BL_Action.cpp +++ b/source/gameengine/Ketsji/BL_Action.cpp @@ -206,7 +206,7 @@ bool BL_Action::Play(const char* name, } // Now that we have an action, we have something we can play - m_starttime = KX_GetActiveEngine()->GetFrameTime(); + m_starttime = -1.f; // We get the start time on our first update m_startframe = m_localtime = start; m_endframe = end; m_blendin = blendin; @@ -338,6 +338,11 @@ void BL_Action::Update(float curtime) curtime -= KX_KetsjiEngine::GetSuspendedDelta(); + // Grab the start time here so we don't end up with a negative m_localtime when + // suspending and resuming scenes. + if (m_starttime < 0) + m_starttime = curtime; + if (m_calc_localtime) SetLocalTime(curtime); else diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp index f2d67e9131d..e4e3fb95543 100644 --- a/source/gameengine/Ketsji/BL_Texture.cpp +++ b/source/gameengine/Ketsji/BL_Texture.cpp @@ -29,6 +29,7 @@ #include "MEM_guardedalloc.h" #include "GPU_draw.h" +#include "GPU_extensions.h" extern "C" { // envmaps @@ -116,6 +117,7 @@ bool BL_Texture::InitFromImage(int unit, Image *img, bool mipmap) return mOk; } + mipmap = mipmap && GPU_get_mipmap(); mTexture = img->bindcode; mType = GL_TEXTURE_2D; @@ -169,7 +171,7 @@ bool BL_Texture::InitFromImage(int unit, Image *img, bool mipmap) void BL_Texture::InitGLTex(unsigned int *pix,int x,int y,bool mipmap) { - if (!GLEW_ARB_texture_non_power_of_two && (!is_power_of_2_i(x) || !is_power_of_2_i(y)) ) { + if (!GPU_non_power_of_two_support() && (!is_power_of_2_i(x) || !is_power_of_2_i(y)) ) { InitNonPow2Tex(pix, x,y,mipmap); return; } @@ -182,7 +184,7 @@ void BL_Texture::InitGLTex(unsigned int *pix,int x,int y,bool mipmap) } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix ); } diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index b28b8c86d33..b602ba447ad 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -130,10 +130,10 @@ unsigned int* KX_BlenderMaterial::GetMCol(void) const void KX_BlenderMaterial::GetMaterialRGBAColor(unsigned char *rgba) const { if (mMaterial) { - *rgba++ = (unsigned char) (mMaterial->matcolor[0]*255.0); - *rgba++ = (unsigned char) (mMaterial->matcolor[1]*255.0); - *rgba++ = (unsigned char) (mMaterial->matcolor[2]*255.0); - *rgba++ = (unsigned char) (mMaterial->matcolor[3]*255.0); + *rgba++ = (unsigned char)(mMaterial->matcolor[0] * 255.0f); + *rgba++ = (unsigned char)(mMaterial->matcolor[1] * 255.0f); + *rgba++ = (unsigned char)(mMaterial->matcolor[2] * 255.0f); + *rgba++ = (unsigned char)(mMaterial->matcolor[3] * 255.0f); } else RAS_IPolyMaterial::GetMaterialRGBAColor(rgba); } diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp index e009478c803..4c63afa7f3e 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.cpp +++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp @@ -33,6 +33,7 @@ * \ingroup ketsji */ +#include "BLI_math_vector.h" #include "KX_CameraActuator.h" #include <iostream> @@ -42,7 +43,6 @@ #include "PyObjectPlus.h" - /* ------------------------------------------------------------------------- */ /* Native functions */ /* ------------------------------------------------------------------------- */ @@ -113,34 +113,7 @@ void KX_CameraActuator::Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map) } } -/* three functions copied from blender arith... don't know if there's an equivalent */ - -static float Kx_Normalize(float *n) -{ - float d; - - d= n[0]*n[0]+n[1]*n[1]+n[2]*n[2]; - /* FLT_EPSILON is too large! A larger value causes normalize errors in a scaled down utah teapot */ - if (d>0.0000000000001) { - d= sqrt(d); - - n[0]/=d; - n[1]/=d; - n[2]/=d; - } else { - n[0]=n[1]=n[2]= 0.0; - d= 0.0; - } - return d; -} - -static void Kx_Crossf(float *c, float *a, float *b) -{ - c[0] = a[1] * b[2] - a[2] * b[1]; - c[1] = a[2] * b[0] - a[0] * b[2]; - c[2] = a[0] * b[1] - a[1] * b[0]; -} - +/* copied from blender BLI_math ... don't know if there's an equivalent */ static void Kx_VecUpMat3(float vec[3], float mat[][3], short axis) { @@ -184,7 +157,7 @@ static void Kx_VecUpMat3(float vec[3], float mat[][3], short axis) mat[coz][0]= vec[0]; mat[coz][1]= vec[1]; mat[coz][2]= vec[2]; - if (Kx_Normalize((float *)mat[coz]) == 0.f) { + if (normalize_v3((float *)mat[coz]) == 0.f) { /* this is a very abnormal situation: the camera has reach the object center exactly * We will choose a completely arbitrary direction */ mat[coz][0] = 1.0f; @@ -197,15 +170,14 @@ static void Kx_VecUpMat3(float vec[3], float mat[][3], short axis) mat[coy][1] = - inp * mat[coz][1]; mat[coy][2] = 1.0f - inp * mat[coz][2]; - if (Kx_Normalize((float *)mat[coy]) == 0.f) { + if (normalize_v3((float *)mat[coy]) == 0.f) { /* the camera is vertical, chose the y axis arbitrary */ mat[coy][0] = 0.f; mat[coy][1] = 1.f; mat[coy][2] = 0.f; } - Kx_Crossf(mat[cox], mat[coy], mat[coz]); - + cross_v3_v3v3(mat[cox], mat[coy], mat[coz]); } bool KX_CameraActuator::Update(double curtime, bool frame) diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index d87bb937b41..44c9cb1dab8 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -748,10 +748,10 @@ void KX_Dome::CreateMeshDome250(void) * Once we take the tangent of that angle, you have the verts coordinate corresponding to the verts on the side faces. * Then we need to multiply it by sqrt(2.0) to get the coordinate of the verts on the diagonal of the original cube. */ - verts_height = tan((rad_ang/2) - (MT_PI/2))*M_SQRT2; + verts_height = tanf((rad_ang / 2.0f) - (float)(MT_PI / 2.0)) * (float)M_SQRT2; - uv_height = uv_ratio * ((verts_height/2) + 0.5); - uv_base = uv_ratio * (1.0 - ((verts_height/2) + 0.5)); + uv_height = uv_ratio * ( (verts_height / 2.0f) + 0.5f); + uv_base = uv_ratio * (1.0 - ((verts_height / 2.0f) + 0.5f)); //creating faces for the env mapcube 180deg Dome // Front Face - 2 triangles @@ -1325,7 +1325,7 @@ void KX_Dome::FlattenDome(MT_Vector3 verts[3]) for (int i=0;i<3;i++) { r = atan2(sqrt(verts[i][0]*verts[i][0] + verts[i][2]*verts[i][2]), verts[i][1]); - r /= m_radangle/2; + r /= (double)this->m_radangle / 2.0; phi = atan2(verts[i][2], verts[i][0]); @@ -1818,13 +1818,13 @@ void KX_Dome::DrawDomeFisheye(void) else if (m_mode == DOME_TRUNCATED_FRONT) { ortho_width = 1.0; - ortho_height = 2 * ((float)can_height / can_width) - 1.0; + ortho_height = 2.0f * ((float)can_height / can_width) - 1.0f; glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_width, -20.0, 10.0); } else { //m_mode == DOME_TRUNCATED_REAR ortho_width = 1.0; - ortho_height = 2 * ((float)can_height / can_width) - 1.0; + ortho_height = 2.0f * ((float)can_height / can_width) - 1.0f; glOrtho((-ortho_width), ortho_width, (-ortho_width), ortho_height, -20.0, 10.0); } @@ -1905,8 +1905,8 @@ void KX_Dome::DrawPanorama(void) ortho_height = (float)can_height/can_width; } else { - ortho_width = (float)can_width/can_height * 0.5; - ortho_height = 0.5; + ortho_width = (float)can_width / can_height * 0.5f; + ortho_height = 0.5f; } glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); diff --git a/source/gameengine/Ketsji/KX_FontObject.cpp b/source/gameengine/Ketsji/KX_FontObject.cpp index 308154d8ebc..931eac7a974 100644 --- a/source/gameengine/Ketsji/KX_FontObject.cpp +++ b/source/gameengine/Ketsji/KX_FontObject.cpp @@ -117,25 +117,25 @@ void KX_FontObject::ProcessReplica() KX_GetActiveScene()->AddFont(this); } -int GetFontId (VFont *font) +int GetFontId (VFont *vfont) { PackedFile *packedfile=NULL; int fontid = -1; - if (font->packedfile) { - packedfile= font->packedfile; - fontid= BLF_load_mem(font->name, (unsigned char*)packedfile->data, packedfile->size); + if (vfont->packedfile) { + packedfile= vfont->packedfile; + fontid= BLF_load_mem(vfont->name, (unsigned char*)packedfile->data, packedfile->size); if (fontid == -1) { - printf("ERROR: packed font \"%s\" could not be loaded.\n", font->name); + printf("ERROR: packed font \"%s\" could not be loaded.\n", vfont->name); fontid = BLF_load("default"); } return fontid; } - /* once we have packed working we can load the FO_BUILTIN_NAME font */ - const char *filepath = font->name; - if (strcmp(FO_BUILTIN_NAME, filepath) == 0) { + /* once we have packed working we can load the builtin font */ + const char *filepath = vfont->name; + if (BKE_vfont_is_builtin(vfont)) { fontid = BLF_load("default"); /* XXX the following code is supposed to work (after you add get_builtin_packedfile to BKE_font.h ) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 496b3925456..04a806dfd92 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -261,12 +261,12 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj, bool addToCom // Make sure the objects have some scale MT_Vector3 scale1 = NodeGetWorldScaling(); MT_Vector3 scale2 = obj->NodeGetWorldScaling(); - if (fabs(scale2[0]) < FLT_EPSILON || - fabs(scale2[1]) < FLT_EPSILON || - fabs(scale2[2]) < FLT_EPSILON || - fabs(scale1[0]) < FLT_EPSILON || - fabs(scale1[1]) < FLT_EPSILON || - fabs(scale1[2]) < FLT_EPSILON) { return; } + if (fabs(scale2[0]) < (MT_Scalar)FLT_EPSILON || + fabs(scale2[1]) < (MT_Scalar)FLT_EPSILON || + fabs(scale2[2]) < (MT_Scalar)FLT_EPSILON || + fabs(scale1[0]) < (MT_Scalar)FLT_EPSILON || + fabs(scale1[1]) < (MT_Scalar)FLT_EPSILON || + fabs(scale1[2]) < (MT_Scalar)FLT_EPSILON) { return; } // Remove us from our old parent and set our new parent RemoveParent(scene); @@ -931,7 +931,7 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac) return; } - if (fac<=0.0) { + if (fac <= 0.0f) { return; } @@ -944,10 +944,10 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac) ori.setValue(orimat[0][2], orimat[1][2], orimat[2][2]); //pivot axis if (MT_abs(vect.dot(ori)) > 1.0-3.0*MT_EPSILON) //is the vector parallel to the pivot? ori.setValue(orimat[0][1], orimat[1][1], orimat[2][1]); //change the pivot! - if (fac == 1.0) { + if (fac == 1.0f) { x = vect; } else { - x = (vect * fac) + ((orimat * MT_Vector3(1.0, 0.0, 0.0)) * (1-fac)); + x = (vect * fac) + ((orimat * MT_Vector3(1.0, 0.0, 0.0)) * (1.0f - fac)); len = x.length(); if (MT_fuzzyZero(len)) x = vect; else x /= len; @@ -959,10 +959,10 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac) ori.setValue(orimat[0][0], orimat[1][0], orimat[2][0]); if (MT_abs(vect.dot(ori)) > 1.0-3.0*MT_EPSILON) ori.setValue(orimat[0][2], orimat[1][2], orimat[2][2]); - if (fac == 1.0) { + if (fac == 1.0f) { y = vect; } else { - y = (vect * fac) + ((orimat * MT_Vector3(0.0, 1.0, 0.0)) * (1-fac)); + y = (vect * fac) + ((orimat * MT_Vector3(0.0, 1.0, 0.0)) * (1.0f - fac)); len = y.length(); if (MT_fuzzyZero(len)) y = vect; else y /= len; @@ -974,10 +974,10 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac) ori.setValue(orimat[0][1], orimat[1][1], orimat[2][1]); if (MT_abs(vect.dot(ori)) > 1.0-3.0*MT_EPSILON) ori.setValue(orimat[0][0], orimat[1][0], orimat[2][0]); - if (fac == 1.0) { + if (fac == 1.0f) { z = vect; } else { - z = (vect * fac) + ((orimat * MT_Vector3(0.0, 0.0, 1.0)) * (1-fac)); + z = (vect * fac) + ((orimat * MT_Vector3(0.0, 0.0, 1.0)) * (1.0f - fac)); len = z.length(); if (MT_fuzzyZero(len)) z = vect; else z /= len; @@ -1162,9 +1162,9 @@ void KX_GameObject::NodeSetWorldScale(const MT_Vector3& scale) { // Make sure the objects have some scale MT_Vector3 p_scale = parent->GetWorldScaling(); - if (fabs(p_scale[0]) < FLT_EPSILON || - fabs(p_scale[1]) < FLT_EPSILON || - fabs(p_scale[2]) < FLT_EPSILON) + if (fabs(p_scale[0]) < (MT_Scalar)FLT_EPSILON || + fabs(p_scale[1]) < (MT_Scalar)FLT_EPSILON || + fabs(p_scale[2]) < (MT_Scalar)FLT_EPSILON) { return; } @@ -1190,9 +1190,9 @@ void KX_GameObject::NodeSetWorldPosition(const MT_Point3& trans) { // Make sure the objects have some scale MT_Vector3 scale = parent->GetWorldScaling(); - if (fabs(scale[0]) < FLT_EPSILON || - fabs(scale[1]) < FLT_EPSILON || - fabs(scale[2]) < FLT_EPSILON) + if (fabs(scale[0]) < (MT_Scalar)FLT_EPSILON || + fabs(scale[1]) < (MT_Scalar)FLT_EPSILON || + fabs(scale[2]) < (MT_Scalar)FLT_EPSILON) { return; } @@ -1940,7 +1940,7 @@ PyObject* KX_GameObject::pyattr_get_mass(void *self_v, const KX_PYATTRIBUTE_DEF { KX_GameObject* self= static_cast<KX_GameObject*>(self_v); KX_IPhysicsController *spc = self->GetPhysicsController(); - return PyFloat_FromDouble(spc ? spc->GetMass() : 0.0f); + return PyFloat_FromDouble(spc ? spc->GetMass() : 0.0); } int KX_GameObject::pyattr_set_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -1948,7 +1948,7 @@ int KX_GameObject::pyattr_set_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrd KX_GameObject* self= static_cast<KX_GameObject*>(self_v); KX_IPhysicsController *spc = self->GetPhysicsController(); MT_Scalar val = PyFloat_AsDouble(value); - if (val < 0.0f) { /* also accounts for non float */ + if (val < 0.0) { /* also accounts for non float */ PyErr_SetString(PyExc_AttributeError, "gameOb.mass = float: KX_GameObject, expected a float zero or above"); return PY_SET_ATTR_FAIL; } @@ -1971,7 +1971,7 @@ int KX_GameObject::pyattr_set_lin_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF KX_GameObject* self= static_cast<KX_GameObject*>(self_v); KX_IPhysicsController *spc = self->GetPhysicsController(); MT_Scalar val = PyFloat_AsDouble(value); - if (val < 0.0f) { /* also accounts for non float */ + if (val < 0.0) { /* also accounts for non float */ PyErr_SetString(PyExc_AttributeError, "gameOb.linVelocityMin = float: KX_GameObject, expected a float zero or above"); return PY_SET_ATTR_FAIL; } @@ -1994,7 +1994,7 @@ int KX_GameObject::pyattr_set_lin_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF KX_GameObject* self= static_cast<KX_GameObject*>(self_v); KX_IPhysicsController *spc = self->GetPhysicsController(); MT_Scalar val = PyFloat_AsDouble(value); - if (val < 0.0f) { /* also accounts for non float */ + if (val < 0.0) { /* also accounts for non float */ PyErr_SetString(PyExc_AttributeError, "gameOb.linVelocityMax = float: KX_GameObject, expected a float zero or above"); return PY_SET_ATTR_FAIL; } @@ -2360,8 +2360,8 @@ int KX_GameObject::pyattr_set_timeOffset(void *self_v, const KX_PYATTRIBUTE_DEF KX_GameObject* self= static_cast<KX_GameObject*>(self_v); if (self->GetSGNode()) { MT_Scalar val = PyFloat_AsDouble(value); - SG_Node* sg_parent= self->GetSGNode()->GetSGParent(); - if (val < 0.0f) { /* also accounts for non float */ + SG_Node *sg_parent= self->GetSGNode()->GetSGParent(); + if (val < 0.0) { /* also accounts for non float */ PyErr_SetString(PyExc_AttributeError, "gameOb.timeOffset = float: KX_GameObject, expected a float zero or above"); return PY_SET_ATTR_FAIL; } @@ -2644,7 +2644,7 @@ PyObject* KX_GameObject::PyGetReactionForce() return PyObjectFrom(dummy_point); */ - return Py_BuildValue("fff", 0.0f, 0.0f, 0.0f); + return Py_BuildValue("fff", 0.0, 0.0, 0.0); } @@ -2761,18 +2761,18 @@ PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* args) { PyObject* pyvect; int axis = 2; //z axis is the default - float fac = 1.0; + float fac = 1.0f; if (PyArg_ParseTuple(args,"O|if:alignAxisToVect",&pyvect,&axis, &fac)) { MT_Vector3 vect; - if (PyVecTo(pyvect, vect)) - { - if (fac<=0.0) Py_RETURN_NONE; // Nothing to do. - if (fac> 1.0) fac= 1.0; - - AlignAxisToVect(vect,axis,fac); - NodeUpdateGS(0.f); + if (PyVecTo(pyvect, vect)) { + if (fac > 0.0f) { + if (fac> 1.0f) fac = 1.0f; + + AlignAxisToVect(vect, axis, fac); + NodeUpdateGS(0.f); + } Py_RETURN_NONE; } } diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 21c3198b8f9..a560b606f5b 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -503,6 +503,8 @@ bool KX_KetsjiEngine::BeginFrame() void KX_KetsjiEngine::EndFrame() { + m_rendertools->MotionBlur(m_rasterizer); + // Show profiling info m_logger->StartLog(tc_overhead, m_kxsystem->GetTimeInSeconds(), true); if (m_show_framerate || m_show_profile || (m_show_debug_properties && m_propertiesPresent)) @@ -782,21 +784,21 @@ else // Handle the animations independently of the logic time step if (GetRestrictAnimationFPS()) { - m_logger->StartLog(tc_animations, m_kxsystem->GetTimeInSeconds(), true); + double clocktime = m_kxsystem->GetTimeInSeconds(); + m_logger->StartLog(tc_animations, clocktime, true); SG_SetActiveStage(SG_STAGE_ANIMATION_UPDATE); double anim_timestep = 1.0/KX_GetActiveScene()->GetAnimationFPS(); - if (m_clockTime - m_previousAnimTime > anim_timestep) + if (clocktime - m_previousAnimTime > anim_timestep) { // Sanity/debug print to make sure we're actually going at the fps we want (should be close to anim_timestep) // printf("Anim fps: %f\n", 1.0/(m_clockTime - m_previousAnimTime)); - m_previousAnimTime = m_clockTime; + m_previousAnimTime = clocktime; for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit) { - (*sceneit)->UpdateAnimations(m_frameTime); + (*sceneit)->UpdateAnimations(clocktime); } } - m_previousClockTime = m_clockTime; } // Start logging time spend outside main loop @@ -1344,7 +1346,6 @@ void KX_KetsjiEngine::PostRenderScene(KX_Scene* scene) m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight()); m_rasterizer->FlushDebugShapes(); - m_rendertools->MotionBlur(m_rasterizer); scene->Render2DFilters(m_canvas); #ifdef WITH_PYTHON scene->RunDrawingCallbacks(scene->GetPostDrawCB()); diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index 5922e97aaf4..f5aa1bb3c75 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -29,11 +29,12 @@ * \ingroup ketsji */ - #if defined(WIN32) && !defined(FREE_WINDOWS) #pragma warning (disable : 4786) #endif +#include <stdio.h> + #include "GL/glew.h" #include "KX_Light.h" @@ -67,10 +68,13 @@ KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks, KX_LightObject::~KX_LightObject() { GPULamp *lamp; + Lamp *la = (Lamp*)GetBlenderObject()->data; if ((lamp = GetGPULamp())) { float obmat[4][4] = {{0}}; GPU_lamp_update(lamp, 0, 0, obmat); + GPU_lamp_update_distance(lamp, la->dist, la->att1, la->att2); + GPU_lamp_update_spot(lamp, la->spotsize, la->spotblend); } m_rendertools->RemoveLight(&m_lightobj); @@ -145,11 +149,12 @@ bool KX_LightObject::ApplyLight(KX_Scene *kxscene, int oblayer, int slot) //vec[1]= -base->object->obmat[2][1]; //vec[2]= -base->object->obmat[2][2]; glLightfv((GLenum)(GL_LIGHT0+slot), GL_SPOT_DIRECTION, vec); - glLightf((GLenum)(GL_LIGHT0+slot), GL_SPOT_CUTOFF, m_lightobj.m_spotsize/2.0); - glLightf((GLenum)(GL_LIGHT0+slot), GL_SPOT_EXPONENT, 128.0*m_lightobj.m_spotblend); + glLightf((GLenum)(GL_LIGHT0+slot), GL_SPOT_CUTOFF, m_lightobj.m_spotsize / 2.0f); + glLightf((GLenum)(GL_LIGHT0+slot), GL_SPOT_EXPONENT, 128.0f * m_lightobj.m_spotblend); } - else + else { glLightf((GLenum)(GL_LIGHT0+slot), GL_SPOT_CUTOFF, 180.0); + } } if (m_lightobj.m_nodiffuse) { @@ -206,6 +211,8 @@ void KX_LightObject::Update() GPU_lamp_update(lamp, m_lightobj.m_layer, 0, obmat); GPU_lamp_update_colors(lamp, m_lightobj.m_red, m_lightobj.m_green, m_lightobj.m_blue, m_lightobj.m_energy); + GPU_lamp_update_distance(lamp, m_lightobj.m_distance, m_lightobj.m_att1, m_lightobj.m_att2); + GPU_lamp_update_spot(lamp, m_lightobj.m_spotsize, m_lightobj.m_spotblend); } } diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 823363dfd11..536b32cbd77 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -676,12 +676,12 @@ static PyObject *gLibLoad(PyObject*, PyObject* args, PyObject* kwds) char *err_str= NULL; short options=0; - int load_actions=0, verbose=0; + int load_actions=0, verbose=0, load_scripts=1; - static const char *kwlist[] = {"path", "group", "buffer", "load_actions", "verbose", NULL}; + static const char *kwlist[] = {"path", "group", "buffer", "load_actions", "verbose", "load_scripts", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|y*ii:LibLoad", const_cast<char**>(kwlist), - &path, &group, &py_buffer, &load_actions, &verbose)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|y*iii:LibLoad", const_cast<char**>(kwlist), + &path, &group, &py_buffer, &load_actions, &verbose, &load_scripts)) return NULL; /* setup options */ @@ -689,6 +689,8 @@ static PyObject *gLibLoad(PyObject*, PyObject* args, PyObject* kwds) options |= KX_BlenderSceneConverter::LIB_LOAD_LOAD_ACTIONS; if (verbose != 0) options |= KX_BlenderSceneConverter::LIB_LOAD_VERBOSE; + if (load_scripts != 0) + options |= KX_BlenderSceneConverter::LIB_LOAD_LOAD_SCRIPTS; if (!py_buffer.buf) { diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h index f1ed5b3c982..2de58f8b3a0 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.h +++ b/source/gameengine/Ketsji/KX_RadarSensor.h @@ -90,10 +90,11 @@ public: KX_RADAR_AXIS_NEG_Z }; - /* python */ virtual sensortype GetSensorType() { return ST_RADAR; } - + /* python */ +#ifdef WITH_PYTHON static PyObject* pyattr_get_angle(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); +#endif }; #endif //__KX_RADARSENSOR_H__ diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp index 35c791e427d..f408b2cd7c9 100644 --- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp @@ -27,7 +27,7 @@ /** \file gameengine/Ketsji/KX_SCA_DynamicActuator.cpp * \ingroup ketsji - * Adjust dynamics settins for this object + * Adjust dynamics settings for this object */ /* Previously existed as: diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index e09d5f13bfe..5d4b9ae40c2 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -2164,7 +2164,11 @@ PyObject* KX_Scene::pyattr_get_cameras(void *self_v, const KX_PYATTRIBUTE_DEF *a PyObject* KX_Scene::pyattr_get_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_Scene* self= static_cast<KX_Scene*>(self_v); - return self->GetActiveCamera()->GetProxy(); + KX_Camera* cam= self->GetActiveCamera(); + if (cam) + return self->GetActiveCamera()->GetProxy(); + else + Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 7e3378bd13f..f8480753395 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -309,8 +309,8 @@ public: RAS_BucketManager* GetBucketManager(); RAS_MaterialBucket* FindBucket(RAS_IPolyMaterial* polymat, bool &bucketCreated); void RenderBuckets(const MT_Transform& cameratransform, - RAS_IRasterizer* rasty, - RAS_IRenderTools* rendertools); + RAS_IRasterizer* rasty, + RAS_IRenderTools* rendertools); /** * Update all transforms according to the scenegraph. @@ -325,18 +325,18 @@ public: m_groupGameObjects.find(gameobj) != m_groupGameObjects.end()); } SCA_IObject* AddReplicaObject(CValue* gameobj, - CValue* locationobj, - int lifespan=0); + CValue* locationobj, + int lifespan=0); KX_GameObject* AddNodeReplicaObject(SG_IObject* node, - CValue* gameobj); + CValue* gameobj); void RemoveNodeDestructObject(SG_IObject* node, - CValue* gameobj); + CValue* gameobj); void RemoveObject(CValue* gameobj); void DelayedRemoveObject(CValue* gameobj); int NewRemoveObject(CValue* gameobj); void ReplaceMesh(CValue* gameobj, - void* meshob, bool use_gfx, bool use_phys); + void* meshob, bool use_gfx, bool use_phys); void AddAnimatedObject(CValue* gameobj); void RemoveAnimatedObject(CValue* gameobj); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 0a105ee1c1a..ed2b9cfcb0b 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -632,6 +632,8 @@ CcdPhysicsController::~CcdPhysicsController() delete m_MotionState; if (m_bulletMotionState) delete m_bulletMotionState; + if (m_characterController) + delete m_characterController; delete m_object; DeleteControllerShape(); @@ -836,6 +838,11 @@ void CcdPhysicsController::SetPhysicsEnvironment(class PHY_IPhysicsEnvironment * if (m_cci.m_physicsEnv->removeCcdPhysicsController(this)) { physicsEnv->addCcdPhysicsController(this); + + // Set the object to be active so it can at least by evaluated once. + // This fixes issues with static objects not having their physics meshes + // in the right spot when lib loading. + this->GetCollisionObject()->setActivationState(ACTIVE_TAG); } m_cci.m_physicsEnv = physicsEnv; } diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index 3b49607ff1b..5d28bf47401 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -451,6 +451,11 @@ bool CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctr } else { m_dynamicsWorld->removeCollisionObject(ctrl->GetCollisionObject()); + + if (ctrl->GetCharacterController()) + { + m_dynamicsWorld->removeAction(ctrl->GetCharacterController()); + } } } if (ctrl->m_registerCount != 0) @@ -830,16 +835,16 @@ void CcdPhysicsEnvironment::setCcdMode(int ccdMode) void CcdPhysicsEnvironment::setSolverSorConstant(float sor) { - m_solverInfo.m_sor = sor; + m_dynamicsWorld->getSolverInfo().m_sor = sor; } void CcdPhysicsEnvironment::setSolverTau(float tau) { - m_solverInfo.m_tau = tau; + m_dynamicsWorld->getSolverInfo().m_tau = tau; } void CcdPhysicsEnvironment::setSolverDamping(float damping) { - m_solverInfo.m_damping = damping; + m_dynamicsWorld->getSolverInfo().m_damping = damping; } diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h index 8d9c770b8c3..c499a1ef75c 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h @@ -83,8 +83,6 @@ protected: int m_profileTimings; bool m_enableSatCollisionDetection; - btContactSolverInfo m_solverInfo; - void processFhSprings(double curTime,float timeStep); public: diff --git a/source/gameengine/Physics/common/PHY_DynamicTypes.h b/source/gameengine/Physics/common/PHY_DynamicTypes.h index a72929d25c5..69bbc7745e0 100644 --- a/source/gameengine/Physics/common/PHY_DynamicTypes.h +++ b/source/gameengine/Physics/common/PHY_DynamicTypes.h @@ -96,18 +96,18 @@ enum PHY_NUM_RESPONSE }; - typedef struct PHY_CollData { - PHY__Vector3 m_point1; /* Point in object1 in world coordinates */ - PHY__Vector3 m_point2; /* Point in object2 in world coordinates */ - PHY__Vector3 m_normal; /* point2 - point1 */ - } PHY_CollData; - - - typedef bool (*PHY_ResponseCallback)(void *client_data, - void *client_object1, - void *client_object2, - const PHY_CollData *coll_data); - typedef void (*PHY_CullingCallback)(KX_ClientObjectInfo* info, void* param); +typedef struct PHY_CollData { + PHY__Vector3 m_point1; /* Point in object1 in world coordinates */ + PHY__Vector3 m_point2; /* Point in object2 in world coordinates */ + PHY__Vector3 m_normal; /* point2 - point1 */ +} PHY_CollData; + + +typedef bool (*PHY_ResponseCallback)(void *client_data, + void *client_object1, + void *client_object2, + const PHY_CollData *coll_data); +typedef void (*PHY_CullingCallback)(KX_ClientObjectInfo* info, void* param); /// PHY_PhysicsType enumerates all possible Physics Entities. diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp index 097c2a9c824..92c390efd39 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp @@ -52,7 +52,6 @@ RAS_2DFilterManager::RAS_2DFilterManager(): texturewidth(-1), textureheight(-1), -canvaswidth(-1), canvasheight(-1), /* numberoffilters(0), */ /* UNUSED */ need_tex_update(true) { isshadersupported = GLEW_ARB_shader_objects && @@ -404,7 +403,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas) RAS_Rect rect = canvas->GetWindowArea(); int rect_width = rect.GetWidth()+1, rect_height = rect.GetHeight()+1; - if (canvaswidth != canvas->GetWidth() || canvasheight != canvas->GetHeight()) + if (texturewidth != rect_width || textureheight != rect_height) { UpdateOffsetMatrix(canvas); UpdateCanvasTextureCoord((unsigned int*)viewport); diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.h b/source/gameengine/Rasterizer/RAS_2DFilterManager.h index 93d143dd3ce..ba74018d36b 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.h +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.h @@ -62,8 +62,6 @@ private: unsigned int texname[3]; int texturewidth; int textureheight; - int canvaswidth; - int canvasheight; /* int numberoffilters; */ /* UNUSED */ /* bit 0: enable/disable depth texture * bit 1: enable/disable luminance texture*/ diff --git a/source/gameengine/Rasterizer/RAS_FramingManager.h b/source/gameengine/Rasterizer/RAS_FramingManager.h index 6312f83737e..dd640bc6839 100644 --- a/source/gameengine/Rasterizer/RAS_FramingManager.h +++ b/source/gameengine/Rasterizer/RAS_FramingManager.h @@ -289,7 +289,7 @@ private : /** * Private constructor - this class is not meant - * for instanciation. + * for instantiation. */ RAS_FramingManager( diff --git a/source/gameengine/Rasterizer/RAS_IRenderTools.h b/source/gameengine/Rasterizer/RAS_IRenderTools.h index 5d3efb8c38a..c02bc5e7a44 100644 --- a/source/gameengine/Rasterizer/RAS_IRenderTools.h +++ b/source/gameengine/Rasterizer/RAS_IRenderTools.h @@ -113,14 +113,14 @@ public: */ virtual void - RenderText3D(int fontid, - const char* text, - int size, - int dpi, - float* color, - double* mat, - float aspect - ) = 0; + RenderText3D(int fontid, + const char* text, + int size, + int dpi, + float* color, + double* mat, + float aspect + ) = 0; /** diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 76d1a64a4c0..b769fc4b703 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -962,10 +962,10 @@ void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi) void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat) { glMatrixMode(GL_PROJECTION); - double* matrix = &mat(0,0); + double* matrix = &mat(0, 0); glLoadMatrixd(matrix); - m_camortho= (mat(3, 3) != 0.0f); + m_camortho = (mat(3, 3) != 0.0); } void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat) @@ -977,7 +977,7 @@ void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat) /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */ glLoadMatrixd(matrix); - m_camortho= (mat[3][3] != 0.0f); + m_camortho= (mat[3][3] != 0.0); } MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix( @@ -1002,11 +1002,11 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix( // if Rasterizer.setFocalLength is not called we use the camera focallength if (!m_setfocallength) // if focallength is null we use a value known to be reasonable - m_focallength = (focallength == 0.f) ? m_eyeseparation * 30.0 + m_focallength = (focallength == 0.f) ? m_eyeseparation * 30.0f : focallength; near_div_focallength = frustnear / m_focallength; - offset = 0.5 * m_eyeseparation * near_div_focallength; + offset = 0.5f * m_eyeseparation * near_div_focallength; switch(m_curreye) { case RAS_STEREO_LEFTEYE: diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index 9fdd0cd393b..c8763671dd1 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -138,7 +138,7 @@ void ImageRender::Render() // compute distance of observer to mirror = D - observerPos . normal MT_Scalar observerDistance = mirrorPlaneDTerm - observerWorldPos.dot(mirrorWorldZ); // if distance < 0.01 => observer is on wrong side of mirror, don't render - if (observerDistance < 0.01f) + if (observerDistance < 0.01) return; // set camera world position = observerPos + normal * 2 * distance MT_Point3 cameraWorldPos = observerWorldPos + (MT_Scalar(2.0)*observerDistance)*mirrorWorldZ; diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript index 1e3f232a919..e66284948ed 100644 --- a/source/gameengine/VideoTexture/SConscript +++ b/source/gameengine/VideoTexture/SConscript @@ -15,7 +15,7 @@ incs += ' #source/blender/gpu #intern/string #intern/moto/include' incs += ' #intern/guardedalloc #intern/container #extern/glew/include' incs += ' #intern/ffmpeg' -defs = [] +defs = ['GLEW_STATIC'] if env['OURPLATFORM'] in ('win32-vc', 'win64-vc','win32-mingw', 'win64-mingw'): if env['BF_DEBUG']: defs.append('_DEBUG') |