From 7ef78723b7d43cee5897da2c43f5038e56ccd3d6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 Nov 2012 00:59:11 +0000 Subject: code cleanup: doxy comment corrections and correct own typo animation player docs. --- intern/ghost/GHOST_C-api.h | 14 ++++++---- intern/utfconv/utfconv.h | 20 +++++++------- source/blender/blenlib/intern/string_utf8.c | 32 +++++++++++----------- source/blender/bmesh/intern/bmesh_core.c | 2 +- source/blender/bmesh/intern/bmesh_operators.h | 8 ------ .../blender/bmesh/tools/bmesh_decimate_collapse.c | 2 +- .../blender/bmesh/tools/bmesh_decimate_dissolve.c | 3 -- source/blender/compositor/intern/COM_WorkPackage.h | 2 +- source/blender/editors/space_node/node_edit.c | 2 +- .../editors/space_view3d/view3d_iterators.c | 2 +- source/creator/creator.c | 2 +- 11 files changed, 40 insertions(+), 49 deletions(-) diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index 87ab3c013c6..f886dfd9d7d 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -120,7 +120,7 @@ extern GHOST_TimerTaskHandle GHOST_InstallTimer(GHOST_SystemHandle systemhandle, /** * Removes a timer. * \param systemhandle The handle to the system - * \param timerTask Timer task to be removed. + * \param timertaskhandle Timer task to be removed. * \return Indication of success. */ extern GHOST_TSuccess GHOST_RemoveTimer(GHOST_SystemHandle systemhandle, @@ -185,7 +185,7 @@ extern GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandl /** * Changes the window user data. * \param windowhandle The handle to the window - * \param data The window user data. + * \param userdata The window user data. */ extern void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle, GHOST_TUserDataPtr userdata); @@ -212,6 +212,7 @@ extern int GHOST_ValidWindow(GHOST_SystemHandle systemhandle, * Begins full screen mode. * \param systemhandle The handle to the system * \param setting The new setting of the display. + * \param stereoVisual Option for stereo display. * \return A handle to the window displayed in full screen. * This window is invalid after full screen has been ended. */ @@ -302,7 +303,7 @@ extern GHOST_TStandardCursor GHOST_GetCursorShape(GHOST_WindowHandle windowhandl /** * Set the shape of the cursor. * \param windowhandle The handle to the window - * \param cursor The new cursor shape type id. + * \param cursorshape The new cursor shape type id. * \return Indication of success. */ extern GHOST_TSuccess GHOST_SetCursorShape(GHOST_WindowHandle windowhandle, @@ -484,10 +485,10 @@ extern GHOST_TUserDataPtr GHOST_GetTimerTaskUserData(GHOST_TimerTaskHandle timer /** * Changes the time user data. * \param timertaskhandle The handle to the timertask - * \param data The timer user data. + * \param userdata The timer user data. */ extern void GHOST_SetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle, - GHOST_TUserDataPtr userData); + GHOST_TUserDataPtr userdata); /** * Returns indication as to whether the window is valid. @@ -825,7 +826,8 @@ extern GHOST_TUns8 *GHOST_getClipboard(int selection); /** * Put data to the Clipboard - * \param set the selection instead, X11 only feature + * \param buffer the string buffer to set. + * \param selection Set the selection instead, X11 only feature. */ extern void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection); diff --git a/intern/utfconv/utfconv.h b/intern/utfconv/utfconv.h index cf0e69170a2..ada85e274e3 100644 --- a/intern/utfconv/utfconv.h +++ b/intern/utfconv/utfconv.h @@ -57,18 +57,18 @@ size_t count_utf_16_from_8(const char *string8); /** * Converts utf-16 string to allocated utf-8 string - * @params in16 utf-16 string to convert - * @params out8 utf-8 string to string the conversion - * @params size8 the allocated size in bytes of out8 + * @param in16 utf-16 string to convert + * @param out8 utf-8 string to string the conversion + * @param size8 the allocated size in bytes of out8 * @return Returns any errors occured during conversion. See the block above, */ int conv_utf_16_to_8(const wchar_t *in16, char *out8, size_t size8); /** * Converts utf-8 string to allocated utf-16 string - * @params in8 utf-8 string to convert - * @params out16 utf-16 string to string the conversion - * @params size16 the allocated size in wchar_t (two byte) of out16 + * @param in8 utf-8 string to convert + * @param out16 utf-16 string to string the conversion + * @param size16 the allocated size in wchar_t (two byte) of out16 * @return Returns any errors occured during conversion. See the block above, */ int conv_utf_8_to_16(const char *in8, wchar_t *out16, size_t size16); @@ -76,16 +76,16 @@ int conv_utf_8_to_16(const char *in8, wchar_t *out16, size_t size16); /** * Allocates and converts the utf-8 string from utf-16 - * @params in16 utf-16 string to convert - * @params add any additional size which will be allocated for new utf-8 string in bytes + * @param in16 utf-16 string to convert + * @param add any additional size which will be allocated for new utf-8 string in bytes * @return New allocated and converted utf-8 string or NULL if in16 is 0. */ char *alloc_utf_8_from_16(const wchar_t *in16, size_t add); /** * Allocates and converts the utf-16 string from utf-8 - * @params in8 utf-8 string to convert - * @params add any additional size which will be allocated for new utf-16 string in wchar_t (two bytes) + * @param in8 utf-8 string to convert + * @param add any additional size which will be allocated for new utf-16 string in wchar_t (two bytes) * @return New allocated and converted utf-16 string or NULL if in8 is 0. */ wchar_t *alloc_utf16_from_8(const char *in8, size_t add); diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c index 16a5f03095d..bf98f2ae77c 100644 --- a/source/blender/blenlib/intern/string_utf8.c +++ b/source/blender/blenlib/intern/string_utf8.c @@ -394,10 +394,10 @@ int BLI_str_utf8_size_safe(const char *p) /* was g_utf8_get_char */ /** * BLI_str_utf8_as_unicode: - * @p a pointer to Unicode character encoded as UTF-8 + * \param p a pointer to Unicode character encoded as UTF-8 * * Converts a sequence of bytes encoded as UTF-8 to a Unicode character. - * If @p does not point to a valid UTF-8 encoded character, results are + * If \a p does not point to a valid UTF-8 encoded character, results are * undefined. If you are not sure that the bytes are complete * valid Unicode characters, you should use g_utf8_get_char_validated() * instead. @@ -536,14 +536,14 @@ size_t BLI_str_utf8_from_unicode(unsigned int c, char *outbuf) /* was g_utf8_find_prev_char */ /** * BLI_str_find_prev_char_utf8: - * @str: pointer to the beginning of a UTF-8 encoded string - * @p pointer to some position within @str + * \param str pointer to the beginning of a UTF-8 encoded string + * \param p pointer to some position within \a str * - * Given a position @p with a UTF-8 encoded string @str, find the start - * of the previous UTF-8 character starting before. @p Returns %NULL if no - * UTF-8 characters are present in @str before @p + * Given a position \a p with a UTF-8 encoded string \a str, find the start + * of the previous UTF-8 character starting before. \a p Returns %NULL if no + * UTF-8 characters are present in \a str before \a p * - * @p does not have to be at the beginning of a UTF-8 character. No check + * \a p does not have to be at the beginning of a UTF-8 character. No check * is made to see if the character found is actually valid other than * it starts with an appropriate byte. * @@ -562,13 +562,13 @@ char * BLI_str_find_prev_char_utf8(const char *str, const char *p) /* was g_utf8_find_next_char */ /** * BLI_str_find_next_char_utf8: - * @p a pointer to a position within a UTF-8 encoded string - * @end a pointer to the byte following the end of the string, + * \param p a pointer to a position within a UTF-8 encoded string + * \param end a pointer to the byte following the end of the string, * or %NULL to indicate that the string is nul-terminated. * - * Finds the start of the next UTF-8 character in the string after @p + * Finds the start of the next UTF-8 character in the string after \a p * - * @p does not have to be at the beginning of a UTF-8 character. No check + * \a p does not have to be at the beginning of a UTF-8 character. No check * is made to see if the character found is actually valid other than * it starts with an appropriate byte. * @@ -594,13 +594,13 @@ char *BLI_str_find_next_char_utf8(const char *p, const char *end) /* was g_utf8_prev_char */ /** * BLI_str_prev_char_utf8: - * @p a pointer to a position within a UTF-8 encoded string + * \param p a pointer to a position within a UTF-8 encoded string * - * Finds the previous UTF-8 character in the string before @p + * Finds the previous UTF-8 character in the string before \a p * - * @p does not have to be at the beginning of a UTF-8 character. No check + * \a p does not have to be at the beginning of a UTF-8 character. No check * is made to see if the character found is actually valid other than - * it starts with an appropriate byte. If @p might be the first + * it starts with an appropriate byte. If \a p might be the first * character of the string, you must use g_utf8_find_prev_char() instead. * * Return value: a pointer to the found character. diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 03094873e25..541ac28bf1a 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -1334,10 +1334,10 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, * will be attached to that end and is returned in \a r_e. * * \par Examples: + * *
  *                     E
  *     Before: OV-------------TV
- *
  *                 E       RE
  *     After:  OV------NV-----TV
  * 
diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h index b74d97c9bb5..8c478a3517f 100644 --- a/source/blender/bmesh/intern/bmesh_operators.h +++ b/source/blender/bmesh/intern/bmesh_operators.h @@ -83,11 +83,6 @@ enum { SIMVERT_EDGE }; -enum { - OPUVC_AXIS_X = 1, - OPUVC_AXIS_Y -}; - /* vertex path selection values */ enum { VPATH_SELECT_EDGE_LENGTH = 0, @@ -98,9 +93,6 @@ extern BMOpDefine *opdefines[]; extern int bmesh_total_ops; /*------specific operator helper functions-------*/ - -struct Object; - void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag, float smooth, float fractal, float along_normal, int numcuts, diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c index 781001508f2..eeb1774b83b 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c +++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c @@ -960,7 +960,7 @@ static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e, * \brief BM_mesh_decimate * \param bm The mesh * \param factor face count multiplier [0 - 1] - * \param vertex_weights Optional array of vertex aligned weights [0 - 1], + * \param vweights Optional array of vertex aligned weights [0 - 1], * a vertex group is the usual source for this. */ void BM_mesh_decimate_collapse(BMesh *bm, const float factor, float *vweights, const int do_triangulate) diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c index d2a5c580ae6..f67f01e4585 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c +++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c @@ -69,9 +69,6 @@ static int dissolve_elem_cmp(const void *a1, const void *a2) return 0; } -/** - * \param do_all_verts Collapse all verts between 2 faces - don't check their edge angle. - */ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const int do_dissolve_boundaries, BMVert **vinput_arr, const int vinput_len, BMEdge **einput_arr, const int einput_len) diff --git a/source/blender/compositor/intern/COM_WorkPackage.h b/source/blender/compositor/intern/COM_WorkPackage.h index 953a164e95e..2bb124a1c84 100644 --- a/source/blender/compositor/intern/COM_WorkPackage.h +++ b/source/blender/compositor/intern/COM_WorkPackage.h @@ -44,7 +44,7 @@ private: unsigned int m_chunkNumber; public: /** - * @constructor + * constructor * @param group the ExecutionGroup * @param chunkNumber the number of the chunk */ diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 62e941d3148..fd6d9ba8023 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -177,7 +177,7 @@ static void compo_startjob(void *cjv, short *stop, short *do_update, float *prog } /** - * \param sa_owner is the owner of the job, + * \param scene_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. * diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c index b928e060ca0..37607729d0d 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.c +++ b/source/blender/editors/space_view3d/view3d_iterators.c @@ -20,7 +20,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/editors/object/view3d_iterators.c +/** \file blender/editors/space_view3d/view3d_iterators.c * \ingroup spview3d */ diff --git a/source/creator/creator.c b/source/creator/creator.c index ff67fe09896..0f1207a9a88 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -1079,7 +1079,7 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle) "\n\t\t-f \t\tSpecify FPS to start with" "\n\t\t-j \tSet frame step to " "\n\t\t-s \tPlay from " - "\n\t\t-j \tPlay until "; + "\n\t\t-e \tPlay until "; static char game_doc[] = "Game Engine specific options" "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames" -- cgit v1.2.3 From 3fe8134d6dbd954c6afaec8064abc30be61886c7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 Nov 2012 02:24:03 +0000 Subject: add subtypes to bmesh operators (needed for python api to know how to convert return values). --- source/blender/bmesh/intern/bmesh_opdefines.c | 872 ++++++++++++----------- source/blender/bmesh/intern/bmesh_operator_api.h | 38 +- source/blender/bmesh/intern/bmesh_operators.c | 28 +- source/blender/bmesh/intern/bmesh_operators.h | 4 +- source/blender/python/bmesh/bmesh_py_ops.c | 28 +- 5 files changed, 504 insertions(+), 466 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index ec07eb5d9f7..8076fc00a44 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -100,39 +100,39 @@ static BMOpDefine bmo_smooth_vert_def = { "smooth_vert", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */ - {BMO_OP_SLOT_BOOL, "mirror_clip_x"}, /* set vertices close to the x axis before the operation to 0 */ - {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, "clip_dist"}, /* 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}, - }, - {{0}}, /* no output */ + {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {"mirror_clip_x", BMO_OP_SLOT_BOOL}, /* set vertices close to the x axis before the operation to 0 */ + {"mirror_clip_y", BMO_OP_SLOT_BOOL}, /* set vertices close to the y axis before the operation to 0 */ + {"mirror_clip_z", BMO_OP_SLOT_BOOL}, /* set vertices close to the z axis before the operation to 0 */ + {"clip_dist", BMO_OP_SLOT_FLT}, /* clipping threshod for the above three slots */ + {"use_axis_x", BMO_OP_SLOT_BOOL}, /* smooth vertices along X axis */ + {"use_axis_y", BMO_OP_SLOT_BOOL}, /* smooth vertices along Y axis */ + {"use_axis_z", BMO_OP_SLOT_BOOL}, /* smooth vertices along Z axis */ + {{'\0'}}, + }, + {{{'\0'}}}, /* no output */ bmo_smooth_vert_exec, 0 }; /* - * Vertext Smooth Laplacian + * Vertext Smooth Laplacian * Smooths vertices by using Laplacian smoothing propose by. * Desbrun, et al. Implicit Fairing of Irregular Meshes using Diffusion and Curvature Flow */ static BMOpDefine bmo_smooth_laplacian_vert_def = { "smooth_laplacian_vert", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */ - {BMO_OP_SLOT_FLT, "lambda"}, /* lambda param */ - {BMO_OP_SLOT_FLT, "lambda_border"}, /* lambda param in border */ - {BMO_OP_SLOT_BOOL, "use_x"}, /* Smooth object along X axis */ - {BMO_OP_SLOT_BOOL, "use_y"}, /* Smooth object along Y axis */ - {BMO_OP_SLOT_BOOL, "use_z"}, /* Smooth object along Z axis */ - {BMO_OP_SLOT_BOOL, "preserve_volume"}, /* Apply volume preservation after smooth */ - {0}, + {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {"lambda", BMO_OP_SLOT_FLT}, /* lambda param */ + {"lambda_border", BMO_OP_SLOT_FLT}, /* lambda param in border */ + {"use_x", BMO_OP_SLOT_BOOL}, /* Smooth object along X axis */ + {"use_y", BMO_OP_SLOT_BOOL}, /* Smooth object along Y axis */ + {"use_z", BMO_OP_SLOT_BOOL}, /* Smooth object along Z axis */ + {"preserve_volume", BMO_OP_SLOT_BOOL}, /* Apply volume preservation after smooth */ + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_smooth_laplacian_vert_exec, 0 }; @@ -146,11 +146,11 @@ static BMOpDefine bmo_smooth_laplacian_vert_def = { static BMOpDefine bmo_recalc_face_normals_def = { "recalc_face_normals", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, - {BMO_OP_SLOT_BOOL, "use_flip"}, /* internal flag, used by bmesh_rationalize_normals */ - {0}, + {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, + {"use_flip", BMO_OP_SLOT_BOOL}, /* internal flag, used by bmesh_rationalize_normals */ + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_recalc_face_normals_exec, BMO_OP_FLAG_UNTAN_MULTIRES, }; @@ -168,14 +168,14 @@ static BMOpDefine bmo_recalc_face_normals_def = { static BMOpDefine bmo_region_extend_def = { "region_extend", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input geometry */ - {BMO_OP_SLOT_BOOL, "use_constrict"}, /* find boundary inside the regions, not outside. */ - {BMO_OP_SLOT_BOOL, "use_faces"}, /* extend from faces instead of edges */ - {0}, + {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, /* input geometry */ + {"use_constrict", BMO_OP_SLOT_BOOL}, /* find boundary inside the regions, not outside. */ + {"use_faces", BMO_OP_SLOT_BOOL}, /* extend from faces instead of edges */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* output slot, computed boundary geometry. */ - {0}, + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output slot, computed boundary geometry. */ + {{'\0'}}, }, bmo_region_extend_exec, 0 @@ -190,13 +190,13 @@ static BMOpDefine bmo_region_extend_def = { static BMOpDefine bmo_rotate_edges_def = { "rotate_edges", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */ - {BMO_OP_SLOT_BOOL, "use_ccw"}, /* rotate edge counter-clockwise if true, othewise clockwise */ - {0}, + {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edges */ + {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate edge counter-clockwise if true, othewise clockwise */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* newly spun edges */ - {0}, + {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, /* newly spun edges */ + {{'\0'}}, }, bmo_rotate_edges_exec, BMO_OP_FLAG_UNTAN_MULTIRES @@ -211,10 +211,10 @@ static BMOpDefine bmo_rotate_edges_def = { static BMOpDefine bmo_reverse_faces_def = { "reverse_faces", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */ - {0}, + {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_reverse_faces_exec, BMO_OP_FLAG_UNTAN_MULTIRES, }; @@ -228,13 +228,13 @@ static BMOpDefine bmo_reverse_faces_def = { static BMOpDefine bmo_bisect_edges_def = { "bisect_edges", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */ - {BMO_OP_SLOT_INT, "cuts"}, /* number of cuts */ - {0}, + {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edges */ + {"cuts", BMO_OP_SLOT_INT}, /* number of cuts */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom_split.out"}, /* newly created vertices and edges */ - {0}, + {{"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF}, /* newly created vertices and edges */ + {{'\0'}}, }, bmo_bisect_edges_exec, BMO_OP_FLAG_UNTAN_MULTIRES @@ -251,17 +251,17 @@ static BMOpDefine bmo_bisect_edges_def = { static BMOpDefine bmo_mirror_def = { "mirror", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input geometry */ - {BMO_OP_SLOT_MAT, "mat"}, /* matrix defining the mirror transformation */ - {BMO_OP_SLOT_FLT, "merge_dist"}, /* maximum distance for merging. does no merging if 0. */ - {BMO_OP_SLOT_INT, "axis"}, /* the axis to use, 0, 1, or 2 for x, y, z */ - {BMO_OP_SLOT_BOOL, "mirror_u"}, /* mirror UVs across the u axis */ - {BMO_OP_SLOT_BOOL, "mirror_v"}, /* mirror UVs across the v axis */ - {0}, + {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, /* input geometry */ + {"mat", BMO_OP_SLOT_MAT}, /* matrix defining the mirror transformation */ + {"merge_dist", BMO_OP_SLOT_FLT}, /* maximum distance for merging. does no merging if 0. */ + {"axis", BMO_OP_SLOT_INT}, /* the axis to use, 0, 1, or 2 for x, y, z */ + {"mirror_u", BMO_OP_SLOT_BOOL}, /* mirror UVs across the u axis */ + {"mirror_v", BMO_OP_SLOT_BOOL}, /* mirror UVs across the v axis */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* output geometry, mirrored */ - {0}, + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output geometry, mirrored */ + {{'\0'}}, }, bmo_mirror_exec, 0, @@ -279,14 +279,14 @@ static BMOpDefine bmo_mirror_def = { static BMOpDefine bmo_find_doubles_def = { "find_doubles", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */ - {BMO_OP_SLOT_ELEMENT_BUF, "keep_verts"}, /* list of verts to keep */ - {BMO_OP_SLOT_FLT, "dist"}, /* minimum distance */ - {0}, + {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {"keep_verts", BMO_OP_SLOT_ELEMENT_BUF}, /* list of verts to keep */ + {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_MAPPING, "targetmap.out"}, - {0}, + {{"targetmap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM}, + {{'\0'}}, }, bmo_find_doubles_exec, 0, @@ -301,11 +301,11 @@ static BMOpDefine bmo_find_doubles_def = { static BMOpDefine bmo_remove_doubles_def = { "remove_doubles", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input verts */ - {BMO_OP_SLOT_FLT, "dist"}, /* minimum distance */ - {0}, + {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input verts */ + {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */ + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_remove_doubles_exec, BMO_OP_FLAG_UNTAN_MULTIRES, }; @@ -320,11 +320,11 @@ static BMOpDefine bmo_remove_doubles_def = { static BMOpDefine bmo_automerge_def = { "automerge", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input verts */ - {BMO_OP_SLOT_FLT, "dist"}, /* minimum distance */ - {0}, + {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input verts */ + {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */ + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_automerge_exec, BMO_OP_FLAG_UNTAN_MULTIRES, }; @@ -337,10 +337,10 @@ static BMOpDefine bmo_automerge_def = { static BMOpDefine bmo_collapse_def = { "collapse", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */ - {0}, + {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edge */ + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_collapse_exec, BMO_OP_FLAG_UNTAN_MULTIRES, }; @@ -354,11 +354,11 @@ static BMOpDefine bmo_collapse_def = { static BMOpDefine bmo_pointmerge_facedata_def = { "pointmerge_facedata", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */ - {BMO_OP_SLOT_ELEMENT_BUF, "snapv"}, /* snap vertex */ - {0}, + {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {"snapv", BMO_OP_SLOT_ELEMENT_BUF}, /* snap vertex */ + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_pointmerge_facedata_exec, 0, }; @@ -373,10 +373,10 @@ static BMOpDefine bmo_pointmerge_facedata_def = { static BMOpDefine bmo_average_vert_facedata_def = { "average_vert_facedata", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertice */ - {0}, + {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertice */ + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_average_vert_facedata_exec, 0, }; @@ -389,11 +389,11 @@ static BMOpDefine bmo_average_vert_facedata_def = { static BMOpDefine bmo_pointmerge_def = { "pointmerge", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertice */ - {BMO_OP_SLOT_VEC, "merge_co"}, - {0}, + {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertice */ + {"merge_co", BMO_OP_SLOT_VEC}, + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_pointmerge_exec, BMO_OP_FLAG_UNTAN_MULTIRES, }; @@ -406,10 +406,10 @@ static BMOpDefine bmo_pointmerge_def = { static BMOpDefine bmo_collapse_uvs_def = { "collapse_uvs", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */ - {0}, + {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edge */ + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_collapse_uvs_exec, 0, }; @@ -424,10 +424,11 @@ static BMOpDefine bmo_collapse_uvs_def = { static BMOpDefine bmo_weld_verts_def = { "weld_verts", /* slots_in */ - {{BMO_OP_SLOT_MAPPING, "targetmap"}, /* maps welded vertices to verts they should weld to */ - {0}, + /* maps welded vertices to verts they should weld to */ + {{"targetmap", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM}, + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_weld_verts_exec, BMO_OP_FLAG_UNTAN_MULTIRES, }; @@ -441,12 +442,12 @@ static BMOpDefine bmo_weld_verts_def = { static BMOpDefine bmo_create_vert_def = { "create_vert", /* slots_in */ - {{BMO_OP_SLOT_VEC, "co"}, /* the coordinate of the new vert */ - {0}, + {{"co", BMO_OP_SLOT_VEC}, /* the coordinate of the new vert */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "vert.out"}, /* the new vert */ - {0}, + {{"vert.out", BMO_OP_SLOT_ELEMENT_BUF}, /* the new vert */ + {{'\0'}}, }, bmo_create_vert_exec, 0, @@ -461,17 +462,17 @@ static BMOpDefine bmo_create_vert_def = { static BMOpDefine bmo_join_triangles_def = { "join_triangles", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input geometry. */ - {BMO_OP_SLOT_BOOL, "cmp_sharp"}, - {BMO_OP_SLOT_BOOL, "cmp_uvs"}, - {BMO_OP_SLOT_BOOL, "cmp_vcols"}, - {BMO_OP_SLOT_BOOL, "cmp_materials"}, - {BMO_OP_SLOT_FLT, "limit"}, - {0}, + {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input geometry. */ + {"cmp_sharp", BMO_OP_SLOT_BOOL}, + {"cmp_uvs", BMO_OP_SLOT_BOOL}, + {"cmp_vcols", BMO_OP_SLOT_BOOL}, + {"cmp_materials", BMO_OP_SLOT_BOOL}, + {"limit", BMO_OP_SLOT_FLT}, + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* joined faces */ - {0}, + {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* joined faces */ + {{'\0'}}, }, bmo_join_triangles_exec, BMO_OP_FLAG_UNTAN_MULTIRES, @@ -491,16 +492,16 @@ static BMOpDefine bmo_join_triangles_def = { static BMOpDefine bmo_contextual_create_def = { "contextual_create", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input geometry. */ - {BMO_OP_SLOT_INT, "mat_nr"}, /* material to use */ - {BMO_OP_SLOT_BOOL, "use_smooth"}, /* smooth to use */ - {0}, + {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, /* input geometry. */ + {"mat_nr", BMO_OP_SLOT_INT}, /* material to use */ + {"use_smooth", BMO_OP_SLOT_BOOL}, /* smooth to use */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* newly-made face(s) */ + {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* newly-made face(s) */ /* note, this is for stand-alone edges only, not edges which are apart of newly created faces */ - {BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* newly-made edge(s) */ - {0}, + {"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, /* newly-made edge(s) */ + {{'\0'}}, }, bmo_contextual_create_exec, BMO_OP_FLAG_UNTAN_MULTIRES, @@ -512,14 +513,14 @@ static BMOpDefine bmo_contextual_create_def = { static BMOpDefine bmo_bridge_loops_def = { "bridge_loops", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */ - {BMO_OP_SLOT_BOOL, "use_merge"}, - {BMO_OP_SLOT_FLT, "merge_factor"}, - {0}, + {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edge */ + {"use_merge", BMO_OP_SLOT_BOOL}, + {"merge_factor", BMO_OP_SLOT_FLT}, + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* new faces */ - {0}, + {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* new faces */ + {{'\0'}}, }, bmo_bridge_loops_exec, 0, @@ -528,19 +529,21 @@ static BMOpDefine bmo_bridge_loops_def = { static BMOpDefine bmo_edgenet_fill_def = { "edgenet_fill", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */ - {BMO_OP_SLOT_MAPPING, "restrict"}, /* restricts edges to groups. maps edges to integer */ - {BMO_OP_SLOT_BOOL, "use_restrict"}, - {BMO_OP_SLOT_BOOL, "use_fill_check"}, - {BMO_OP_SLOT_ELEMENT_BUF, "exclude_faces"}, /* list of faces to ignore for manifold check */ - {BMO_OP_SLOT_INT, "mat_nr"}, /* material to use */ - {BMO_OP_SLOT_BOOL, "use_smooth"}, /* material to use */ - {0}, + {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edge */ + /* restricts edges to groups. maps edges to integer */ + {"restrict", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_BOOL}, + {"use_restrict", BMO_OP_SLOT_BOOL}, + {"use_fill_check", BMO_OP_SLOT_BOOL}, + {"exclude_faces", BMO_OP_SLOT_ELEMENT_BUF}, /* list of faces to ignore for manifold check */ + {"mat_nr", BMO_OP_SLOT_INT}, /* material to use */ + {"use_smooth", BMO_OP_SLOT_BOOL}, /* material to use */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_MAPPING, "face_groupmap.out"}, /* maps new faces to the group numbers they came from */ - {BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* new face */ - {0}, + /* maps new faces to the group numbers they came from */ + {{"face_groupmap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM}, + {"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* new face */ + {{'\0'}}, }, bmo_edgenet_fill_exec, 0, @@ -559,12 +562,12 @@ static BMOpDefine bmo_edgenet_fill_def = { static BMOpDefine bmo_edgenet_prepare_def = { "edgenet_prepare", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */ - {0}, + {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edges */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* new edges */ - {0}, + {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, /* new edges */ + {{'\0'}}, }, bmo_edgenet_prepare, 0, @@ -579,12 +582,12 @@ static BMOpDefine bmo_edgenet_prepare_def = { static BMOpDefine bmo_rotate_def = { "rotate", /* slots_in */ - {{BMO_OP_SLOT_VEC, "cent"}, /* center of rotation */ - {BMO_OP_SLOT_MAT, "mat"}, /* matrix defining rotation */ - {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */ - {0}, + {{"cent", BMO_OP_SLOT_VEC}, /* center of rotation */ + {"mat", BMO_OP_SLOT_MAT}, /* matrix defining rotation */ + {"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_rotate_exec, 0, }; @@ -598,11 +601,11 @@ static BMOpDefine bmo_rotate_def = { static BMOpDefine bmo_translate_def = { "translate", /* slots_in */ - {{BMO_OP_SLOT_VEC, "vec"}, /* translation offset */ - {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */ - {0}, + {{"vec", BMO_OP_SLOT_VEC}, /* translation offset */ + {"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_translate_exec, 0, }; @@ -615,11 +618,11 @@ static BMOpDefine bmo_translate_def = { static BMOpDefine bmo_scale_def = { "scale", /* slots_in */ - {{BMO_OP_SLOT_VEC, "vec"}, /* scale factor */ - {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */ - {0}, + {{"vec", BMO_OP_SLOT_VEC}, /* scale factor */ + {"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_scale_exec, 0, }; @@ -634,11 +637,11 @@ static BMOpDefine bmo_scale_def = { static BMOpDefine bmo_transform_def = { "transform", /* slots_in */ - {{BMO_OP_SLOT_MAT, "mat"}, /* transform matrix */ - {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */ - {0}, + {{"mat", BMO_OP_SLOT_MAT}, /* transform matrix */ + {"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_transform_exec, 0, }; @@ -652,11 +655,11 @@ static BMOpDefine bmo_transform_def = { static BMOpDefine bmo_object_load_bmesh_def = { "object_load_bmesh", /* slots_in */ - {{BMO_OP_SLOT_PTR, "scene"}, - {BMO_OP_SLOT_PTR, "object"}, - {0}, + {{"scene", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_SCENE}, + {"object", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}, + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_object_load_bmesh_exec, 0, }; @@ -670,12 +673,15 @@ static BMOpDefine bmo_object_load_bmesh_def = { static BMOpDefine bmo_bmesh_to_mesh_def = { "bmesh_to_mesh", /* slots_in */ - {{BMO_OP_SLOT_PTR, "mesh"}, /* pointer to a mesh structure to fill in */ - {BMO_OP_SLOT_PTR, "object"}, /* pointer to an object structure */ - {BMO_OP_SLOT_BOOL, "skip_tessface"}, /* don't calculate mfaces */ - {0}, + { + /* pointer to a mesh structure to fill in */ + {"mesh", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_MESH}, + /* pointer to an object structure */ + {"object", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}, + {"skip_tessface", BMO_OP_SLOT_BOOL}, /* don't calculate mfaces */ + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_bmesh_to_mesh_exec, 0, }; @@ -689,12 +695,15 @@ static BMOpDefine bmo_bmesh_to_mesh_def = { static BMOpDefine bmo_mesh_to_bmesh_def = { "mesh_to_bmesh", /* slots_in */ - {{BMO_OP_SLOT_PTR, "mesh"}, /* pointer to a Mesh structure */ - {BMO_OP_SLOT_PTR, "object"}, /* pointer to an Object structure */ - {BMO_OP_SLOT_BOOL, "use_shapekey"}, /* load active shapekey coordinates into verts */ - {0}, + { + /* pointer to a Mesh structure */ + {"mesh", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_MESH}, + /* pointer to an Object structure */ + {"object", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}, + {"use_shapekey", BMO_OP_SLOT_BOOL}, /* load active shapekey coordinates into verts */ + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_mesh_to_bmesh_exec, 0 }; @@ -707,13 +716,13 @@ static BMOpDefine bmo_mesh_to_bmesh_def = { static BMOpDefine bmo_extrude_discrete_faces_def = { "extrude_discrete_faces", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */ - {0}, + {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* output faces */ - {BMO_OP_SLOT_ELEMENT_BUF, "geom_skirt.out"}, /* output skirt geometry, faces and edges */ - {0}, + {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output faces */ + {"geom_skirt.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output skirt geometry, faces and edges */ + {{'\0'}}, }, bmo_extrude_discrete_faces_exec, 0 @@ -728,12 +737,12 @@ static BMOpDefine bmo_extrude_discrete_faces_def = { static BMOpDefine bmo_extrude_edge_only_def = { "extrude_edge_only", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input vertices */ - {0}, + {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* output geometry */ - {0}, + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output geometry */ + {{'\0'}}, }, bmo_extrude_edge_only_exec, 0 @@ -747,13 +756,13 @@ static BMOpDefine bmo_extrude_edge_only_def = { static BMOpDefine bmo_extrude_vert_indiv_def = { "extrude_vert_indiv", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */ - {0}, + {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* output wire edges */ - {BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output vertices */ - {0}, + {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output wire edges */ + {"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output vertices */ + {{'\0'}}, }, bmo_extrude_vert_indiv_exec, 0 @@ -762,12 +771,12 @@ static BMOpDefine bmo_extrude_vert_indiv_def = { static BMOpDefine bmo_connect_verts_def = { "connect_verts", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, - {0}, + {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, - {0}, + {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{'\0'}}, }, bmo_connect_verts_exec, BMO_OP_FLAG_UNTAN_MULTIRES @@ -776,14 +785,14 @@ static BMOpDefine bmo_connect_verts_def = { static BMOpDefine bmo_extrude_face_region_def = { "extrude_face_region", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* edges and faces */ - {BMO_OP_SLOT_MAPPING, "edges_exclude"}, - {BMO_OP_SLOT_BOOL, "use_keep_orig"}, /* keep original geometry */ - {0}, + {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, /* edges and faces */ + {"edges_exclude", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_EMPTY}, + {"use_keep_orig", BMO_OP_SLOT_BOOL}, /* keep original geometry */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, - {0}, + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{'\0'}}, }, bmo_extrude_face_region_exec, 0 @@ -792,10 +801,10 @@ static BMOpDefine bmo_extrude_face_region_def = { static BMOpDefine bmo_dissolve_verts_def = { "dissolve_verts", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, - {0}, + {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_dissolve_verts_exec, BMO_OP_FLAG_UNTAN_MULTIRES }; @@ -803,13 +812,13 @@ static BMOpDefine bmo_dissolve_verts_def = { static BMOpDefine bmo_dissolve_edges_def = { "dissolve_edges", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, - {BMO_OP_SLOT_BOOL, "use_verts"}, /* dissolve verts left between only 2 edges. */ - {0}, + {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, + {"use_verts", BMO_OP_SLOT_BOOL}, /* dissolve verts left between only 2 edges. */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "region.out"}, - {0}, + {{"region.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{'\0'}}, }, bmo_dissolve_edges_exec, BMO_OP_FLAG_UNTAN_MULTIRES @@ -818,12 +827,12 @@ static BMOpDefine bmo_dissolve_edges_def = { static BMOpDefine bmo_dissolve_edge_loop_def = { "dissolve_edge_loop", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, - {0}, + {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "region.out"}, - {0}, + {{"region.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{'\0'}}, }, bmo_dissolve_edgeloop_exec, BMO_OP_FLAG_UNTAN_MULTIRES @@ -832,13 +841,13 @@ static BMOpDefine bmo_dissolve_edge_loop_def = { static BMOpDefine bmo_dissolve_faces_def = { "dissolve_faces", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, - {BMO_OP_SLOT_BOOL, "use_verts"}, /* dissolve verts left between only 2 edges. */ - {0}, + {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, + {"use_verts", BMO_OP_SLOT_BOOL}, /* dissolve verts left between only 2 edges. */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "region.out"}, - {0}, + {{"region.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{'\0'}}, }, bmo_dissolve_faces_exec, BMO_OP_FLAG_UNTAN_MULTIRES @@ -847,13 +856,13 @@ static BMOpDefine bmo_dissolve_faces_def = { static BMOpDefine bmo_dissolve_limit_def = { "dissolve_limit", /* slots_in */ - {{BMO_OP_SLOT_FLT, "angle_limit"}, /* total rotation angle (degrees) */ - {BMO_OP_SLOT_BOOL, "use_dissolve_boundaries"}, - {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, - {BMO_OP_SLOT_ELEMENT_BUF, "edges"}, - {0}, + {{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (degrees) */ + {"use_dissolve_boundaries", BMO_OP_SLOT_BOOL}, + {"verts", BMO_OP_SLOT_ELEMENT_BUF}, + {"edges", BMO_OP_SLOT_ELEMENT_BUF}, + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_dissolve_limit_exec, BMO_OP_FLAG_UNTAN_MULTIRES }; @@ -861,15 +870,15 @@ static BMOpDefine bmo_dissolve_limit_def = { static BMOpDefine bmo_triangulate_def = { "triangulate", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, - {BMO_OP_SLOT_BOOL, "use_beauty"}, - {0}, + {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, + {"use_beauty", BMO_OP_SLOT_BOOL}, + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, - {BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, - {BMO_OP_SLOT_MAPPING, "facemap.out"}, - {0}, + {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, + {"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, + {"facemap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM}, + {{'\0'}}, }, bmo_triangulate_exec, BMO_OP_FLAG_UNTAN_MULTIRES @@ -878,11 +887,11 @@ static BMOpDefine bmo_triangulate_def = { static BMOpDefine bmo_unsubdivide_def = { "unsubdivide", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */ - {BMO_OP_SLOT_INT, "iterations"}, - {0}, + {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {"iterations", BMO_OP_SLOT_INT}, + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_unsubdivide_exec, BMO_OP_FLAG_UNTAN_MULTIRES }; @@ -890,27 +899,27 @@ static BMOpDefine bmo_unsubdivide_def = { static BMOpDefine bmo_subdivide_edges_def = { "subdivide_edges", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, - {BMO_OP_SLOT_FLT, "smooth"}, - {BMO_OP_SLOT_FLT, "fractal"}, - {BMO_OP_SLOT_FLT, "along_normal"}, - {BMO_OP_SLOT_INT, "cuts"}, - {BMO_OP_SLOT_INT, "seed"}, - {BMO_OP_SLOT_MAPPING, "custompatterns"}, - {BMO_OP_SLOT_MAPPING, "edgepercents"}, - - {BMO_OP_SLOT_INT, "quad_corner_type"}, /* quad corner type, see bmesh_operators.h */ - {BMO_OP_SLOT_BOOL, "use_gridfill"}, /* fill in fully-selected faces with a grid */ - {BMO_OP_SLOT_BOOL, "use_singleedge"}, /* tessellate the case of one edge selected in a quad or triangle */ - {BMO_OP_SLOT_BOOL, "use_sphere"}, /* for making new primitives only */ - {0}, + {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, + {"smooth", BMO_OP_SLOT_FLT}, + {"fractal", BMO_OP_SLOT_FLT}, + {"along_normal", BMO_OP_SLOT_FLT}, + {"cuts", BMO_OP_SLOT_INT}, + {"seed", BMO_OP_SLOT_INT}, + {"custompatterns", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL}, /* uses custom pointers */ + {"edgepercents", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_FLOAT}, + + {"quad_corner_type", BMO_OP_SLOT_INT}, /* quad corner type, see bmesh_operators.h */ + {"use_gridfill", BMO_OP_SLOT_BOOL}, /* fill in fully-selected faces with a grid */ + {"use_singleedge", BMO_OP_SLOT_BOOL}, /* tessellate the case of one edge selected in a quad or triangle */ + {"use_sphere", BMO_OP_SLOT_BOOL}, /* for making new primitives only */ + {{'\0'}}, }, /* slots_out */ {/* these next three can have multiple types of elements in them */ - {BMO_OP_SLOT_ELEMENT_BUF, "geom_inner.out"}, - {BMO_OP_SLOT_ELEMENT_BUF, "geom_split.out"}, - {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* contains all output geometr */ - {0}, + {"geom_inner.out", BMO_OP_SLOT_ELEMENT_BUF}, + {"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF}, + {"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, /* contains all output geometr */ + {{'\0'}}, }, bmo_subdivide_edges_exec, BMO_OP_FLAG_UNTAN_MULTIRES @@ -919,11 +928,11 @@ static BMOpDefine bmo_subdivide_edges_def = { static BMOpDefine bmo_delete_def = { "delete", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, - {BMO_OP_SLOT_INT, "context"}, - {0}, + {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, + {"context", BMO_OP_SLOT_INT}, + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_delete_exec, 0 }; @@ -931,19 +940,20 @@ static BMOpDefine bmo_delete_def = { static BMOpDefine bmo_duplicate_def = { "duplicate", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, - {BMO_OP_SLOT_PTR, "dest"}, /* destination bmesh, if NULL will use current on */ - {0}, + {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, + /* destination bmesh, if NULL will use current on */ + {"dest", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_BMESH}, + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom_orig.out"}, - {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, + {{"geom_orig.out", BMO_OP_SLOT_ELEMENT_BUF}, + {"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, /* facemap maps from source faces to dupe * faces, and from dupe faces to source faces */ - {BMO_OP_SLOT_MAPPING, "facemap.out"}, - {BMO_OP_SLOT_MAPPING, "boundarymap.out"}, - {BMO_OP_SLOT_MAPPING, "isovertmap.out"}, - {0}, + {"facemap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM}, + {"boundarymap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM}, + {"isovertmap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM}, + {{'\0'}}, }, bmo_duplicate_exec, 0 @@ -952,16 +962,17 @@ static BMOpDefine bmo_duplicate_def = { static BMOpDefine bmo_split_def = { "split", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, - {BMO_OP_SLOT_PTR, "dest"}, /* destination bmesh, if NULL will use current one */ - {BMO_OP_SLOT_BOOL, "use_only_faces"}, /* when enabled. don't duplicate loose verts/edges */ - {0}, + {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, + /* destination bmesh, if NULL will use current one */ + {"dest", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_BMESH}, + {"use_only_faces", BMO_OP_SLOT_BOOL}, /* when enabled. don't duplicate loose verts/edges */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, - {BMO_OP_SLOT_MAPPING, "boundarymap.out"}, - {BMO_OP_SLOT_MAPPING, "isovertmap.out"}, - {0}, + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, + {"boundarymap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM}, + {"isovertmap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM}, + {{'\0'}}, }, bmo_split_exec, 0 @@ -976,18 +987,18 @@ static BMOpDefine bmo_split_def = { static BMOpDefine bmo_spin_def = { "spin", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, - {BMO_OP_SLOT_VEC, "cent"}, /* rotation center */ - {BMO_OP_SLOT_VEC, "axis"}, /* rotation axis */ - {BMO_OP_SLOT_VEC, "dvec"}, /* translation delta per step */ - {BMO_OP_SLOT_FLT, "angle"}, /* total rotation angle (degrees) */ - {BMO_OP_SLOT_INT, "steps"}, /* number of steps */ - {BMO_OP_SLOT_BOOL, "use_duplicate"}, /* duplicate or extrude? */ - {0}, + {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, + {"cent", BMO_OP_SLOT_VEC}, /* rotation center */ + {"axis", BMO_OP_SLOT_VEC}, /* rotation axis */ + {"dvec", BMO_OP_SLOT_VEC}, /* translation delta per step */ + {"angle", BMO_OP_SLOT_FLT}, /* total rotation angle (degrees) */ + {"steps", BMO_OP_SLOT_INT}, /* number of steps */ + {"use_duplicate", BMO_OP_SLOT_BOOL}, /* duplicate or extrude? */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom_last.out"}, /* result of last step */ - {0}, + {{"geom_last.out", BMO_OP_SLOT_ELEMENT_BUF}, /* result of last step */ + {{'\0'}}, }, bmo_spin_exec, 0 @@ -1002,15 +1013,15 @@ static BMOpDefine bmo_spin_def = { static BMOpDefine bmo_similar_faces_def = { "similar_faces", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */ - {BMO_OP_SLOT_INT, "type"}, /* type of selection */ - {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */ - {BMO_OP_SLOT_INT, "compare"}, /* comparison method */ - {0}, + {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {"type", BMO_OP_SLOT_INT}, /* type of selection */ + {"thresh", BMO_OP_SLOT_FLT}, /* threshold of selection */ + {"compare", BMO_OP_SLOT_INT}, /* comparison method */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* output faces */ - {0}, + {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output faces */ + {{'\0'}}, }, bmo_similar_faces_exec, 0 @@ -1024,15 +1035,15 @@ static BMOpDefine bmo_similar_faces_def = { static BMOpDefine bmo_similar_edges_def = { "similar_edges", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */ - {BMO_OP_SLOT_INT, "type"}, /* type of selection */ - {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */ - {BMO_OP_SLOT_INT, "compare"}, /* comparison method */ - {0}, + {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edges */ + {"type", BMO_OP_SLOT_INT}, /* type of selection */ + {"thresh", BMO_OP_SLOT_FLT}, /* threshold of selection */ + {"compare", BMO_OP_SLOT_INT}, /* comparison method */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* output edges */ - {0}, + {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output edges */ + {{'\0'}}, }, bmo_similar_edges_exec, 0 @@ -1046,15 +1057,15 @@ static BMOpDefine bmo_similar_edges_def = { static BMOpDefine bmo_similar_verts_def = { "similar_verts", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */ - {BMO_OP_SLOT_INT, "type"}, /* type of selection */ - {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */ - {BMO_OP_SLOT_INT, "compare"}, /* comparison method */ - {0}, + {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {"type", BMO_OP_SLOT_INT}, /* type of selection */ + {"thresh", BMO_OP_SLOT_FLT}, /* threshold of selection */ + {"compare", BMO_OP_SLOT_INT}, /* comparison method */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output vertices */ - {0}, + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output vertices */ + {{'\0'}}, }, bmo_similar_verts_exec, 0 @@ -1067,12 +1078,12 @@ static BMOpDefine bmo_similar_verts_def = { static BMOpDefine bmo_rotate_uvs_def = { "rotate_uvs", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */ - {BMO_OP_SLOT_BOOL, "use_ccw"}, /* rotate counter-clockwise if true, othewise clockwise */ - {0}, + {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, othewise clockwise */ + {{'\0'}}, }, /* slots_out */ - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_rotate_uvs_exec, 0 }; @@ -1084,10 +1095,10 @@ static BMOpDefine bmo_rotate_uvs_def = { static BMOpDefine bmo_reverse_uvs_def = { "reverse_uvs", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */ - {0}, + {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_reverse_uvs_exec, 0 }; @@ -1099,11 +1110,11 @@ static BMOpDefine bmo_reverse_uvs_def = { static BMOpDefine bmo_rotate_colors_def = { "rotate_colors", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */ - {BMO_OP_SLOT_BOOL, "use_ccw"}, /* rotate counter-clockwise if true, othewise clockwise */ - {0}, + {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, othewise clockwise */ + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_rotate_colors_exec, 0 }; @@ -1115,10 +1126,10 @@ static BMOpDefine bmo_rotate_colors_def = { static BMOpDefine bmo_reverse_colors_def = { "reverse_colors", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */ - {0}, + {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {{'\0'}}, }, - {{0}}, /* no output */ + {{{'\0'}}}, /* no output */ bmo_reverse_colors_exec, 0 }; @@ -1131,14 +1142,14 @@ static BMOpDefine bmo_reverse_colors_def = { static BMOpDefine bmo_shortest_path_def = { "shortest_path", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "startv"}, /* start vertex */ - {BMO_OP_SLOT_ELEMENT_BUF, "endv"}, /* end vertex */ - {BMO_OP_SLOT_INT, "type"}, /* type of selection */ - {0}, + {{"startv", BMO_OP_SLOT_ELEMENT_BUF}, /* start vertex */ + {"endv", BMO_OP_SLOT_ELEMENT_BUF}, /* end vertex */ + {"type", BMO_OP_SLOT_INT}, /* type of selection */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output vertices */ - {0}, + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output vertices */ + {{'\0'}}, }, bmo_shortest_path_exec, 0 @@ -1152,15 +1163,15 @@ static BMOpDefine bmo_shortest_path_def = { static BMOpDefine bmo_split_edges_def = { "split_edges", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edges */ /* needed for vertex rip so we can rip only half an edge at a boundary wich would otherwise split off */ - {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* optional tag verts, use to have greater control of splits */ - {BMO_OP_SLOT_BOOL, "use_verts"}, /* use 'verts' for splitting, else just find verts to split from edges */ - {0}, + {"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* optional tag verts, use to have greater control of splits */ + {"use_verts", BMO_OP_SLOT_BOOL}, /* use 'verts' for splitting, else just find verts to split from edges */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* old output disconnected edges */ - {0}, + {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, /* old output disconnected edges */ + {{'\0'}}, }, bmo_split_edges_exec, BMO_OP_FLAG_UNTAN_MULTIRES @@ -1174,15 +1185,15 @@ static BMOpDefine bmo_split_edges_def = { static BMOpDefine bmo_create_grid_def = { "create_grid", /* slots_in */ - {{BMO_OP_SLOT_INT, "x_segments"}, /* number of x segments */ - {BMO_OP_SLOT_INT, "y_segments"}, /* number of y segments */ - {BMO_OP_SLOT_FLT, "size"}, /* size of the grid */ - {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */ - {0}, + {{"x_segments", BMO_OP_SLOT_INT}, /* number of x segments */ + {"y_segments", BMO_OP_SLOT_INT}, /* number of y segments */ + {"size", BMO_OP_SLOT_FLT}, /* size of the grid */ + {"mat", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */ - {0}, + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */ + {{'\0'}}, }, bmo_create_grid_exec, 0, @@ -1196,15 +1207,15 @@ static BMOpDefine bmo_create_grid_def = { static BMOpDefine bmo_create_uvsphere_def = { "create_uvsphere", /* slots_in */ - {{BMO_OP_SLOT_INT, "u_segments"}, /* number of u segments */ - {BMO_OP_SLOT_INT, "v_segments"}, /* number of v segment */ - {BMO_OP_SLOT_FLT, "diameter"}, /* diameter */ - {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */ - {0}, + {{"u_segments", BMO_OP_SLOT_INT}, /* number of u segments */ + {"v_segments", BMO_OP_SLOT_INT}, /* number of v segment */ + {"diameter", BMO_OP_SLOT_FLT}, /* diameter */ + {"mat", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */ - {0}, + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */ + {{'\0'}}, }, bmo_create_uvsphere_exec, 0, @@ -1218,14 +1229,14 @@ static BMOpDefine bmo_create_uvsphere_def = { static BMOpDefine bmo_create_icosphere_def = { "create_icosphere", /* slots_in */ - {{BMO_OP_SLOT_INT, "subdivisions"}, /* how many times to recursively subdivide the sphere */ - {BMO_OP_SLOT_FLT, "diameter"}, /* diameter */ - {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */ - {0}, + {{"subdivisions", BMO_OP_SLOT_INT}, /* how many times to recursively subdivide the sphere */ + {"diameter", BMO_OP_SLOT_FLT}, /* diameter */ + {"mat", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */ - {0}, + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */ + {{'\0'}}, }, bmo_create_icosphere_exec, 0, @@ -1239,12 +1250,12 @@ static BMOpDefine bmo_create_icosphere_def = { static BMOpDefine bmo_create_monkey_def = { "create_monkey", /* slots_in */ - {{BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */ - {0}, + {{"mat", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */ - {0}, + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */ + {{'\0'}}, }, bmo_create_monkey_exec, 0, @@ -1258,18 +1269,18 @@ static BMOpDefine bmo_create_monkey_def = { static BMOpDefine bmo_create_cone_def = { "create_cone", /* slots_in */ - {{BMO_OP_SLOT_BOOL, "cap_ends"}, /* wheter or not to fill in the ends with faces */ - {BMO_OP_SLOT_BOOL, "cap_tris"}, /* fill ends with triangles instead of ngons */ - {BMO_OP_SLOT_INT, "segments"}, - {BMO_OP_SLOT_FLT, "diameter1"}, /* diameter of one end */ - {BMO_OP_SLOT_FLT, "diameter2"}, /* diameter of the opposite */ - {BMO_OP_SLOT_FLT, "depth"}, /* distance between ends */ - {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */ - {0}, + {{"cap_ends", BMO_OP_SLOT_BOOL}, /* wheter or not to fill in the ends with faces */ + {"cap_tris", BMO_OP_SLOT_BOOL}, /* fill ends with triangles instead of ngons */ + {"segments", BMO_OP_SLOT_INT}, + {"diameter1", BMO_OP_SLOT_FLT}, /* diameter of one end */ + {"diameter2", BMO_OP_SLOT_FLT}, /* diameter of the opposite */ + {"depth", BMO_OP_SLOT_FLT}, /* distance between ends */ + {"mat", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */ - {0}, + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */ + {{'\0'}}, }, bmo_create_cone_exec, 0, @@ -1281,16 +1292,16 @@ static BMOpDefine bmo_create_cone_def = { static BMOpDefine bmo_create_circle_def = { "create_circle", /* slots_in */ - {{BMO_OP_SLOT_BOOL, "cap_ends"}, /* wheter or not to fill in the ends with faces */ - {BMO_OP_SLOT_BOOL, "cap_tris"}, /* fill ends with triangles instead of ngons */ - {BMO_OP_SLOT_INT, "segments"}, - {BMO_OP_SLOT_FLT, "diameter"}, /* diameter of one end */ - {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */ - {0}, + {{"cap_ends", BMO_OP_SLOT_BOOL}, /* wheter or not to fill in the ends with faces */ + {"cap_tris", BMO_OP_SLOT_BOOL}, /* fill ends with triangles instead of ngons */ + {"segments", BMO_OP_SLOT_INT}, + {"diameter", BMO_OP_SLOT_FLT}, /* diameter of one end */ + {"mat", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */ - {0}, + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */ + {{'\0'}}, }, bmo_create_circle_exec, 0, @@ -1304,13 +1315,13 @@ static BMOpDefine bmo_create_circle_def = { static BMOpDefine bmo_create_cube_def = { "create_cube", /* slots_in */ - {{BMO_OP_SLOT_FLT, "size"}, /* size of the cube */ - {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */ - {0}, + {{"size", BMO_OP_SLOT_FLT}, /* size of the cube */ + {"mat", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */ - {0}, + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */ + {{'\0'}}, }, bmo_create_cube_exec, 0, @@ -1324,26 +1335,26 @@ static BMOpDefine bmo_create_cube_def = { static BMOpDefine bmo_bevel_def = { "bevel", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input edges and vertices */ - {BMO_OP_SLOT_FLT, "offset"}, /* amount to offset beveled edge */ - {BMO_OP_SLOT_INT, "segments"}, /* number of segments in bevel */ - {0}, + {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, /* input edges and vertices */ + {"offset", BMO_OP_SLOT_FLT}, /* amount to offset beveled edge */ + {"segments", BMO_OP_SLOT_INT}, /* number of segments in bevel */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* output faces */ - {0}, + {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output faces */ + {{'\0'}}, }, #if 0 /* old bevel*/ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input edges and vertices */ - {BMO_OP_SLOT_ELEMENT_BUF, "face_spans"}, /* new geometry */ - {BMO_OP_SLOT_ELEMENT_BUF, "face_holes"}, /* new geometry */ - {BMO_OP_SLOT_BOOL, "use_lengths"}, /* grab edge lengths from a PROP_FLT customdata layer */ - {BMO_OP_SLOT_BOOL, "use_even"}, /* corner vert placement: use shell/angle calculations */ - {BMO_OP_SLOT_BOOL, "use_dist"}, /* corner vert placement: evaluate percent as a distance, + {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, /* input edges and vertices */ + {"face_spans", BMO_OP_SLOT_ELEMENT_BUF}, /* new geometry */ + {"face_holes", BMO_OP_SLOT_ELEMENT_BUF}, /* new geometry */ + {"use_lengths", BMO_OP_SLOT_BOOL}, /* grab edge lengths from a PROP_FLT customdata layer */ + {"use_even", BMO_OP_SLOT_BOOL}, /* corner vert placement: use shell/angle calculations */ + {"use_dist", BMO_OP_SLOT_BOOL}, /* corner vert placement: evaluate percent as a distance, * modifier uses this. We could do this as another float setting */ - {BMO_OP_SLOT_INT, "lengthlayer"}, /* which PROP_FLT layer to us */ - {BMO_OP_SLOT_FLT, "percent"}, /* percentage to expand beveled edge */ - {0}, + {"lengthlayer", BMO_OP_SLOT_INT}, /* which PROP_FLT layer to us */ + {"percent", BMO_OP_SLOT_FLT}, /* percentage to expand beveled edge */ + {{'\0'}}, }, #endif bmo_bevel_exec, @@ -1358,13 +1369,13 @@ static BMOpDefine bmo_bevel_def = { static BMOpDefine bmo_beautify_fill_def = { "beautify_fill", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */ - {BMO_OP_SLOT_ELEMENT_BUF, "constrain_edges"}, /* edges that can't be flipped */ - {0}, + {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {"constrain_edges", BMO_OP_SLOT_ELEMENT_BUF}, /* edges that can't be flipped */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* new flipped faces and edges */ - {0}, + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, /* new flipped faces and edges */ + {{'\0'}}, }, bmo_beautify_fill_exec, BMO_OP_FLAG_UNTAN_MULTIRES @@ -1378,12 +1389,12 @@ static BMOpDefine bmo_beautify_fill_def = { static BMOpDefine bmo_triangle_fill_def = { "triangle_fill", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */ - {0}, + {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edges */ + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* new faces and edges */ - {0}, + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, /* new faces and edges */ + {{'\0'}}, }, bmo_triangle_fill_exec, BMO_OP_FLAG_UNTAN_MULTIRES @@ -1397,13 +1408,13 @@ static BMOpDefine bmo_triangle_fill_def = { static BMOpDefine bmo_solidify_def = { "solidify", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, - {BMO_OP_SLOT_FLT, "thickness"}, - {0}, + {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, + {"thickness", BMO_OP_SLOT_FLT}, + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, - {0}, + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{'\0'}}, }, bmo_solidify_face_region_exec, 0 @@ -1417,18 +1428,18 @@ static BMOpDefine bmo_solidify_def = { static BMOpDefine bmo_inset_def = { "inset", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */ - {BMO_OP_SLOT_BOOL, "use_boundary"}, - {BMO_OP_SLOT_BOOL, "use_even_offset"}, - {BMO_OP_SLOT_BOOL, "use_relative_offset"}, - {BMO_OP_SLOT_FLT, "thickness"}, - {BMO_OP_SLOT_FLT, "depth"}, - {BMO_OP_SLOT_BOOL, "use_outset"}, - {0}, + {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {"use_boundary", BMO_OP_SLOT_BOOL}, + {"use_even_offset", BMO_OP_SLOT_BOOL}, + {"use_relative_offset", BMO_OP_SLOT_BOOL}, + {"thickness", BMO_OP_SLOT_FLT}, + {"depth", BMO_OP_SLOT_FLT}, + {"use_outset", BMO_OP_SLOT_BOOL}, + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* output faces */ - {0}, + {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output faces */ + {{'\0'}}, }, bmo_inset_exec, 0 @@ -1442,18 +1453,18 @@ static BMOpDefine bmo_inset_def = { static BMOpDefine bmo_wireframe_def = { "wireframe", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */ - {BMO_OP_SLOT_BOOL, "use_boundary"}, - {BMO_OP_SLOT_BOOL, "use_even_offset"}, - {BMO_OP_SLOT_BOOL, "use_crease"}, - {BMO_OP_SLOT_FLT, "thickness"}, - {BMO_OP_SLOT_BOOL, "use_relative_offset"}, - {BMO_OP_SLOT_FLT, "depth"}, - {0}, + {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {"use_boundary", BMO_OP_SLOT_BOOL}, + {"use_even_offset", BMO_OP_SLOT_BOOL}, + {"use_crease", BMO_OP_SLOT_BOOL}, + {"thickness", BMO_OP_SLOT_FLT}, + {"use_relative_offset", BMO_OP_SLOT_BOOL}, + {"depth", BMO_OP_SLOT_FLT}, + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* output faces */ - {0}, + {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output faces */ + {{'\0'}}, }, bmo_wireframe_exec, 0 @@ -1467,14 +1478,14 @@ static BMOpDefine bmo_wireframe_def = { static BMOpDefine bmo_slide_vert_def = { "slide_vert", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "vert"}, - {BMO_OP_SLOT_ELEMENT_BUF, "edge"}, - {BMO_OP_SLOT_FLT, "distance_t"}, - {0}, + {{"vert", BMO_OP_SLOT_ELEMENT_BUF}, + {"edge", BMO_OP_SLOT_ELEMENT_BUF}, + {"distance_t", BMO_OP_SLOT_FLT}, + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, - {0}, + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{'\0'}}, }, bmo_slide_vert_exec, BMO_OP_FLAG_UNTAN_MULTIRES @@ -1499,16 +1510,16 @@ static BMOpDefine bmo_slide_vert_def = { static BMOpDefine bmo_convex_hull_def = { "convex_hull", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "input"}, - {BMO_OP_SLOT_BOOL, "use_existing_faces"}, - {0}, + {{"input", BMO_OP_SLOT_ELEMENT_BUF}, + {"use_existing_faces", BMO_OP_SLOT_BOOL}, + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, - {BMO_OP_SLOT_ELEMENT_BUF, "geom_interior.out"}, - {BMO_OP_SLOT_ELEMENT_BUF, "geom_unused.out"}, - {BMO_OP_SLOT_ELEMENT_BUF, "geom_holes.out"}, - {0}, + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, + {"geom_interior.out", BMO_OP_SLOT_ELEMENT_BUF}, + {"geom_unused.out", BMO_OP_SLOT_ELEMENT_BUF}, + {"geom_holes.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{'\0'}}, }, bmo_convex_hull_exec, 0 @@ -1528,19 +1539,19 @@ static BMOpDefine bmo_convex_hull_def = { static BMOpDefine bmo_symmetrize_def = { "symmetrize", /* slots_in */ - {{BMO_OP_SLOT_ELEMENT_BUF, "input"}, - {BMO_OP_SLOT_INT, "direction"}, - {0}, + {{"input", BMO_OP_SLOT_ELEMENT_BUF}, + {"direction", BMO_OP_SLOT_INT}, + {{'\0'}}, }, /* slots_out */ - {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, - {0}, + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{'\0'}}, }, bmo_symmetrize_exec, 0 }; -BMOpDefine *opdefines[] = { +const BMOpDefine *bmo_opdefines[] = { &bmo_automerge_def, &bmo_average_vert_facedata_def, &bmo_beautify_fill_def, @@ -1615,7 +1626,6 @@ BMOpDefine *opdefines[] = { &bmo_unsubdivide_def, &bmo_weld_verts_def, &bmo_wireframe_def, - }; -int bmesh_total_ops = (sizeof(opdefines) / sizeof(void *)); +const int bmo_opdefines_total = (sizeof(bmo_opdefines) / sizeof(void *)); diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h index b87e023e63a..efc2f6a492e 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api.h +++ b/source/blender/bmesh/intern/bmesh_operator_api.h @@ -91,15 +91,15 @@ BLI_INLINE void _bmo_elem_flag_toggle( BMesh *bm, BMFlagLayer *oflags, const /* slot type arrays are terminated by the last member * having a slot type of 0 */ -enum { - BMO_OP_SLOT_SENTINEL = 0, +typedef enum eBMOpSlotType { + /* BMO_OP_SLOT_SENTINEL = 0, */ BMO_OP_SLOT_BOOL = 1, BMO_OP_SLOT_INT = 2, BMO_OP_SLOT_FLT = 3, /* normally store pointers to object, scene, * _never_ store arrays corresponding to mesh elements with this */ - BMO_OP_SLOT_PTR = 4, + BMO_OP_SLOT_PTR = 4, /* requres subtype BMO_OP_SLOT_SUBTYPE_PTR_xxx */ BMO_OP_SLOT_MAT = 5, BMO_OP_SLOT_VEC = 8, @@ -108,16 +108,39 @@ enum { * * it's very important this remain a power of two */ BMO_OP_SLOT_ELEMENT_BUF = 9, /* list of verts/edges/faces */ - BMO_OP_SLOT_MAPPING = 10 /* simple hash map */ -}; + BMO_OP_SLOT_MAPPING = 10 /* simple hash map, requres subtype BMO_OP_SLOT_SUBTYPE_MAP_xxx */ +} eBMOpSlotType; #define BMO_OP_SLOT_TOTAL_TYPES 11 +/* leave zero for invalid/unset */ +typedef enum eBMOpSlotSubType { + /* BMO_OP_SLOT_MAPPING */ +#define BMO_OP_SLOT_SUBTYPE_MAP__FIRST BMO_OP_SLOT_SUBTYPE_MAP_EMPTY + BMO_OP_SLOT_SUBTYPE_MAP_EMPTY = 1, /* use as a set(), unused value */ + BMO_OP_SLOT_SUBTYPE_MAP_ELEM = 2, + BMO_OP_SLOT_SUBTYPE_MAP_FLOAT = 3, + BMO_OP_SLOT_SUBTYPE_MAP_INT = 4, + BMO_OP_SLOT_SUBTYPE_MAP_BOOL = 5, + BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL = 6, /* python can't convert these */ +#define BMO_OP_SLOT_SUBTYPE_MAP__LAST BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL + + /* BMO_OP_SLOT_PTR */ +#define BMO_OP_SLOT_SUBTYPE_PTR__FIRST BMO_OP_SLOT_SUBTYPE_PTR_BMESH + BMO_OP_SLOT_SUBTYPE_PTR_BMESH = 10, + BMO_OP_SLOT_SUBTYPE_PTR_SCENE = 11, + BMO_OP_SLOT_SUBTYPE_PTR_OBJECT = 12, + BMO_OP_SLOT_SUBTYPE_PTR_MESH = 13, +#define BMO_OP_SLOT_SUBTYPE_PTR__LAST BMO_OP_SLOT_SUBTYPE_PTR_MESH + +} eBMOpSlotSubType; + /* please ignore all these structures, don't touch them in tool code, except * for when your defining an operator with BMOpDefine.*/ typedef struct BMOpSlot { const char *slot_name; /* pointer to BMOpDefine.slot_args */ - int slot_type; + eBMOpSlotType slot_type; + eBMOpSlotSubType slot_subtype; int len; // int flag; /* UNUSED */ // int index; /* index within slot array */ /* UNUSED */ @@ -166,8 +189,9 @@ enum { #define MAX_SLOTNAME 32 typedef struct BMOSlotType { - int type; char name[MAX_SLOTNAME]; + eBMOpSlotType type; + eBMOpSlotSubType subtype; } BMOSlotType; typedef struct BMOpDefine { diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 157837a13c0..7fd9bcf1951 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -127,7 +127,7 @@ void BMO_pop(BMesh *bm) /* use for both slot_types_in and slot_types_out */ -static void bmo_op_slots_init(BMOSlotType *slot_types, BMOpSlot *slot_args) +static void bmo_op_slots_init(const BMOSlotType *slot_types, BMOpSlot *slot_args) { unsigned int i; for (i = 0; slot_types[i].type; i++) { @@ -158,15 +158,15 @@ void BMO_op_init(BMesh *bm, BMOperator *op, const int flag, const char *opname) memset(op, 0, sizeof(BMOperator)); op->type = opcode; - op->type_flag = opdefines[opcode]->type_flag; + op->type_flag = bmo_opdefines[opcode]->type_flag; op->flag = flag; /* initialize the operator slot types */ - bmo_op_slots_init(opdefines[opcode]->slot_types_in, op->slots_in); - bmo_op_slots_init(opdefines[opcode]->slot_types_out, op->slots_out); + bmo_op_slots_init(bmo_opdefines[opcode]->slot_types_in, op->slots_in); + bmo_op_slots_init(bmo_opdefines[opcode]->slot_types_out, op->slots_out); /* callback */ - op->exec = opdefines[opcode]->exec; + op->exec = bmo_opdefines[opcode]->exec; /* memarena, used for operator's slot buffers */ op->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); @@ -199,7 +199,7 @@ void BMO_op_exec(BMesh *bm, BMOperator *op) BMO_pop(bm); } -static void bmo_op_slots_free(BMOSlotType *slot_types, BMOpSlot *slot_args) +static void bmo_op_slots_free(const BMOSlotType *slot_types, BMOpSlot *slot_args) { BMOpSlot *slot; unsigned int i; @@ -220,13 +220,13 @@ static void bmo_op_slots_free(BMOSlotType *slot_types, BMOpSlot *slot_args) */ void BMO_op_finish(BMesh *bm, BMOperator *op) { - bmo_op_slots_free(opdefines[op->type]->slot_types_in, op->slots_in); - bmo_op_slots_free(opdefines[op->type]->slot_types_out, op->slots_out); + bmo_op_slots_free(bmo_opdefines[op->type]->slot_types_in, op->slots_in); + bmo_op_slots_free(bmo_opdefines[op->type]->slot_types_out, op->slots_out); BLI_memarena_free(op->arena); #ifdef DEBUG - BM_ELEM_INDEX_VALIDATE(bm, "post bmo", opdefines[op->type]->opname); + BM_ELEM_INDEX_VALIDATE(bm, "post bmo", bmo_opdefines[op->type]->opname); #else (void)bm; #endif @@ -631,7 +631,7 @@ void *bmo_slot_buffer_grow(BMesh *bm, BMOperator *op, int slot_code, int totadd) if (slot->len >= slot->size) { slot->size = (slot->size + 1 + totadd) * 2; - allocsize = BMO_OPSLOT_TYPEINFO[opdefines[op->type]->slot_types[slot_code].type] * slot->size; + allocsize = BMO_OPSLOT_TYPEINFO[bmo_opdefines[op->type]->slot_types[slot_code].type] * slot->size; tmp = slot->data.buf; slot->data.buf = MEM_callocN(allocsize, "opslot dynamic array"); @@ -646,7 +646,7 @@ void *bmo_slot_buffer_grow(BMesh *bm, BMOperator *op, int slot_code, int totadd) slot->len += totadd; slot->size = slot->len + 2; - allocsize = BMO_OPSLOT_TYPEINFO[opdefines[op->type]->slot_types[slot_code].type] * slot->len; + allocsize = BMO_OPSLOT_TYPEINFO[bmo_opdefines[op->type]->slot_types[slot_code].type] * slot->len; tmp = slot->data.buf; slot->data.buf = MEM_callocN(allocsize, "opslot dynamic array"); @@ -1393,8 +1393,8 @@ static int bmo_opname_to_opcode(const char *opname) { int i; - for (i = 0; i < bmesh_total_ops; i++) { - if (!strcmp(opname, opdefines[i]->opname)) { + for (i = 0; i < bmo_opdefines_total; i++) { + if (!strcmp(opname, bmo_opdefines[i]->opname)) { return i; } } @@ -1463,7 +1463,7 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v } BMO_op_init(bm, op, flag, opname); -// def = opdefines[i]; +// def = bmo_opdefines[i]; i = 0; state = 1; /* 0: not inside slot_code name, 1: inside slot_code name */ diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h index 8c478a3517f..03363ed765a 100644 --- a/source/blender/bmesh/intern/bmesh_operators.h +++ b/source/blender/bmesh/intern/bmesh_operators.h @@ -89,8 +89,8 @@ enum { VPATH_SELECT_TOPOLOGICAL }; -extern BMOpDefine *opdefines[]; -extern int bmesh_total_ops; +extern const BMOpDefine *bmo_opdefines[]; +extern const int bmo_opdefines_total; /*------specific operator helper functions-------*/ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag, diff --git a/source/blender/python/bmesh/bmesh_py_ops.c b/source/blender/python/bmesh/bmesh_py_ops.c index 2b82826eb04..5ab8b7c0e26 100644 --- a/source/blender/python/bmesh/bmesh_py_ops.c +++ b/source/blender/python/bmesh/bmesh_py_ops.c @@ -353,6 +353,10 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject * case BMO_OP_SLOT_VEC: item = Vector_CreatePyObject(BMO_SLOT_AS_VECTOR(slot), slot->len, Py_NEW, NULL); break; + case BMO_OP_SLOT_PTR: + BLI_assert(0); /* currently we don't have any pointer return values in use */ + item = (Py_INCREF(Py_None), Py_None); + break; case BMO_OP_SLOT_ELEMENT_BUF: { const int size = slot->len; @@ -501,15 +505,15 @@ PyTypeObject bmesh_op_Type = { /* bmesh fake module 'bmesh.ops' * ***************************** */ -static PyObject *bpy_bmesh_fmod_getattro(PyObject *UNUSED(self), PyObject *pyname) +static PyObject *bpy_bmesh_ops_fakemod_getattro(PyObject *UNUSED(self), PyObject *pyname) { - const unsigned int tot = bmesh_total_ops; + const unsigned int tot = bmo_opdefines_total; unsigned int i; const char *opname = _PyUnicode_AsString(pyname); for (i = 0; i < tot; i++) { - if (strcmp(opdefines[i]->opname, opname) == 0) { - return bpy_bmesh_op_CreatePyObject(opdefines[i]->opname); + if (strcmp(bmo_opdefines[i]->opname, opname) == 0) { + return bpy_bmesh_op_CreatePyObject(opname); } } @@ -519,23 +523,23 @@ static PyObject *bpy_bmesh_fmod_getattro(PyObject *UNUSED(self), PyObject *pynam return NULL; } -static PyObject *bpy_bmesh_fmod_dir(PyObject *UNUSED(self)) +static PyObject *bpy_bmesh_ops_fakemod_dir(PyObject *UNUSED(self)) { - const unsigned int tot = bmesh_total_ops; + const unsigned int tot = bmo_opdefines_total; unsigned int i; PyObject *ret; - ret = PyList_New(bmesh_total_ops); + ret = PyList_New(bmo_opdefines_total); for (i = 0; i < tot; i++) { - PyList_SET_ITEM(ret, i, PyUnicode_FromString(opdefines[i]->opname)); + PyList_SET_ITEM(ret, i, PyUnicode_FromString(bmo_opdefines[i]->opname)); } return ret; } -static struct PyMethodDef bpy_bmesh_fmod_methods[] = { - {"__dir__", (PyCFunction)bpy_bmesh_fmod_dir, METH_NOARGS, NULL}, +static struct PyMethodDef bpy_bmesh_ops_fakemod_methods[] = { + {"__dir__", (PyCFunction)bpy_bmesh_ops_fakemod_dir, METH_NOARGS, NULL}, {NULL, NULL, 0, NULL} }; @@ -565,7 +569,7 @@ static PyTypeObject bmesh_ops_fakemod_Type = { NULL, /* reprfunc tp_str; */ /* will only use these if this is a subtype of a py class */ - bpy_bmesh_fmod_getattro, /* getattrofunc tp_getattro; */ + bpy_bmesh_ops_fakemod_getattro, /* getattrofunc tp_getattro; */ NULL, /* setattrofunc tp_setattro; */ /* Functions to access object as input/output buffer */ @@ -594,7 +598,7 @@ static PyTypeObject bmesh_ops_fakemod_Type = { NULL, /* iternextfunc tp_iternext; */ /*** Attribute descriptor and subclassing stuff ***/ - bpy_bmesh_fmod_methods, /* struct PyMethodDef *tp_methods; */ + bpy_bmesh_ops_fakemod_methods, /* struct PyMethodDef *tp_methods; */ NULL, /* struct PyMemberDef *tp_members; */ NULL, /* struct PyGetSetDef *tp_getset; */ NULL, /* struct _typeobject *tp_base; */ -- cgit v1.2.3 From 3d64381e4de22c8c65177b8f8d1b541284ae4483 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 Nov 2012 03:16:29 +0000 Subject: use more rigid type checking for bmesh slot subtypes. --- .../bmesh/intern/bmesh_operator_api_inline.h | 61 ++++++++++++++++++++-- source/blender/bmesh/intern/bmesh_operators.c | 8 ++- source/blender/bmesh/operators/bmo_dupe.c | 9 ++-- source/blender/bmesh/operators/bmo_extrude.c | 2 +- source/blender/bmesh/operators/bmo_mirror.c | 2 +- source/blender/bmesh/operators/bmo_removedoubles.c | 24 ++++----- source/blender/bmesh/operators/bmo_triangulate.c | 4 +- source/blender/editors/mesh/editmesh_tools.c | 6 +-- source/blender/modifiers/intern/MOD_array.c | 10 ++-- source/blender/modifiers/intern/MOD_skin.c | 5 +- 10 files changed, 94 insertions(+), 37 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_operator_api_inline.h b/source/blender/bmesh/intern/bmesh_operator_api_inline.h index b405ecc1841..1f6e44e9320 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api_inline.h +++ b/source/blender/bmesh/intern/bmesh_operator_api_inline.h @@ -72,12 +72,22 @@ BLI_INLINE void _bmo_elem_flag_toggle(BMesh *bm, BMFlagLayer *oflags, const shor BLI_INLINE void BMO_slot_map_int_insert(BMOperator *op, BMOpSlot *slot, void *element, int val) { + BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_INT); + BMO_slot_map_insert(op, slot, element, &val, sizeof(int)); +} + +BLI_INLINE void BMO_slot_map_bool_insert(BMOperator *op, BMOpSlot *slot, + void *element, int val) +{ + BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_BOOL); + BLI_assert(val == FALSE || val == TRUE); BMO_slot_map_insert(op, slot, element, &val, sizeof(int)); } BLI_INLINE void BMO_slot_map_float_insert(BMOperator *op, BMOpSlot *slot, void *element, float val) { + BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_FLOAT); BMO_slot_map_insert(op, slot, element, &val, sizeof(float)); } @@ -90,9 +100,26 @@ BLI_INLINE void BMO_slot_map_float_insert(BMOperator *op, BMOpSlot *slot, BLI_INLINE void BMO_slot_map_ptr_insert(BMOperator *op, BMOpSlot *slot, const void *element, void *val) { + BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL); BMO_slot_map_insert(op, slot, element, &val, sizeof(void *)); } +BLI_INLINE void BMO_slot_map_elem_insert(BMOperator *op, BMOpSlot *slot, + const void *element, void *val) +{ + BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_ELEM); + BMO_slot_map_insert(op, slot, element, &val, sizeof(void *)); +} + + +/* no values */ +BLI_INLINE void BMO_slot_map_empty_insert(BMOperator *op, BMOpSlot *slot, + const void *element) +{ + BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_EMPTY); + BMO_slot_map_insert(op, slot, element, NULL, 0); +} + BLI_INLINE int BMO_slot_map_contains(BMOpSlot *slot, const void *element) { BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING); @@ -126,7 +153,10 @@ BLI_INLINE void *BMO_slot_map_data_get(BMOpSlot *slot, const void *element) BLI_INLINE float BMO_slot_map_float_get(BMOpSlot *slot, const void *element) { - float *val = (float *) BMO_slot_map_data_get(slot, element); + float *val; + BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_FLOAT); + + val = (float *) BMO_slot_map_data_get(slot, element); if (val) return *val; return 0.0f; @@ -134,15 +164,40 @@ BLI_INLINE float BMO_slot_map_float_get(BMOpSlot *slot, const void *element) BLI_INLINE int BMO_slot_map_int_get(BMOpSlot *slot, const void *element) { - int *val = (int *) BMO_slot_map_data_get(slot, element); + int *val; + BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_INT); + + val = (int *) BMO_slot_map_data_get(slot, element); + if (val) return *val; + + return 0; +} + +BLI_INLINE int BMO_slot_map_bool_get(BMOpSlot *slot, const void *element) +{ + int *val; + BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_BOOL); + + val = (int *) BMO_slot_map_data_get(slot, element); + BLI_assert(val == NULL || *val == FALSE || *val == TRUE); if (val) return *val; return 0; } -BLI_INLINE void *BMO_slot_map_ptr_get(BMOpSlot *slot, const void *element) +BLI_INLINE void *BMO_slot_map_ptr_get_(BMOpSlot *slot, const void *element) +{ + void **val = (void **) BMO_slot_map_data_get(slot, element); + BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL); + if (val) return *val; + + return NULL; +} + +BLI_INLINE void *BMO_slot_map_elem_get(BMOpSlot *slot, const void *element) { void **val = (void **) BMO_slot_map_data_get(slot, element); + BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_ELEM); if (val) return *val; return NULL; diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 7fd9bcf1951..fd26ac16224 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -131,8 +131,9 @@ static void bmo_op_slots_init(const BMOSlotType *slot_types, BMOpSlot *slot_args { unsigned int i; for (i = 0; slot_types[i].type; i++) { - slot_args[i].slot_name = slot_types[i].name; - slot_args[i].slot_type = slot_types[i].type; + slot_args[i].slot_name = slot_types[i].name; + slot_args[i].slot_type = slot_types[i].type; + slot_args[i].slot_subtype = slot_types[i].subtype; // slot_args[i].index = i; // UNUSED } } @@ -610,6 +611,9 @@ void BMO_slot_map_insert(BMOperator *op, BMOpSlot *slot, if (!slot->data.ghash) { slot->data.ghash = BLI_ghash_ptr_new("bmesh slot map hash"); } + else { + BLI_assert(slot->data.ghash); + } BLI_ghash_insert(slot->data.ghash, (void *)element, mapping); } diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c index c4f6c821320..591c758fbb2 100644 --- a/source/blender/bmesh/operators/bmo_dupe.c +++ b/source/blender/bmesh/operators/bmo_dupe.c @@ -104,8 +104,7 @@ static BMEdge *copy_edge(BMOperator *op, if (rlen < 2) { /* not sure what non-manifold cases of greater then three * radial should do. */ - BMO_slot_map_ptr_insert(op, slot_boundarymap_out, - source_edge, target_edge); + BMO_slot_map_elem_insert(op, slot_boundarymap_out, source_edge, target_edge); } /* Insert new edge into the edge hash */ @@ -158,8 +157,8 @@ static BMFace *copy_face(BMOperator *op, /* create new face */ target_face = BM_face_create(target_mesh, vtar, edar, source_face->len, FALSE); - BMO_slot_map_ptr_insert(op, slot_facemap_out, source_face, target_face); - BMO_slot_map_ptr_insert(op, slot_facemap_out, target_face, source_face); + BMO_slot_map_elem_insert(op, slot_facemap_out, source_face, target_face); + BMO_slot_map_elem_insert(op, slot_facemap_out, target_face, source_face); BM_elem_attrs_copy(source_mesh, target_mesh, source_face, target_face); @@ -235,7 +234,7 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst) } if (isolated) { - BMO_slot_map_ptr_insert(op, slot_isovertmap_out, v, v2); + BMO_slot_map_elem_insert(op, slot_isovertmap_out, v, v2); } BMO_elem_flag_enable(bm_src, v, DUPE_DONE); diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c index 6a9d9c1e48b..25ebf32b25a 100644 --- a/source/blender/bmesh/operators/bmo_extrude.c +++ b/source/blender/bmesh/operators/bmo_extrude.c @@ -354,7 +354,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) slot_facemap_out = BMO_slot_get(dupeop.slots_out, "facemap.out"); if (bm->act_face && BMO_elem_flag_test(bm, bm->act_face, EXT_INPUT)) { - bm->act_face = BMO_slot_map_ptr_get(slot_facemap_out, bm->act_face); + bm->act_face = BMO_slot_map_elem_get(slot_facemap_out, bm->act_face); } if (delorig) { diff --git a/source/blender/bmesh/operators/bmo_mirror.c b/source/blender/bmesh/operators/bmo_mirror.c index 01bce976ec0..6435f44f1d6 100644 --- a/source/blender/bmesh/operators/bmo_mirror.c +++ b/source/blender/bmesh/operators/bmo_mirror.c @@ -92,7 +92,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op) v = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); for (i = 0; i < ototvert; i++) { if (fabsf(v->co[axis]) <= dist) { - BMO_slot_map_ptr_insert(&weldop, slot_targetmap, vmap[i], v); + BMO_slot_map_elem_insert(&weldop, slot_targetmap, vmap[i], v); } v = BM_iter_step(&iter); } diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c index 45e678b96bb..06d11c7b19d 100644 --- a/source/blender/bmesh/operators/bmo_removedoubles.c +++ b/source/blender/bmesh/operators/bmo_removedoubles.c @@ -44,7 +44,7 @@ static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op, BMOpSlot int split = FALSE; BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - v2 = BMO_slot_map_ptr_get(slot_targetmap, l->v); + v2 = BMO_slot_map_elem_get(slot_targetmap, l->v); /* ok: if v2 is NULL (e.g. not in the map) then it's * a target vert, otherwise it's a double */ if ((v2 && BM_vert_in_face(f, v2)) && @@ -110,7 +110,7 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op) /* mark merge verts for deletion */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - if ((v2 = BMO_slot_map_ptr_get(slot_targetmap, v))) { + if ((v2 = BMO_slot_map_elem_get(slot_targetmap, v))) { BMO_elem_flag_enable(bm, v, ELE_DEL); /* merge the vertex flags, else we get randomly selected/unselected verts */ @@ -126,8 +126,8 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op) BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { if (BMO_elem_flag_test(bm, e->v1, ELE_DEL) || BMO_elem_flag_test(bm, e->v2, ELE_DEL)) { - v = BMO_slot_map_ptr_get(slot_targetmap, e->v1); - v2 = BMO_slot_map_ptr_get(slot_targetmap, e->v2); + v = BMO_slot_map_elem_get(slot_targetmap, e->v1); + v2 = BMO_slot_map_elem_get(slot_targetmap, e->v2); if (!v) v = e->v1; if (!v2) v2 = e->v2; @@ -175,10 +175,10 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op) v = l->v; v2 = l->next->v; if (BMO_elem_flag_test(bm, v, ELE_DEL)) { - v = BMO_slot_map_ptr_get(slot_targetmap, v); + v = BMO_slot_map_elem_get(slot_targetmap, v); } if (BMO_elem_flag_test(bm, v2, ELE_DEL)) { - v2 = BMO_slot_map_ptr_get(slot_targetmap, v2); + v2 = BMO_slot_map_elem_get(slot_targetmap, v2); } e2 = v != v2 ? BM_edge_exists(v, v2) : NULL; @@ -208,10 +208,10 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op) v2 = loops[1]->v; if (BMO_elem_flag_test(bm, v, ELE_DEL)) { - v = BMO_slot_map_ptr_get(slot_targetmap, v); + v = BMO_slot_map_elem_get(slot_targetmap, v); } if (BMO_elem_flag_test(bm, v2, ELE_DEL)) { - v2 = BMO_slot_map_ptr_get(slot_targetmap, v2); + v2 = BMO_slot_map_elem_get(slot_targetmap, v2); } f2 = BM_face_create_ngon(bm, v, v2, edges, a, TRUE); @@ -360,7 +360,7 @@ void bmo_pointmerge_exec(BMesh *bm, BMOperator *op) copy_v3_v3(snapv->co, vec); } else { - BMO_slot_map_ptr_insert(&weldop, slot_targetmap, v, snapv); + BMO_slot_map_elem_insert(&weldop, slot_targetmap, v, snapv); } } @@ -414,9 +414,9 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op) copy_v3_v3(edges[i]->v2->co, center); if (edges[i]->v1 != edges[0]->v1) - BMO_slot_map_ptr_insert(&weldop, slot_targetmap, edges[i]->v1, edges[0]->v1); + BMO_slot_map_elem_insert(&weldop, slot_targetmap, edges[i]->v1, edges[0]->v1); if (edges[i]->v2 != edges[0]->v1) - BMO_slot_map_ptr_insert(&weldop, slot_targetmap, edges[i]->v2, edges[0]->v1); + BMO_slot_map_elem_insert(&weldop, slot_targetmap, edges[i]->v2, edges[0]->v1); } } @@ -554,7 +554,7 @@ static void bmesh_find_doubles_common(BMesh *bm, BMOperator *op, BMO_elem_flag_enable(bm, v_other, VERT_DOUBLE); BMO_elem_flag_enable(bm, v_check, VERT_TARGET); - BMO_slot_map_ptr_insert(optarget, optarget_slot, v_other, v_check); + BMO_slot_map_elem_insert(optarget, optarget_slot, v_other, v_check); } } } diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c index 775fa0cb60d..46f08d8ead7 100644 --- a/source/blender/bmesh/operators/bmo_triangulate.c +++ b/source/blender/bmesh/operators/bmo_triangulate.c @@ -65,9 +65,9 @@ void bmo_triangulate_exec(BMesh *bm, BMOperator *op) BM_face_triangulate(bm, face, projectverts, EDGE_NEW, FACE_NEW, newfaces, use_beauty); - BMO_slot_map_ptr_insert(op, slot_facemap_out, face, face); + BMO_slot_map_elem_insert(op, slot_facemap_out, face, face); for (i = 0; newfaces[i]; i++) { - BMO_slot_map_ptr_insert(op, slot_facemap_out, newfaces[i], face); + BMO_slot_map_elem_insert(op, slot_facemap_out, newfaces[i], face); } } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 9bc926598db..507b93d959f 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -354,21 +354,21 @@ static short edbm_extrude_edge(Object *obedit, BMEditMesh *em, const char hflag, if ((fabsf(co1[0]) < mmd->tolerance) && (fabsf(co2[0]) < mmd->tolerance)) { - BMO_slot_map_ptr_insert(&extop, slot_edges_exclude, edge, NULL); + BMO_slot_map_empty_insert(&extop, slot_edges_exclude, edge); } } if (mmd->flag & MOD_MIR_AXIS_Y) { if ((fabsf(co1[1]) < mmd->tolerance) && (fabsf(co2[1]) < mmd->tolerance)) { - BMO_slot_map_ptr_insert(&extop, slot_edges_exclude, edge, NULL); + BMO_slot_map_empty_insert(&extop, slot_edges_exclude, edge); } } if (mmd->flag & MOD_MIR_AXIS_Z) { if ((fabsf(co1[2]) < mmd->tolerance) && (fabsf(co2[2]) < mmd->tolerance)) { - BMO_slot_map_ptr_insert(&extop, slot_edges_exclude, edge, NULL); + BMO_slot_map_empty_insert(&extop, slot_edges_exclude, edge); } } } diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index d4463098f07..3ca2c364345 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -274,10 +274,10 @@ static void bm_merge_dm_transform(BMesh *bm, DerivedMesh *dm, float mat[4][4], v2 = BMO_iter_map_value_p(&oiter); /* check in case the target vertex (v2) is already marked * for merging */ - while ((v3 = BMO_slot_map_ptr_get(slot_targetmap, v2))) { + while ((v3 = BMO_slot_map_elem_get(slot_targetmap, v2))) { v2 = v3; } - BMO_slot_map_ptr_insert(weld_op, slot_targetmap, v, v2); + BMO_slot_map_elem_insert(weld_op, slot_targetmap, v, v2); } BMO_op_finish(bm, &find_op); @@ -319,7 +319,7 @@ static void merge_first_last(BMesh *bm, slot_targetmap = BMO_slot_get(weld_op->slots_in, "targetmap"); BMO_ITER (v, &oiter, find_op.slots_out, "targetmap.out", 0) { v2 = BMO_iter_map_value_p(&oiter); - BMO_slot_map_ptr_insert(weld_op, slot_targetmap, v, v2); + BMO_slot_map_elem_insert(weld_op, slot_targetmap, v, v2); } BMO_op_finish(bm, &find_op); @@ -494,11 +494,11 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, /* check in case the target vertex (v2) is already marked * for merging */ - while ((v3 = BMO_slot_map_ptr_get(slot_targetmap, v2))) { + while ((v3 = BMO_slot_map_elem_get(slot_targetmap, v2))) { v2 = v3; } - BMO_slot_map_ptr_insert(&weld_op, slot_targetmap, v, v2); + BMO_slot_map_elem_insert(&weld_op, slot_targetmap, v, v2); } #undef _E diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index 9f702957fa5..a37835e11dc 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -1093,7 +1093,7 @@ static BMFace *collapse_face_corners(BMesh *bm, BMFace *f, int n, v_safe = shortest_edge->v1; v_merge = shortest_edge->v2; mid_v3_v3v3(v_safe->co, v_safe->co, v_merge->co); - BMO_slot_map_ptr_insert(&op, slot_targetmap, v_merge, v_safe); + BMO_slot_map_elem_insert(&op, slot_targetmap, v_merge, v_safe); BMO_op_exec(bm, &op); BMO_op_finish(bm, &op); @@ -1287,8 +1287,7 @@ static void skin_fix_hole_no_good_verts(BMesh *bm, Frame *frame, BMFace *split_f "weld_verts"); slot_targetmap = BMO_slot_get(op.slots_in, "targetmap"); for (i = 0; i < 4; i++) { - BMO_slot_map_ptr_insert(&op, slot_targetmap, - verts[i], frame->verts[best_order[i]]); + BMO_slot_map_elem_insert(&op, slot_targetmap, verts[i], frame->verts[best_order[i]]); } BMO_op_exec(bm, &op); BMO_op_finish(bm, &op); -- cgit v1.2.3 From e77e1f183ae6732eadda82ba1d7ab9975a9224f8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 Nov 2012 03:47:20 +0000 Subject: fix for uninitialized memory use with numeric input: bevel/inset/marker-move would use uninitialized memory when used as modal operators and pressing backspace after entering values. --- .../bmesh/intern/bmesh_operator_api_inline.h | 2 +- source/blender/editors/animation/anim_markers.c | 21 +++++++++++++-------- source/blender/editors/mesh/editmesh_loopcut.c | 2 +- source/blender/editors/mesh/editmesh_tools.c | 8 ++++---- source/blender/editors/util/numinput.c | 3 +++ 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_operator_api_inline.h b/source/blender/bmesh/intern/bmesh_operator_api_inline.h index 1f6e44e9320..acbc765f0df 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api_inline.h +++ b/source/blender/bmesh/intern/bmesh_operator_api_inline.h @@ -185,7 +185,7 @@ BLI_INLINE int BMO_slot_map_bool_get(BMOpSlot *slot, const void *element) return 0; } -BLI_INLINE void *BMO_slot_map_ptr_get_(BMOpSlot *slot, const void *element) +BLI_INLINE void *BMO_slot_map_ptr_get(BMOpSlot *slot, const void *element) { void **val = (void **) BMO_slot_map_data_get(slot, element); BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL); diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index 4ac7b61fccb..d595034032e 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -860,16 +860,21 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt) } if (evt->val == KM_PRESS) { - float vec; - char str_tx[NUM_STR_REP_LEN]; - if (handleNumInput(&mm->num, evt)) { - applyNumInput(&mm->num, &vec); - outputNumInput(&mm->num, str_tx); - - RNA_int_set(op->ptr, "frames", vec); + char str_tx[NUM_STR_REP_LEN]; + float value = RNA_int_get(op->ptr, "frames"); + applyNumInput(&mm->num, &value); + + if (hasNumInput(&mm->num)) { + outputNumInput(&mm->num, str_tx); + } + else { + BLI_snprintf(str_tx, sizeof(str_tx), "%d", (int)value); + } + + RNA_int_set(op->ptr, "frames", value); ed_marker_move_apply(C, op); - // ed_marker_header_update(C, op, str, (int)vec[0]); + // ed_marker_header_update(C, op, str, (int)value); // strcat(str, str_tx); BLI_snprintf(str, sizeof(str), "Marker offset %s", str_tx); ED_area_headerprint(CTX_wm_area(C), str); diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index f951073155d..fcfb12a09bf 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -552,9 +552,9 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event) /* using the keyboard to input the number of cuts */ if (event->val == KM_PRESS) { /* init as zero so backspace clears */ - float value = 0.0f; if (handleNumInput(&lcd->num, event)) { + float value = RNA_int_get(op->ptr, "number_cuts"); applyNumInput(&lcd->num, &value); /* allow zero so you can backspace and type in a value diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 507b93d959f..9dd7c1c5bdf 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -4973,9 +4973,9 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) if (event->val == KM_PRESS) { /* Try to handle numeric inputs... */ #ifdef NEW_BEVEL - float value; if (handleNumInput(&opdata->num_input, event)) { + float value = RNA_float_get(op->ptr, "offset"); applyNumInput(&opdata->num_input, &value); RNA_float_set(op->ptr, "offset", value); edbm_bevel_calc(C, op); @@ -4983,9 +4983,8 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_RUNNING_MODAL; } #else - float factor; - if (handleNumInput(&opdata->num_input, event)) { + float factor = RNA_float_get(op->ptr, "percent"); applyNumInput(&opdata->num_input, &factor); CLAMP(factor, 0.0f, 1.0f); RNA_float_set(op->ptr, "percent", factor); @@ -5365,9 +5364,10 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) if (event->val == KM_PRESS) { /* Try to handle numeric inputs... */ - float amounts[2]; if (handleNumInput(&opdata->num_input, event)) { + float amounts[2] = {RNA_float_get(op->ptr, "thickness"), + RNA_float_get(op->ptr, "depth")}; applyNumInput(&opdata->num_input, amounts); amounts[0] = max_ff(amounts[0], 0.0f); RNA_float_set(op->ptr, "thickness", amounts[0]); diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index b73f5fa0869..0ec16ead35d 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -130,6 +130,9 @@ short hasNumInput(NumInput *n) return 0; } +/** + * \warning \a vec must be set beforehand otherwise we risk uninitialized vars. + */ void applyNumInput(NumInput *n, float *vec) { short i, j; -- cgit v1.2.3 From 6857d3118063caca392e1dd4034bca24e2f125cb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 Nov 2012 04:58:33 +0000 Subject: fix [#33305] Bevel tool crashes Blender if the number of segments exceeds 28 this was infact a general bug in BLI_array_grow_items(), surprising we didnt run into it before. - growing the array for the first time would use the static var even if it wasn't big enough. --- source/blender/blenlib/BLI_array.h | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h index 84cfe89f1b8..a21778307c1 100644 --- a/source/blender/blenlib/BLI_array.h +++ b/source/blender/blenlib/BLI_array.h @@ -77,11 +77,13 @@ MEM_allocN_len(arr) / sizeof(*arr) \ ) +#define _bli_array_totalsize_static(arr) \ + (sizeof(_##arr##_static) / sizeof(*arr)) #define BLI_array_totalsize(arr) ( \ (size_t) \ (((void *)(arr) == (void *)_##arr##_static && (void *)(arr) != NULL) ? \ - (sizeof(_##arr##_static) / sizeof(*arr)) : \ + _bli_array_totalsize_static(arr) : \ BLI_array_totalsize_dyn(arr)) \ ) @@ -93,8 +95,18 @@ * * Allow for a large 'num' value when the new size is more then double * to allocate the exact sized array. */ -#define _bli_array_grow_items(arr, num) ( \ - (BLI_array_totalsize(arr) >= _##arr##_count + num) ? \ + +/* grow an array by a specified number of items */ +#define BLI_array_grow_items(arr, num) ( \ + (((void *)(arr) == NULL) && \ + ((void *)(_##arr##_static) != NULL) && \ + /* dont add _##arr##_count below because it must be zero */ \ + (_bli_array_totalsize_static(arr) >= _##arr##_count + num)) ? \ + /* we have an empty array and a static var big enough */ \ + ((arr = (void *)_##arr##_static), (_##arr##_count += (num))) \ + : \ + /* use existing static array or allocate */ \ + ((BLI_array_totalsize(arr) >= _##arr##_count + num) ? \ (_##arr##_count += num) : \ ( \ (void) (_##arr##_tmp = MEM_callocN( \ @@ -115,14 +127,7 @@ (void) (arr = _##arr##_tmp \ ), \ (_##arr##_count += num) \ - ) \ -) - -/* grow an array by a specified number of items */ -#define BLI_array_grow_items(arr, num) ( \ - ((void *)(arr) == NULL && (void *)(_##arr##_static) != NULL) ? \ - ((arr = (void *)_##arr##_static), (_##arr##_count += num)) : \ - _bli_array_grow_items(arr, num) \ + )) \ ) /* returns length of array */ -- cgit v1.2.3 From e1dc4201934c94b5e6d5f23655a555afba77bc5c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 Nov 2012 05:06:33 +0000 Subject: use slightly more efficient BLI_array_fixedstack_declare() instead of BLI_array_staticdeclare() for bevel code since the array size is known. --- source/blender/bmesh/tools/bmesh_bevel.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 75e74155f66..7e5eb02fa03 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -264,14 +264,13 @@ static BMFace *bev_create_ngon(BMesh *bm, BMVert **vert_arr, const int totv, BMF else { int i; BMEdge **ee = NULL; - BLI_array_staticdeclare(ee, BM_DEFAULT_NGON_STACK_SIZE); + BLI_array_fixedstack_declare(ee, BM_DEFAULT_NGON_STACK_SIZE, totv, __func__); - BLI_array_grow_items(ee, totv); for (i = 0; i < totv; i++) { ee[i] = BM_edge_create(bm, vert_arr[i], vert_arr[(i + 1) % totv], NULL, TRUE); } f = BM_face_create_ngon(bm, vert_arr[0], vert_arr[1], ee, totv, FALSE); - BLI_array_free(ee); + BLI_array_fixedstack_free(ee); } if (facerep && f) { int has_mdisps = CustomData_has_layer(&bm->ldata, CD_MDISPS); -- cgit v1.2.3 From 7ecf0542956523391ea94084664fdf5c8365aa3b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 26 Nov 2012 06:59:50 +0000 Subject: Bevel: allow page up / page down shortcuts for segments in addition to mousewheel. --- source/blender/editors/mesh/editmesh_tools.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 9dd7c1c5bdf..e6bd0b4a12b 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -5025,6 +5025,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) #ifdef NEW_BEVEL case WHEELUPMOUSE: /* change number of segments */ + case PAGEUPKEY: if (event->val == KM_RELEASE) break; @@ -5035,6 +5036,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) break; case WHEELDOWNMOUSE: /* change number of segments */ + case PAGEDOWNKEY: if (event->val == KM_RELEASE) break; -- cgit v1.2.3 From cf2c459325a31b4a40f7abb24dc16c67016d75ad Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 26 Nov 2012 06:59:59 +0000 Subject: Fix #33285: loop cut is not supposed to cut through triangles/ngons, but it still happened when the loop would go all the way around the mesh with just one triangle/ngon inbetween to close the loop. --- source/blender/bmesh/intern/bmesh_opdefines.c | 1 + source/blender/bmesh/intern/bmesh_operators.h | 1 + source/blender/bmesh/intern/bmesh_queries.c | 23 +++++++++++++++++++++++ source/blender/bmesh/intern/bmesh_queries.h | 1 + source/blender/bmesh/operators/bmo_subdivide.c | 10 +++++++++- source/blender/editors/mesh/editmesh_loopcut.c | 12 +++++++++++- source/blender/editors/mesh/editmesh_tools.c | 2 +- 7 files changed, 47 insertions(+), 3 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 8076fc00a44..d8f29c082a4 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -911,6 +911,7 @@ static BMOpDefine bmo_subdivide_edges_def = { {"quad_corner_type", BMO_OP_SLOT_INT}, /* quad corner type, see bmesh_operators.h */ {"use_gridfill", BMO_OP_SLOT_BOOL}, /* fill in fully-selected faces with a grid */ {"use_singleedge", BMO_OP_SLOT_BOOL}, /* tessellate the case of one edge selected in a quad or triangle */ + {"use_onlyquads", BMO_OP_SLOT_BOOL}, /* only subdivide quads (for loopcut) */ {"use_sphere", BMO_OP_SLOT_BOOL}, /* for making new primitives only */ {{'\0'}}, }, diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h index 03363ed765a..9a89e2bc996 100644 --- a/source/blender/bmesh/intern/bmesh_operators.h +++ b/source/blender/bmesh/intern/bmesh_operators.h @@ -98,6 +98,7 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag, int numcuts, int seltype, int cornertype, const short use_singleedge, const short use_gridfill, + const short use_onlyquads, int seed); #include "intern/bmesh_operator_api_inline.h" diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index ec2e90591cc..195c60c5a9c 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -823,6 +823,29 @@ int BM_edge_share_face_check(BMEdge *e1, BMEdge *e2) return FALSE; } +/** + * Test if e1 shares any quad faces with e2 + */ +int BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2) +{ + BMLoop *l; + BMFace *f; + + if (e1->l && e2->l) { + l = e1->l; + do { + f = l->f; + if (f->len == 4) { + if (bmesh_radial_face_find(e2, f)) { + return TRUE; + } + } + l = l->radial_next; + } while (l != e1->l); + } + return FALSE; +} + /** * Tests to see if e1 shares a vertex with e2 */ diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index d97faebf021..7a18f69371e 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -90,6 +90,7 @@ int BM_face_share_edge_count(BMFace *f1, BMFace *f2); int BM_face_share_face_check(BMFace *f1, BMFace *f2); int BM_face_share_edge_check(BMFace *f1, BMFace *f2); int BM_edge_share_face_check(BMEdge *e1, BMEdge *e2); +int BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2); int BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2); BMVert *BM_edge_share_vert(BMEdge *e1, BMEdge *e2); diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index f9b6611c88b..74972da8888 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -715,7 +715,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) BMFace *face; BLI_array_declare(verts); float smooth, fractal, along_normal; - int use_sphere, cornertype, use_singleedge, use_gridfill; + int use_sphere, cornertype, use_singleedge, use_gridfill, use_onlyquads; int skey, seed, i, j, matched, a, b, numcuts, totesel; BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, SUBD_SPLIT); @@ -729,6 +729,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) use_singleedge = BMO_slot_bool_get(op->slots_in, "use_singleedge"); use_gridfill = BMO_slot_bool_get(op->slots_in, "use_gridfill"); + use_onlyquads = BMO_slot_bool_get(op->slots_in, "use_onlyquads"); use_sphere = BMO_slot_bool_get(op->slots_in, "use_sphere"); BLI_srandom(seed); @@ -804,6 +805,10 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) BMEdge *e1 = NULL, *e2 = NULL; float vec1[3], vec2[3]; + /* skip non-quads if requested */ + if(use_onlyquads && face->len != 4) + continue; + /* figure out which pattern to use */ BLI_array_empty(edges); @@ -1089,6 +1094,7 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag, int numcuts, int seltype, int cornertype, const short use_singleedge, const short use_gridfill, + const short use_onlyquads, int seed) { BMOperator op; @@ -1100,12 +1106,14 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag, "cuts=%i " "quad_corner_type=%i " "use_singleedge=%b use_gridfill=%b " + "use_onlyquads=%b " "seed=%i", edge_hflag, smooth, fractal, along_normal, numcuts, cornertype, use_singleedge, use_gridfill, + use_onlyquads, seed); BMO_op_exec(bm, &op); diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index fcfb12a09bf..3920d684243 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -261,7 +261,11 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, int select) lasteed = eed; } +#ifdef BMW_EDGERING_NGON if (lasteed != startedge && BM_edge_share_face_check(lasteed, startedge)) { +#else + if (lasteed != startedge && BM_edge_share_quad_check(lasteed, startedge)) { +#endif v[1][0] = v[0][0]; v[1][1] = v[0][1]; @@ -309,6 +313,11 @@ static void ringsel_finish(bContext *C, wmOperator *op) RingSelOpData *lcd = op->customdata; const int cuts = RNA_int_get(op->ptr, "number_cuts"); const float smoothness = 0.292f * RNA_float_get(op->ptr, "smoothness"); +#ifdef BMW_EDGERING_NGON + const int use_onlyquads = FALSE; +#else + const int use_onlyquads = TRUE; +#endif if (lcd->eed) { BMEditMesh *em = lcd->em; @@ -322,7 +331,8 @@ static void ringsel_finish(bContext *C, wmOperator *op) BM_mesh_esubdivide(em->bm, BM_ELEM_SELECT, smoothness, 0.0f, 0.0f, cuts, - SUBDIV_SELECT_LOOPCUT, SUBD_PATH, 0, TRUE, 0); + SUBDIV_SELECT_LOOPCUT, SUBD_PATH, 0, TRUE, + use_onlyquads, 0); /* force edge slide to edge select mode in in face select mode */ if (em->selectmode & SCE_SELECT_FACE) { diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index e6bd0b4a12b..335f2a8c829 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -109,7 +109,7 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op) smooth, fractal, along_normal, cuts, SUBDIV_SELECT_ORIG, RNA_enum_get(op->ptr, "quadcorner"), - RNA_boolean_get(op->ptr, "quadtri"), TRUE, + RNA_boolean_get(op->ptr, "quadtri"), TRUE, FALSE, RNA_int_get(op->ptr, "seed")); EDBM_update_generic(C, em, TRUE); -- cgit v1.2.3 From 9784f3d466e80f442c8d922b971b6b2937c8cbd6 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 26 Nov 2012 08:00:15 +0000 Subject: Fix #33292: cycles material draw mode selection not working on some cards, now skip glsl for picking as was already done for other GLSL drawing. --- source/blender/editors/space_view3d/drawmesh.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index f35a844afc9..0ecde350b00 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -51,6 +51,7 @@ #include "BKE_DerivedMesh.h" #include "BKE_effect.h" +#include "BKE_global.h" #include "BKE_image.h" #include "BKE_material.h" #include "BKE_paint.h" @@ -965,7 +966,7 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Mesh *me = ob->data; TexMatCallback data = {scene, ob, me, dm}; int (*set_face_cb)(void *, int); - int glsl; + int glsl, picking = (G.f & G_PICKSEL); /* face hiding callback depending on mode */ if (ob == scene->obedit) @@ -976,11 +977,11 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, set_face_cb = NULL; /* test if we can use glsl */ - glsl = (v3d->drawtype == OB_MATERIAL) && GPU_glsl_support(); + glsl = (v3d->drawtype == OB_MATERIAL) && GPU_glsl_support() && !picking; GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL); - if (glsl) { + if (glsl || picking) { /* draw glsl */ dm->drawMappedFacesMat(dm, tex_mat_set_material_cb, -- cgit v1.2.3 From 42c54bcd9362922bed70d596568c7495fa6334bb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 Nov 2012 08:44:37 +0000 Subject: py/bmesh api - support for converting from/to BMO_OP_SLOT_MAPPING type. --- source/blender/bmesh/intern/bmesh_operator_api.h | 5 +- .../bmesh/intern/bmesh_operator_api_inline.h | 6 +- source/blender/bmesh/intern/bmesh_operators.c | 8 +- source/blender/python/bmesh/bmesh_py_ops.c | 280 +++++++++++++++++++-- source/blender/python/bmesh/bmesh_py_types.c | 3 +- source/blender/python/bmesh/bmesh_py_types.h | 2 + 6 files changed, 281 insertions(+), 23 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h index efc2f6a492e..e84883540d6 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api.h +++ b/source/blender/bmesh/intern/bmesh_operator_api.h @@ -414,7 +414,7 @@ int BMO_slot_buffer_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot int BMO_slot_map_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name); void BMO_slot_map_insert(BMOperator *op, BMOpSlot *slot, - const void *element, void *data, int len); + const void *element, const void *data, const int len); /* Counts the number of edges with tool flag toolflag around */ @@ -502,6 +502,9 @@ typedef struct BMOElemMapping { int len; } BMOElemMapping; +/* pointer after BMOElemMapping */ +#define BMO_OP_SLOT_MAPPING_DATA(var) (void *)(((BMOElemMapping *)var) + 1) + extern const int BMO_OPSLOT_TYPEINFO[BMO_OP_SLOT_TOTAL_TYPES]; #ifdef __cplusplus diff --git a/source/blender/bmesh/intern/bmesh_operator_api_inline.h b/source/blender/bmesh/intern/bmesh_operator_api_inline.h index acbc765f0df..4143c4d0883 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api_inline.h +++ b/source/blender/bmesh/intern/bmesh_operator_api_inline.h @@ -70,14 +70,14 @@ BLI_INLINE void _bmo_elem_flag_toggle(BMesh *bm, BMFlagLayer *oflags, const shor } BLI_INLINE void BMO_slot_map_int_insert(BMOperator *op, BMOpSlot *slot, - void *element, int val) + void *element, const int val) { BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_INT); BMO_slot_map_insert(op, slot, element, &val, sizeof(int)); } BLI_INLINE void BMO_slot_map_bool_insert(BMOperator *op, BMOpSlot *slot, - void *element, int val) + void *element, const int val) { BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_BOOL); BLI_assert(val == FALSE || val == TRUE); @@ -85,7 +85,7 @@ BLI_INLINE void BMO_slot_map_bool_insert(BMOperator *op, BMOpSlot *slot, } BLI_INLINE void BMO_slot_map_float_insert(BMOperator *op, BMOpSlot *slot, - void *element, float val) + void *element, const float val) { BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_FLOAT); BMO_slot_map_insert(op, slot, element, &val, sizeof(float)); diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index fd26ac16224..83fd338ef1f 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -314,7 +314,7 @@ void _bmo_slot_copy(BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS], const char *slot_n dstmap->element = srcmap->element; dstmap->len = srcmap->len; - memcpy(dstmap + 1, srcmap + 1, srcmap->len); + memcpy(BMO_OP_SLOT_MAPPING_DATA(dstmap), BMO_OP_SLOT_MAPPING_DATA(srcmap), srcmap->len); BLI_ghash_insert(slot_dst->data.ghash, dstmap->element, dstmap); } @@ -596,7 +596,7 @@ int BMO_slot_map_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_na * value, it doesn't store a reference to it. */ void BMO_slot_map_insert(BMOperator *op, BMOpSlot *slot, - const void *element, void *data, int len) + const void *element, const void *data, const int len) { BMOElemMapping *mapping; BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING); @@ -606,7 +606,7 @@ void BMO_slot_map_insert(BMOperator *op, BMOpSlot *slot, mapping->element = (BMHeader *) element; mapping->len = len; - memcpy(mapping + 1, data, len); + memcpy(BMO_OP_SLOT_MAPPING_DATA(mapping), data, len); if (!slot->data.ghash) { slot->data.ghash = BLI_ghash_ptr_new("bmesh slot map hash"); @@ -1279,7 +1279,7 @@ void *BMO_iter_step(BMOIter *iter) void *ret = BLI_ghashIterator_getKey(&iter->giter); map = BLI_ghashIterator_getValue(&iter->giter); - iter->val = map + 1; + iter->val = BMO_OP_SLOT_MAPPING_DATA(map); BLI_ghashIterator_step(&iter->giter); diff --git a/source/blender/python/bmesh/bmesh_py_ops.c b/source/blender/python/bmesh/bmesh_py_ops.c index 5ab8b7c0e26..84b06504d2e 100644 --- a/source/blender/python/bmesh/bmesh_py_ops.c +++ b/source/blender/python/bmesh/bmesh_py_ops.c @@ -305,6 +305,179 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject * break; } + case BMO_OP_SLOT_MAPPING: + { + /* first check types */ + if (slot->slot_subtype != BMO_OP_SLOT_SUBTYPE_MAP_EMPTY) { + if (!PyDict_Check(value)) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a dict, not %.200s", + self->opname, slot_name, Py_TYPE(value)->tp_name); + return NULL; + } + } + else { + if (!PySet_Check(value)) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a set, not %.200s", + self->opname, slot_name, Py_TYPE(value)->tp_name); + return NULL; + } + } + + switch (slot->slot_subtype) { + + /* this could be a static function */ +#define BPY_BM_MAPPING_KEY_CHECK(arg_key) \ + if (!BPy_BMElem_Check(arg_key)) { \ + PyErr_Format(PyExc_TypeError, \ + "%.200s: keyword \"%.200s\" expected " \ + "a dict with bmesh element keys, not %.200s", \ + self->opname, slot_name, Py_TYPE(arg_key)->tp_name); \ + return NULL; \ + } \ + else if (((BPy_BMGeneric *)arg_key)->bm == NULL) { \ + PyErr_Format(PyExc_TypeError, \ + "%.200s: keyword \"%.200s\" invalidated element key in dict", \ + self->opname, slot_name); \ + return NULL; \ + } (void)0 + + + case BMO_OP_SLOT_SUBTYPE_MAP_ELEM: + { + if (PyDict_Size(value) > 0) { + PyObject *arg_key, *arg_value; + Py_ssize_t arg_pos = 0; + while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { + /* TODO, check the elements come from the right mesh? */ + BPY_BM_MAPPING_KEY_CHECK(arg_key); + + if (!BPy_BMElem_Check(arg_value)) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a dict with bmesh element values, not %.200s", + self->opname, slot_name, Py_TYPE(arg_value)->tp_name); + return NULL; + } + else if (((BPy_BMGeneric *)arg_value)->bm == NULL) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" invalidated element value in dict", + self->opname, slot_name); + return NULL; + } + + BMO_slot_map_elem_insert(&bmop, slot, + ((BPy_BMElem *)arg_key)->ele, ((BPy_BMElem *)arg_value)->ele); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_FLOAT: + { + if (PyDict_Size(value) > 0) { + PyObject *arg_key, *arg_value; + Py_ssize_t arg_pos = 0; + while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { + float value_f; + /* TODO, check the elements come from the right mesh? */ + BPY_BM_MAPPING_KEY_CHECK(arg_key); + value_f = PyFloat_AsDouble(arg_value); + + if (value_f == -1.0f && PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a dict with float values, not %.200s", + self->opname, slot_name, Py_TYPE(arg_value)->tp_name); + return NULL; + } + + BMO_slot_map_float_insert(&bmop, slot, + ((BPy_BMElem *)arg_key)->ele, value_f); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_INT: + { + if (PyDict_Size(value) > 0) { + PyObject *arg_key, *arg_value; + Py_ssize_t arg_pos = 0; + while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { + int value_i; + /* TODO, check the elements come from the right mesh? */ + BPY_BM_MAPPING_KEY_CHECK(arg_key); + value_i = PyLong_AsLong(arg_value); + + if (value_i == -1 && PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a dict with int values, not %.200s", + self->opname, slot_name, Py_TYPE(arg_value)->tp_name); + return NULL; + } + + BMO_slot_map_int_insert(&bmop, slot, + ((BPy_BMElem *)arg_key)->ele, value_i); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_BOOL: + { + if (PyDict_Size(value) > 0) { + PyObject *arg_key, *arg_value; + Py_ssize_t arg_pos = 0; + while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { + int value_i; + /* TODO, check the elements come from the right mesh? */ + BPY_BM_MAPPING_KEY_CHECK(arg_key); + value_i = PyLong_AsLong(arg_value); + + if (value_i == -1 && PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a dict with bool values, not %.200s", + self->opname, slot_name, Py_TYPE(arg_value)->tp_name); + return NULL; + } + + BMO_slot_map_bool_insert(&bmop, slot, + ((BPy_BMElem *)arg_key)->ele, value_i != 0); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_EMPTY: + { + if (PySet_Size(value) > 0) { + PyObject *arg_key; + Py_ssize_t arg_pos = 0; + Py_ssize_t arg_hash = 0; + while (_PySet_NextEntry(value, &arg_pos, &arg_key, &arg_hash)) { + /* TODO, check the elements come from the right mesh? */ + BPY_BM_MAPPING_KEY_CHECK(arg_key); + + BMO_slot_map_empty_insert(&bmop, slot, + ((BPy_BMElem *)arg_key)->ele); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL: + default: + { + /* can't convert from these */ + PyErr_Format(PyExc_NotImplementedError, + "This arguments mapping subtype %d is not supported", slot->slot_subtype); + break; + } +#undef BPY_BM_MAPPING_KEY_CHECK + + } + } default: /* TODO --- many others */ PyErr_Format(PyExc_NotImplementedError, @@ -373,24 +546,103 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject * case BMO_OP_SLOT_MAPPING: { GHash *slot_hash = BMO_SLOT_AS_GHASH(slot); - GHashIterator *hash_iter; - item = PyDict_New(); + GHashIterator hash_iter; + + switch (slot->slot_subtype) { + case BMO_OP_SLOT_SUBTYPE_MAP_ELEM: + { + item = PyDict_New(); + if (slot_hash) { + GHASH_ITER (hash_iter, slot_hash) { + BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); + BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); + + PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); + PyObject *py_val = BPy_BMElem_CreatePyObject(bm, *(void **)BMO_OP_SLOT_MAPPING_DATA(ele_val)); + + PyDict_SetItem(ret, py_key, py_val); + Py_DECREF(py_key); + Py_DECREF(py_val); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_FLOAT: + { + item = PyDict_New(); + if (slot_hash) { + GHASH_ITER (hash_iter, slot_hash) { + BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); + BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); + + PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); + PyObject *py_val = PyFloat_FromDouble(*(float *)BMO_OP_SLOT_MAPPING_DATA(ele_val)); + + PyDict_SetItem(ret, py_key, py_val); + Py_DECREF(py_key); + Py_DECREF(py_val); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_INT: + { + item = PyDict_New(); + if (slot_hash) { + GHASH_ITER (hash_iter, slot_hash) { + BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); + BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); + + PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); + PyObject *py_val = PyLong_FromLong(*(int *)BMO_OP_SLOT_MAPPING_DATA(ele_val)); + + PyDict_SetItem(ret, py_key, py_val); + Py_DECREF(py_key); + Py_DECREF(py_val); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_BOOL: + { + item = PyDict_New(); + if (slot_hash) { + GHASH_ITER (hash_iter, slot_hash) { + BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); + BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); + + PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); + PyObject *py_val = PyBool_FromLong(*(int *)BMO_OP_SLOT_MAPPING_DATA(ele_val)); + + PyDict_SetItem(ret, py_key, py_val); + Py_DECREF(py_key); + Py_DECREF(py_val); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_EMPTY: + { + item = PySet_New(NULL); + if (slot_hash) { + GHASH_ITER (hash_iter, slot_hash) { + BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); - for (hash_iter = BLI_ghashIterator_new(slot_hash); - !BLI_ghashIterator_isDone(hash_iter); - BLI_ghashIterator_step(hash_iter) ) - { - BMHeader *ele_key = BLI_ghashIterator_getKey(hash_iter); - BMHeader **ele_val = BLI_ghashIterator_getValue(hash_iter); + PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); - PyObject *py_key = ele_key ? BPy_BMElem_CreatePyObject(bm, ele_key) : (Py_INCREF(Py_None), Py_None); - PyObject *py_val = *ele_val ? BPy_BMElem_CreatePyObject(bm, *ele_val) : (Py_INCREF(Py_None), Py_None); + PySet_Add(item, py_key); - PyDict_SetItem(ret, py_key, py_val); - Py_DECREF(py_key); - Py_DECREF(py_val); + Py_DECREF(py_key); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL: + default: + /* can't convert from these */ + item = (Py_INCREF(Py_None), Py_None); + break; } - BLI_ghashIterator_free(hash_iter); break; } } diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index ee4528df50d..51c2a2be1fd 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -3032,7 +3032,8 @@ void BPy_BM_init_types(void) BPy_BMLoopSeq_Type.tp_methods = bpy_bmloopseq_methods; BPy_BMIter_Type.tp_methods = NULL; - + /*BPy_BMElem_Check() uses bpy_bm_elem_hash() to check types. + * if this changes update the macro */ BPy_BMesh_Type.tp_hash = bpy_bm_hash; BPy_BMVert_Type.tp_hash = bpy_bm_elem_hash; BPy_BMEdge_Type.tp_hash = bpy_bm_elem_hash; diff --git a/source/blender/python/bmesh/bmesh_py_types.h b/source/blender/python/bmesh/bmesh_py_types.h index df5231a4b1b..8de69c2d8a2 100644 --- a/source/blender/python/bmesh/bmesh_py_types.h +++ b/source/blender/python/bmesh/bmesh_py_types.h @@ -55,6 +55,8 @@ extern PyTypeObject BPy_BMIter_Type; #define BPy_BMFaceSeq_Check(v) (Py_TYPE(v) == &BPy_BMFaceSeq_Type) #define BPy_BMLoopSeq_Check(v) (Py_TYPE(v) == &BPy_BMLoopSeq_Type) #define BPy_BMIter_Check(v) (Py_TYPE(v) == &BPy_BMIter_Type) +/* trick since we know they share a hash function */ +#define BPy_BMElem_Check(v) (Py_TYPE(v)->tp_hash == BPy_BMVert_Type.tp_hash) /* cast from _any_ bmesh type - they all have BMesh first */ typedef struct BPy_BMGeneric { -- cgit v1.2.3 From c91562d0ff964a73bf290c20a93e3ba738573e5b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 26 Nov 2012 08:52:07 +0000 Subject: Fix #33310: unnecessary redraw of outliner when editing materials and textures. --- source/blender/editors/mesh/editmesh_select.c | 2 +- source/blender/editors/object/object_relations.c | 2 +- source/blender/editors/render/render_shading.c | 4 ++-- source/blender/editors/space_buttons/space_buttons.c | 2 ++ source/blender/editors/space_node/space_node.c | 2 ++ source/blender/editors/space_outliner/outliner_edit.c | 2 +- source/blender/editors/space_outliner/outliner_select.c | 2 +- source/blender/editors/space_outliner/space_outliner.c | 6 +----- source/blender/editors/space_view3d/space_view3d.c | 1 + source/blender/makesrna/intern/rna_material.c | 4 ++-- source/blender/makesrna/intern/rna_object.c | 2 +- source/blender/makesrna/intern/rna_texture.c | 8 ++++---- source/blender/windowmanager/WM_types.h | 1 + 13 files changed, 20 insertions(+), 18 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 8e78de44baa..a6b798c8887 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -1871,7 +1871,7 @@ int EDBM_select_pick(bContext *C, const int mval[2], short extend, short deselec vc.obedit->actcol = efa->mat_nr + 1; vc.em->mat_nr = efa->mat_nr; - WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING, NULL); + WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, NULL); } diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index e7f09b4055a..6c3155deb17 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2148,7 +2148,7 @@ static int drop_named_material_invoke(bContext *C, wmOperator *op, wmEvent *even DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); - WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING, ma); + WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 25a01d38dd5..eef5e705ce7 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -865,7 +865,7 @@ static int paste_material_exec(bContext *C, wmOperator *UNUSED(op)) paste_matcopybuf(ma); - WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_DRAW, ma); + WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma); return OPERATOR_FINISHED; } @@ -1027,7 +1027,7 @@ static int paste_mtex_exec(bContext *C, wmOperator *UNUSED(op)) paste_mtex_copybuf(id); - WM_event_add_notifier(C, NC_TEXTURE | ND_SHADING_DRAW, NULL); + WM_event_add_notifier(C, NC_TEXTURE | ND_SHADING_LINKS, NULL); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 09ad7312123..c98d213e949 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -297,6 +297,7 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn) buttons_area_redraw(sa, BCONTEXT_PHYSICS); case ND_SHADING: case ND_SHADING_DRAW: + case ND_SHADING_LINKS: /* currently works by redraws... if preview is set, it (re)starts job */ sbuts->preview = 1; break; @@ -319,6 +320,7 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn) switch (wmn->data) { case ND_SHADING: case ND_SHADING_DRAW: + case ND_SHADING_LINKS: case ND_NODES: /* currently works by redraws... if preview is set, it (re)starts job */ sbuts->preview = 1; diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 4d2512cdc93..f7e0d51ea03 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -193,6 +193,8 @@ static void node_area_listener(ScrArea *sa, wmNotifier *wmn) ED_area_tag_refresh(sa); else if (wmn->data == ND_SHADING_DRAW) ED_area_tag_refresh(sa); + else if (wmn->data == ND_SHADING_LINKS) + ED_area_tag_refresh(sa); else if (wmn->action == NA_ADDED && snode->edittree) nodeSetActiveID(snode->edittree, ID_MA, wmn->reference); diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 23766d6a6fe..f7ce48fe7cb 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -1859,7 +1859,7 @@ static int material_drop_invoke(bContext *C, wmOperator *op, wmEvent *event) DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); - WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING, ma); + WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 4668dfa1386..0b585e1272b 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -222,7 +222,7 @@ static int tree_element_active_material(bContext *C, Scene *scene, SpaceOops *so } } if (set) { - WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING, NULL); + WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, NULL); } return 0; } diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index f8856cb9646..ecc09a35670 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -326,15 +326,11 @@ static void outliner_main_area_listener(ARegion *ar, wmNotifier *wmn) break; case NC_MATERIAL: switch (wmn->data) { - case ND_SHADING: - case ND_SHADING_DRAW: + case ND_SHADING_LINKS: ED_region_tag_redraw(ar); break; } break; - case NC_TEXTURE: - ED_region_tag_redraw(ar); - break; case NC_GEOM: switch (wmn->data) { case ND_VERTEX_GROUP: diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 726fd26b11d..1c31cd23e33 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -724,6 +724,7 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) case NC_MATERIAL: switch (wmn->data) { case ND_SHADING_DRAW: + case ND_SHADING_LINKS: ED_region_tag_redraw(ar); break; } diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 9232ae098ea..1221b84372c 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -2121,13 +2121,13 @@ void rna_def_mtex_common(BlenderRNA *brna, StructRNA *srna, const char *begin, RNA_def_property_editable_func(prop, activeeditable); RNA_def_property_pointer_funcs(prop, activeget, activeset, NULL, NULL); RNA_def_property_ui_text(prop, "Active Texture", "Active texture slot being displayed"); - RNA_def_property_update(prop, 0, update); + RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING_LINKS, update); prop = RNA_def_property(srna, "active_texture_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "texact"); RNA_def_property_range(prop, 0, MAX_MTEX - 1); RNA_def_property_ui_text(prop, "Active Texture Index", "Index of active texture slot"); - RNA_def_property_update(prop, 0, update); + RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING_LINKS, update); } #endif diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index a669cb2558a..bd51af77b34 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -2174,7 +2174,7 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_int_funcs(prop, "rna_Object_active_material_index_get", "rna_Object_active_material_index_set", "rna_Object_active_material_index_range"); RNA_def_property_ui_text(prop, "Active Material Index", "Index of active material slot"); - RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING, NULL); + RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING_LINKS, NULL); /* transform */ prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION); diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index e67985f68c5..b212879512e 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -46,6 +46,9 @@ #include "BKE_node.h" +#include "WM_api.h" +#include "WM_types.h" + EnumPropertyItem texture_filter_items[] = { {TXF_BOX, "BOX", 0, "Box", ""}, {TXF_EWA, "EWA", 0, "EWA", ""}, @@ -110,9 +113,6 @@ EnumPropertyItem blend_type_items[] = { #include "ED_node.h" -#include "WM_api.h" -#include "WM_types.h" - static StructRNA *rna_Texture_refine(struct PointerRNA *ptr) { Tex *tex = (Tex *)ptr->data; @@ -603,7 +603,7 @@ static void rna_def_mtex(BlenderRNA *brna) RNA_def_property_struct_type(prop, "Texture"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Texture", "Texture datablock used by this texture slot"); - RNA_def_property_update(prop, 0, "rna_TextureSlot_update"); + RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING_LINKS, "rna_TextureSlot_update"); prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_string_funcs(prop, "rna_TextureSlot_name_get", "rna_TextureSlot_name_length", NULL); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 3dc5874a4fe..347f46c8166 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -300,6 +300,7 @@ typedef struct wmNotifier { /* NC_MATERIAL Material */ #define ND_SHADING (30<<16) #define ND_SHADING_DRAW (31<<16) +#define ND_SHADING_LINKS (32<<16) /* NC_LAMP Lamp */ #define ND_LIGHTING (40<<16) -- cgit v1.2.3 From 240ee2fccb8f53b41966dce9d1cb3187ac80ef47 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 26 Nov 2012 09:46:15 +0000 Subject: Fix #33312: cycles render crash with motion blur / vector pass rendering. It's actually the render threading issue and not a full fix, but this avoids the 3D viewport getting redrawn when changing frames to get motion vectors. --- source/blender/makesrna/intern/rna_scene_api.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index 63253153699..7857aca2aa6 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -62,12 +62,16 @@ static void rna_Scene_frame_set(Scene *scene, int frame, float subframe) BKE_scene_update_for_newframe(G.main, scene, (1 << 20) - 1); BKE_scene_camera_switch_update(scene); - /* cant use NC_SCENE|ND_FRAME because this causes wm_event_do_notifiers to call - * BKE_scene_update_for_newframe which will loose any un-keyed changes [#24690] */ - /* WM_main_add_notifier(NC_SCENE|ND_FRAME, scene); */ - - /* instead just redraw the views */ - WM_main_add_notifier(NC_WINDOW, NULL); + /* don't do notifier when we're rendering, avoid some viewport crashes + * redrawing while the data is being modified for render */ + if(!G.is_rendering) { + /* cant use NC_SCENE|ND_FRAME because this causes wm_event_do_notifiers to call + * BKE_scene_update_for_newframe which will loose any un-keyed changes [#24690] */ + /* WM_main_add_notifier(NC_SCENE|ND_FRAME, scene); */ + + /* instead just redraw the views */ + WM_main_add_notifier(NC_WINDOW, NULL); + } } static void rna_Scene_update_tagged(Scene *scene) -- cgit v1.2.3 From e3d3ffe7469ed2e868968f8c0c4fccb6874378f1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 Nov 2012 10:15:32 +0000 Subject: fix [#33303] face selection masking for painting does not work with mesh with n-gon caused by own change to how origindex is used, now if mpoly's CD_ORIGINDEX array is missing its assumes that its the original mpoly array. --- source/blender/blenkernel/BKE_DerivedMesh.h | 8 +++++++- source/blender/blenkernel/intern/cdderivedmesh.c | 16 ++++++++-------- source/blender/blenkernel/intern/particle.c | 8 ++++---- source/blender/editors/sculpt_paint/paint_utils.c | 4 ++-- source/blender/render/intern/source/convertblender.c | 4 ++-- .../gameengine/Physics/Bullet/CcdPhysicsController.cpp | 8 ++++---- 6 files changed, 27 insertions(+), 21 deletions(-) diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index c6c54cc6e8a..617c4cd2bc8 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -709,10 +709,16 @@ void DM_debug_print(DerivedMesh *dm); void DM_debug_print_cdlayers(CustomData *cdata); #endif +#ifdef __GNUC__ +BLI_INLINE int DM_origindex_mface_mpoly(const int *index_mf_to_mpoly, const int *index_mp_to_orig, const int i) + __attribute__((nonnull(1))) +; +#endif + BLI_INLINE int DM_origindex_mface_mpoly(const int *index_mf_to_mpoly, const int *index_mp_to_orig, const int i) { const int j = index_mf_to_mpoly[i]; - return (j != ORIGINDEX_NONE) ? index_mp_to_orig[j] : ORIGINDEX_NONE; + return (j != ORIGINDEX_NONE) ? (index_mp_to_orig ? index_mp_to_orig[j] : j) : ORIGINDEX_NONE; } #endif diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 9b1720787ed..54f69a49e70 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -623,8 +623,8 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, /* double lookup */ const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); - if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { - index_mf_to_mpoly = index_mp_to_orig = NULL; + if (index_mf_to_mpoly == NULL) { + index_mp_to_orig = NULL; } colType = CD_TEXTURE_MCOL; @@ -812,8 +812,8 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, /* double lookup */ const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); - if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { - index_mf_to_mpoly = index_mp_to_orig = NULL; + if (index_mf_to_mpoly == NULL) { + index_mp_to_orig = NULL; } @@ -1048,8 +1048,8 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, /* double lookup */ const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); - if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { - index_mf_to_mpoly = index_mp_to_orig = NULL; + if (index_mf_to_mpoly == NULL) { + index_mp_to_orig = NULL; } cdDM_update_normals_from_pbvh(dm); @@ -1349,8 +1349,8 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm, /* double lookup */ const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); - if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { - index_mf_to_mpoly = index_mp_to_orig = NULL; + if (index_mf_to_mpoly == NULL) { + index_mp_to_orig = NULL; } cdDM_update_normals_from_pbvh(dm); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 93bf5a5c0b4..5f5a713064d 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -822,8 +822,8 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); - if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { - index_mf_to_mpoly = index_mp_to_orig = NULL; + if (index_mf_to_mpoly == NULL) { + index_mp_to_orig = NULL; } facearea = MEM_callocN(sizeof(float) * totorigface, "SimplifyFaceArea"); @@ -1645,8 +1645,8 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, const f /* double lookup */ const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); - if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { - index_mf_to_mpoly = index_mp_to_orig = NULL; + if (index_mf_to_mpoly == NULL) { + index_mp_to_orig = NULL; } mpoly = dm->getPolyArray(dm); diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index c5eff1a1f0e..cb4b6346c2a 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -257,8 +257,8 @@ void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, const in /* double lookup */ const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); - if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { - index_mf_to_mpoly = index_mp_to_orig = NULL; + if (index_mf_to_mpoly == NULL) { + index_mp_to_orig = NULL; } minabsw = 1e10; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index d6e6171047e..386086333e0 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -1707,8 +1707,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem totface= psmd->dm->getNumTessFaces(psmd->dm); index_mf_to_mpoly = psmd->dm->getTessFaceDataArray(psmd->dm, CD_ORIGINDEX); index_mp_to_orig = psmd->dm->getPolyDataArray(psmd->dm, CD_ORIGINDEX); - if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { - index_mf_to_mpoly = index_mp_to_orig = NULL; + if (index_mf_to_mpoly == NULL) { + index_mp_to_orig = NULL; } for (a=0; atotbound = max_ii(strandbuf->totbound, (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a): a); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 8d587cf39f6..6c6ce94d8d5 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -1507,8 +1507,8 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, /* double lookup */ const int *index_mf_to_mpoly = (const int *)dm->getTessFaceDataArray(dm, CD_ORIGINDEX); const int *index_mp_to_orig = (const int *)dm->getPolyDataArray(dm, CD_ORIGINDEX); - if ((index_mf_to_mpoly && index_mp_to_orig) == false) { - index_mf_to_mpoly = index_mp_to_orig = NULL; + if (index_mf_to_mpoly == NULL) { + index_mp_to_orig = NULL; } m_shapeType = (polytope) ? PHY_SHAPE_POLYTOPE : PHY_SHAPE_MESH; @@ -1816,8 +1816,8 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA /* double lookup */ const int *index_mf_to_mpoly = (const int *)dm->getTessFaceDataArray(dm, CD_ORIGINDEX); const int *index_mp_to_orig = (const int *)dm->getPolyDataArray(dm, CD_ORIGINDEX); - if ((index_mf_to_mpoly && index_mp_to_orig) == false) { - index_mf_to_mpoly = index_mp_to_orig = NULL; + if (index_mf_to_mpoly == NULL) { + index_mp_to_orig = NULL; } MFace *mf; -- cgit v1.2.3 From a91814e94dbd021cf91c164ce10ff20d115dd74d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 Nov 2012 11:03:14 +0000 Subject: style cleanup --- source/blender/bmesh/operators/bmo_subdivide.c | 2 +- source/blender/editors/animation/anim_markers.c | 2 +- source/blender/editors/physics/particle_edit.c | 2 +- source/blender/editors/space_view3d/view3d_draw.c | 2 +- source/blender/makesrna/intern/rna_scene_api.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index 74972da8888..1926e9a0f68 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -806,7 +806,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) float vec1[3], vec2[3]; /* skip non-quads if requested */ - if(use_onlyquads && face->len != 4) + if (use_onlyquads && face->len != 4) continue; /* figure out which pattern to use */ diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index d595034032e..62ffdc7fd3a 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -732,7 +732,7 @@ static void ed_marker_move_apply(bContext *C, wmOperator *op) /* so we get view3d redraws */ BKE_scene_camera_switch_update(scene); - if(camera != scene->camera) { + if (camera != scene->camera) { BKE_screen_view3d_scene_sync(sc); WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene); } diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 2ac5f98927c..f5754297e9f 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -431,7 +431,7 @@ static int key_test_depth(PEData *data, const float co[3], const int screen_co[2 #else /* faster to use depths, these are calculated in PE_set_view3d_data */ /* check if screen_co is within bounds because brush_cut uses out of screen coords */ - if(screen_co[0] >= 0 && screen_co[0] < vd->w && screen_co[1] >= 0 && screen_co[1] < vd->h) { + if (screen_co[0] >= 0 && screen_co[0] < vd->w && screen_co[1] >= 0 && screen_co[1] < vd->h) { BLI_assert(vd && vd->depths); /* we know its not clipped */ depth = vd->depths[screen_co[1] * vd->w + screen_co[0]]; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index fcd92cd5639..6c23635da90 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1940,7 +1940,7 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas * is intended to speed up drawing, and drawing extra (especially wire) can * slow it down too much */ dtx = tbase.object->dtx; - if(tbase.object->dt != OB_BOUNDBOX) + if (tbase.object->dt != OB_BOUNDBOX) tbase.object->dtx = base->object->dtx; /* negative scale flag has to propagate */ diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index 7857aca2aa6..012767b5845 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -64,7 +64,7 @@ static void rna_Scene_frame_set(Scene *scene, int frame, float subframe) /* don't do notifier when we're rendering, avoid some viewport crashes * redrawing while the data is being modified for render */ - if(!G.is_rendering) { + if (!G.is_rendering) { /* cant use NC_SCENE|ND_FRAME because this causes wm_event_do_notifiers to call * BKE_scene_update_for_newframe which will loose any un-keyed changes [#24690] */ /* WM_main_add_notifier(NC_SCENE|ND_FRAME, scene); */ -- cgit v1.2.3 From 58ee2bdfc0b45335a8e3e4f552749a111e926c69 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 26 Nov 2012 11:05:22 +0000 Subject: Fix: cycles light sampling crash, happens on rare occasions due to float rounding errors. --- intern/cycles/SConscript | 2 +- intern/cycles/kernel/kernel_light.h | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/intern/cycles/SConscript b/intern/cycles/SConscript index 1a127e364fe..a0e2650ddc6 100644 --- a/intern/cycles/SConscript +++ b/intern/cycles/SConscript @@ -49,7 +49,7 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', ' # optimized kernel if env['WITH_BF_RAYOPTIMIZATION']: - optim_cxxflags = [] + optim_cxxflags = Split(env['CXXFLAGS']) if env['OURPLATFORM'] == 'win32-vc': optim_cxxflags.append('/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc'.split()) diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index 2791b3abbb6..97ae2d3db87 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -350,10 +350,9 @@ __device int light_distribution_sample(KernelGlobals *kg, float randt) } } - first = max(0, first-1); - kernel_assert(first >= 0 && first < kernel_data.integrator.num_distribution); - - return first; + /* clamping should not be needed but float rounding errors seem to + * make this fail on rare occasions */ + return clamp(first-1, 0, kernel_data.integrator.num_distribution-1); } /* Generic Light */ -- cgit v1.2.3 From c2714a6a5bf9c54cbff7f3c8e37ce25f9c21e8a0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 Nov 2012 11:53:34 +0000 Subject: fix [#31598] Messed up Smart UVs face areas were too close to zero. also copy the face normal to avoid recalculations on each use. --- release/scripts/startup/bl_operators/uvcalc_smart_project.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py index eb05057de3d..dd4ced78422 100644 --- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py +++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py @@ -23,7 +23,7 @@ import bpy from bpy.types import Operator DEG_TO_RAD = 0.017453292519943295 # pi/180.0 -SMALL_NUM = 0.000000001 +SMALL_NUM = 0.0000001 # see bug [#31598] why we dont have smaller values BIG_NUM = 1e15 global USER_FILL_HOLES @@ -759,7 +759,7 @@ class thickface(object): self.v = [mesh_verts[i] for i in face.vertices] self.uv = [uv_layer[i].uv for i in face.loop_indices] - self.no = face.normal + self.no = face.normal.copy() self.area = face.area self.edge_keys = face.edge_keys -- cgit v1.2.3 From 2d6402c10c920ddb29a47666f3f7a60642f701ff Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 26 Nov 2012 12:38:40 +0000 Subject: Switch windows to python 3.3 Should affect on msvc2008 only, however scons with msvc2010 could still be broken. --- CMakeLists.txt | 12 ++++++++++-- build_files/scons/config/win32-vc-config.py | 4 ++-- build_files/scons/config/win64-vc-config.py | 4 ++-- source/creator/CMakeLists.txt | 13 +++++++++---- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 751c2dd548e..c40decc424b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1102,9 +1102,17 @@ elseif(WIN32) if(WITH_PYTHON) # normally cached but not since we include them with blender - set(PYTHON_VERSION 3.2) # CACHE STRING) + if(MSVC10) + set(PYTHON_VERSION 3.2) # CACHE STRING) + else() + set(PYTHON_VERSION 3.3) # CACHE STRING) + endif() + set_lib_path(PYTHON "python") - set(PYTHON_LIBRARY ${PYTHON}/lib/python32.lib) #CACHE FILEPATH + STRING(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION}) + set(PYTHON_LIBRARY ${PYTHON}/lib/python${_PYTHON_VERSION_NO_DOTS}.lib) #CACHE FILEPATH + unset(_PYTHON_VERSION_NO_DOTS) + #Shared includes for both vc2008 and vc2010 set(PYTHON_INCLUDE_DIR ${LIBDIR}/python/include/python${PYTHON_VERSION}) diff --git a/build_files/scons/config/win32-vc-config.py b/build_files/scons/config/win32-vc-config.py index 2120938ec71..21488e75f7e 100644 --- a/build_files/scons/config/win32-vc-config.py +++ b/build_files/scons/config/win32-vc-config.py @@ -9,10 +9,10 @@ BF_FFMPEG_LIB = 'avformat-53.lib avcodec-53.lib avdevice-53.lib avutil-51.lib sw BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll' BF_PYTHON = LIBDIR + '/python' -BF_PYTHON_VERSION = '3.2' +BF_PYTHON_VERSION = '3.3' BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}' BF_PYTHON_BINARY = 'python' -BF_PYTHON_LIB = 'python32' +BF_PYTHON_LIB = 'python33' BF_PYTHON_DLL = '${BF_PYTHON_LIB}' BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib' diff --git a/build_files/scons/config/win64-vc-config.py b/build_files/scons/config/win64-vc-config.py index 15bcdf999bd..c0ea7972aeb 100644 --- a/build_files/scons/config/win64-vc-config.py +++ b/build_files/scons/config/win64-vc-config.py @@ -9,10 +9,10 @@ BF_FFMPEG_LIB = 'avformat-53.lib avcodec-53.lib avdevice-53.lib avutil-51.lib sw BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll' BF_PYTHON = LIBDIR + '/python' -BF_PYTHON_VERSION = '3.2' +BF_PYTHON_VERSION = '3.3' BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}' BF_PYTHON_BINARY = 'python' -BF_PYTHON_LIB = 'python32' +BF_PYTHON_LIB = 'python33' BF_PYTHON_DLL = '${BF_PYTHON_LIB}' BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib' diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 32b990d14c5..b66c000ac89 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -471,14 +471,17 @@ elseif(WIN32) if(WITH_PYTHON) set_lib_path(PYLIB "python") + + STRING(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION}) + install( - FILES ${PYLIB}/lib/python32.dll + FILES ${PYLIB}/lib/python${_PYTHON_VERSION_NO_DOTS}.dll DESTINATION ${TARGETDIR} CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel ) install( - FILES ${PYLIB}/lib/python32_d.dll + FILES ${PYLIB}/lib/python${_PYTHON_VERSION_NO_DOTS}_d.dll DESTINATION ${TARGETDIR} CONFIGURATIONS Debug ) @@ -502,10 +505,10 @@ elseif(WIN32) " if(\"\${CMAKE_INSTALL_CONFIG_NAME}\" STREQUAL \"Debug\") execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \"${TARGETDIR_VER}/python/lib\" - \"${CMAKE_COMMAND}\" -E tar xzfv \"${LIBDIR}/release/python32_d.tar.gz\") + \"${CMAKE_COMMAND}\" -E tar xzfv \"${LIBDIR}/release/python${_PYTHON_VERSION_NO_DOTS}_d.tar.gz\") else() execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \"${TARGETDIR_VER}/python/lib\" - \"${CMAKE_COMMAND}\" -E tar xzfv \"${LIBDIR}/release/python32.tar.gz\") + \"${CMAKE_COMMAND}\" -E tar xzfv \"${LIBDIR}/release/python${_PYTHON_VERSION_NO_DOTS}.tar.gz\") endif() " ) @@ -513,6 +516,8 @@ elseif(WIN32) # doesnt work, todo # install(CODE "execute_process(COMMAND find ${TARGETDIR}/${BLENDER_VERSION}/python/lib/ -name '*.so' -exec strip -s {} '\;')") endif() + + unset(_PYTHON_VERSION_NO_DOTS) endif() if(CMAKE_CL_64) -- cgit v1.2.3 From 2ffa538f7dc3ff756ca71af13e00836e3863b767 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 Nov 2012 13:23:37 +0000 Subject: search box width's now scale with DPI setting. was checking on: [#33294] too small place for material names this helps in some cases but doesn't resolve issue with very long names. --- source/blender/editors/include/UI_interface.h | 3 ++- source/blender/editors/interface/interface.c | 1 + source/blender/editors/interface/interface_regions.c | 15 +++++++++++---- source/blender/editors/interface/interface_templates.c | 6 ++++-- source/blender/editors/space_outliner/outliner_draw.c | 2 +- source/blender/editors/space_view3d/view3d_toolbar.c | 2 +- source/blender/windowmanager/intern/wm_operators.c | 4 ++-- 7 files changed, 22 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 3645f13f27a..f5c943fbb87 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -615,7 +615,8 @@ int uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int /* bfunc gets search item *poin as arg2, or if NULL the old string */ void uiButSetSearchFunc(uiBut *but, uiButSearchFunc sfunc, void *arg1, uiButHandleFunc bfunc, void *active); /* height in pixels, it's using hardcoded values still */ -int uiSearchBoxhHeight(void); +int uiSearchBoxHeight(void); +int uiSearchBoxWidth(void); void uiBlockSetHandleFunc(uiBlock *block, uiBlockHandleFunc func, void *arg); void uiBlockSetButmFunc(uiBlock *block, uiMenuHandleFunc func, void *arg); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 535239cd462..9037afc472a 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -2826,6 +2826,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s EnumPropertyItem *item; int i, totitem, free; + /* TODO, translate after getting the item, saves many lookups */ RNA_property_enum_items_gettexted(block->evil_C, ptr, prop, &item, &totitem, &free); for (i = 0; i < totitem; i++) { if (item[i].identifier[0] && item[i].value == (int)max) { diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index c1547593f96..7c099de9c1e 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -826,11 +826,17 @@ int uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int icon return 1; } -int uiSearchBoxhHeight(void) +int uiSearchBoxHeight(void) { return SEARCH_ITEMS * UI_UNIT_Y + 2 * MENU_TOP; } +int uiSearchBoxWidth(void) +{ + /* was hardcoded at 150 */ + return 9 * UI_UNIT_X; +} + /* ar is the search box itself */ static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step) { @@ -1191,10 +1197,11 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) } } else { + const int searchbox_width = uiSearchBoxWidth(); rect_fl.xmin = but->rect.xmin - 5; /* align text with button */ rect_fl.xmax = but->rect.xmax + 5; /* symmetrical */ rect_fl.ymax = but->rect.ymin; - rect_fl.ymin = rect_fl.ymax - uiSearchBoxhHeight(); + rect_fl.ymin = rect_fl.ymax - uiSearchBoxHeight(); ofsx = (but->block->panel) ? but->block->panel->ofsx : 0; ofsy = (but->block->panel) ? but->block->panel->ofsy : 0; @@ -1202,8 +1209,8 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) BLI_rctf_translate(&rect_fl, ofsx, ofsy); /* minimal width */ - if (BLI_rctf_size_x(&rect_fl) < 150) { - rect_fl.xmax = rect_fl.xmin + 150; /* XXX arbitrary */ + if (BLI_rctf_size_x(&rect_fl) < searchbox_width) { + rect_fl.xmax = rect_fl.xmin + searchbox_width; } /* copy to int, gets projected if possible too */ diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index f872afed486..2f1a37dc8ce 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -191,10 +191,12 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem) } /* list view */ else { + const int searchbox_width = uiSearchBoxWidth(); + const int searchbox_height = uiSearchBoxHeight(); /* fake button, it holds space for search items */ - uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, LABEL, 0, "", 10, 15, searchbox_width, searchbox_height, NULL, 0, 0, 0, 0, NULL); - but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, 150, 19, 0, 0, ""); + but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, searchbox_width, UI_UNIT_Y - 1, 0, 0, ""); uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data); } diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 61d513929ad..d37cb4be8fa 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -631,7 +631,7 @@ static uiBlock *operator_search_menu(bContext *C, ARegion *ar, void *arg_kmi) uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_SEARCH_MENU); /* fake button, it holds space for search items */ - uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, LABEL, 0, "", 10, 15, uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL); but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, 150, UI_UNIT_Y, 0, 0, ""); uiButSetSearchFunc(but, operator_search_cb, arg_kmi, operator_call_cb, ot); diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c index d36b0085acb..bfeb56036e6 100644 --- a/source/blender/editors/space_view3d/view3d_toolbar.c +++ b/source/blender/editors/space_view3d/view3d_toolbar.c @@ -176,7 +176,7 @@ static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase) uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_SEARCH_MENU); /* fake button, it holds space for search items */ - uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, LABEL, 0, "", 10, 15, uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL); but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, 150, 19, 0, 0, ""); uiButSetSearchFunc(but, operator_search_cb, arg_listbase, operator_call_cb, NULL); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 84cfe791bce..027c883c01f 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -793,7 +793,7 @@ static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op) uiButSetSearchFunc(but, operator_enum_search_cb, op->type, operator_enum_call_cb, NULL); /* fake button, it holds space for search items */ - uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxhHeight(), 9 * UI_UNIT_X, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL); uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */ uiEndBlock(C, block); @@ -1566,7 +1566,7 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *UNUSED(arg_ uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL); /* fake button, it holds space for search items */ - uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxhHeight(), 9 * UI_UNIT_X, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL); uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */ uiEndBlock(C, block); -- cgit v1.2.3 From f5d8cd34cda013bee44bee0d0c179e79288ba242 Mon Sep 17 00:00:00 2001 From: Jason Wilkins Date: Mon, 26 Nov 2012 13:48:48 +0000 Subject: -fno-rtti is a gcc option which gives a warning when using MSVC --- intern/cycles/CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt index 7495a98aed1..2a1eddcec27 100644 --- a/intern/cycles/CMakeLists.txt +++ b/intern/cycles/CMakeLists.txt @@ -21,8 +21,11 @@ elseif(CMAKE_COMPILER_IS_GNUCC) endif() # for OSL -set(RTTI_DISABLE_FLAGS "-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID") -# set(RTTI_DISABLE_FLAGS "/GR- -DBOOST_NO_RTTI -DBOOST_NO_TYPEID") +if(WIN32 AND MSVC) + set(RTTI_DISABLE_FLAGS "/GR- -DBOOST_NO_RTTI -DBOOST_NO_TYPEID") +elseif(CMAKE_COMPILER_IS_GNUCC) + set(RTTI_DISABLE_FLAGS "-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID") +endif() # Definitions and Includes -- cgit v1.2.3 From 0a5d44588cdf21dede92184320891da2690d4414 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 Nov 2012 13:58:06 +0000 Subject: switch verious references from py3.2 -> 3.3 or just 3. --- CMakeLists.txt | 12 ++++++------ build_files/cmake/cmake_consistency_check.py | 2 +- build_files/cmake/cmake_netbeans_project.py | 2 +- build_files/cmake/cmake_qtcreator_project.py | 2 +- build_files/cmake/cmake_static_check_clang_array.py | 2 +- build_files/cmake/cmake_static_check_cppcheck.py | 2 +- build_files/cmake/cmake_static_check_smatch.py | 2 +- build_files/cmake/cmake_static_check_sparse.py | 2 +- build_files/cmake/cmake_static_check_splint.py | 2 +- build_files/cmake/example_scripts/make_quicky.py | 2 +- build_files/cmake/project_info.py | 2 +- build_files/scons/config/freebsd7-config.py | 2 +- build_files/scons/config/freebsd8-config.py | 2 +- build_files/scons/config/freebsd9-config.py | 2 +- build_files/scons/config/linuxcross-config.py | 2 +- build_files/scons/config/win32-mingw-config.py | 4 ++-- build_files/scons/config/win64-mingw-config.py | 4 ++-- doc/blender_file_format/BlendFileDnaExporter_25.py | 2 +- doc/blender_file_format/BlendFileReader.py | 2 +- source/blender/makesrna/rna_cleanup/rna_cleaner.py | 2 +- source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py | 2 +- 21 files changed, 28 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c40decc424b..b826b8eeb76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -487,14 +487,14 @@ set(PLATFORM_LINKFLAGS_DEBUG "") # For alternate Python locations the commandline can be used to override detected/default cache settings, e.g: # On Unix: # cmake ../blender \ -# -D PYTHON_VERSION=3.2 \ -# -D PYTHON_INCLUDE_DIR=/opt/py32/include/python3.2d \ -# -D PYTHON_LIBRARY=/opt/py32/lib/libpython3.2d.so +# -D PYTHON_VERSION=3.3 \ +# -D PYTHON_INCLUDE_DIR=/opt/py33/include/python3.3d \ +# -D PYTHON_LIBRARY=/opt/py33/lib/libpython3.3d.so # # On Macs: # cmake ../blender \ -# -D PYTHON_INCLUDE_DIR=/System/Library/Frameworks/Python.framework/Versions/3.2/include/python3.2 \ -# -D PYTHON_LIBPATH=/System/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/config \ +# -D PYTHON_INCLUDE_DIR=/System/Library/Frameworks/Python.framework/Versions/3.3/include/python3.3 \ +# -D PYTHON_LIBPATH=/System/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/config \ # -G Xcode # # When changing any of this remember to update the notes in doc/build_systems/cmake.txt @@ -522,7 +522,7 @@ if(UNIX AND NOT APPLE) find_package_wrapper(Freetype REQUIRED) if(WITH_PYTHON) - # No way to set py32. remove for now. + # No way to set py33. remove for now. # find_package(PythonLibs) # Use our own instead, since wothout py is such a rare case, diff --git a/build_files/cmake/cmake_consistency_check.py b/build_files/cmake/cmake_consistency_check.py index 83ebf927b3c..b13b0ddb424 100755 --- a/build_files/cmake/cmake_consistency_check.py +++ b/build_files/cmake/cmake_consistency_check.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.2 +#!/usr/bin/env python3 # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/build_files/cmake/cmake_netbeans_project.py b/build_files/cmake/cmake_netbeans_project.py index 8f3835c3401..2f36cad4d24 100755 --- a/build_files/cmake/cmake_netbeans_project.py +++ b/build_files/cmake/cmake_netbeans_project.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.2 +#!/usr/bin/env python3 # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/build_files/cmake/cmake_qtcreator_project.py b/build_files/cmake/cmake_qtcreator_project.py index 83ea761e2d1..86201da23de 100755 --- a/build_files/cmake/cmake_qtcreator_project.py +++ b/build_files/cmake/cmake_qtcreator_project.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.2 +#!/usr/bin/env python3 # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/build_files/cmake/cmake_static_check_clang_array.py b/build_files/cmake/cmake_static_check_clang_array.py index db4e762932e..7f45cc6aadc 100644 --- a/build_files/cmake/cmake_static_check_clang_array.py +++ b/build_files/cmake/cmake_static_check_clang_array.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.2 +#!/usr/bin/env python3 # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/build_files/cmake/cmake_static_check_cppcheck.py b/build_files/cmake/cmake_static_check_cppcheck.py index 518b94d74a5..12369a5e8cd 100644 --- a/build_files/cmake/cmake_static_check_cppcheck.py +++ b/build_files/cmake/cmake_static_check_cppcheck.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.2 +#!/usr/bin/env python3 # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/build_files/cmake/cmake_static_check_smatch.py b/build_files/cmake/cmake_static_check_smatch.py index 8f7bd37d4c3..7535f1cc55a 100644 --- a/build_files/cmake/cmake_static_check_smatch.py +++ b/build_files/cmake/cmake_static_check_smatch.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.2 +#!/usr/bin/env python3 # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/build_files/cmake/cmake_static_check_sparse.py b/build_files/cmake/cmake_static_check_sparse.py index 92d590e52ac..06bef1a1327 100644 --- a/build_files/cmake/cmake_static_check_sparse.py +++ b/build_files/cmake/cmake_static_check_sparse.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.2 +#!/usr/bin/env python3 # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/build_files/cmake/cmake_static_check_splint.py b/build_files/cmake/cmake_static_check_splint.py index d3f22191021..5b1207543f5 100644 --- a/build_files/cmake/cmake_static_check_splint.py +++ b/build_files/cmake/cmake_static_check_splint.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.2 +#!/usr/bin/env python3 # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/build_files/cmake/example_scripts/make_quicky.py b/build_files/cmake/example_scripts/make_quicky.py index 9b853fc01d4..76d4df32f86 100755 --- a/build_files/cmake/example_scripts/make_quicky.py +++ b/build_files/cmake/example_scripts/make_quicky.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.2 +#!/usr/bin/env python3 # ##### BEGIN GPL LICENSE BLOCK ##### # diff --git a/build_files/cmake/project_info.py b/build_files/cmake/project_info.py index b154d578144..34f378a58dd 100755 --- a/build_files/cmake/project_info.py +++ b/build_files/cmake/project_info.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.2 +#!/usr/bin/env python3 # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/build_files/scons/config/freebsd7-config.py b/build_files/scons/config/freebsd7-config.py index 61358de12b4..02c9093567a 100644 --- a/build_files/scons/config/freebsd7-config.py +++ b/build_files/scons/config/freebsd7-config.py @@ -7,7 +7,7 @@ LIBDIR = "${LCGDIR}" BF_PYTHON_ABI_FLAGS = '' BF_PYTHON = '/usr/local' BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib' -BF_PYTHON_VERSION = '3.2' +BF_PYTHON_VERSION = '3.3' WITH_BF_STATICPYTHON = False BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS}' BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}' diff --git a/build_files/scons/config/freebsd8-config.py b/build_files/scons/config/freebsd8-config.py index 0f6c7f64786..5d3308c50d4 100644 --- a/build_files/scons/config/freebsd8-config.py +++ b/build_files/scons/config/freebsd8-config.py @@ -7,7 +7,7 @@ LIBDIR = "${LCGDIR}" BF_PYTHON_ABI_FLAGS = '' BF_PYTHON = '/usr/local' BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib' -BF_PYTHON_VERSION = '3.2' +BF_PYTHON_VERSION = '3.3' WITH_BF_STATICPYTHON = False BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS}' BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}' diff --git a/build_files/scons/config/freebsd9-config.py b/build_files/scons/config/freebsd9-config.py index c0df68f99ad..98c2c8fa500 100644 --- a/build_files/scons/config/freebsd9-config.py +++ b/build_files/scons/config/freebsd9-config.py @@ -7,7 +7,7 @@ LIBDIR = "${LCGDIR}" BF_PYTHON_ABI_FLAGS = '' BF_PYTHON = '/usr/local' BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib' -BF_PYTHON_VERSION = '3.2' +BF_PYTHON_VERSION = '3.3' WITH_BF_STATICPYTHON = False BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS}' BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}' diff --git a/build_files/scons/config/linuxcross-config.py b/build_files/scons/config/linuxcross-config.py index 63264807720..54faf59b2a4 100644 --- a/build_files/scons/config/linuxcross-config.py +++ b/build_files/scons/config/linuxcross-config.py @@ -2,7 +2,7 @@ LCGDIR = '#../lib/windows' LIBDIR = '${LCGDIR}' BF_PYTHON = LIBDIR + '/python' -BF_PYTHON_VERSION = '3.2' +BF_PYTHON_VERSION = '3.3' BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}' BF_PYTHON_BINARY = 'python' BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}mw' diff --git a/build_files/scons/config/win32-mingw-config.py b/build_files/scons/config/win32-mingw-config.py index 80e3592c71e..391421609d2 100644 --- a/build_files/scons/config/win32-mingw-config.py +++ b/build_files/scons/config/win32-mingw-config.py @@ -2,12 +2,12 @@ LCGDIR = '#../lib/mingw32' LIBDIR = "${LCGDIR}" BF_PYTHON = LIBDIR + '/python' -BF_PYTHON_VERSION = '3.2' +BF_PYTHON_VERSION = '3.3' WITH_BF_STATICPYTHON = False BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}' BF_PYTHON_BINARY = 'python' BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}mw' -BF_PYTHON_DLL = 'python32' +BF_PYTHON_DLL = 'python33' BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib' BF_PYTHON_LIB_STATIC = '${BF_PYTHON}/lib/libpython${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}.a' diff --git a/build_files/scons/config/win64-mingw-config.py b/build_files/scons/config/win64-mingw-config.py index fdfd792f180..d00e7a3ffa7 100644 --- a/build_files/scons/config/win64-mingw-config.py +++ b/build_files/scons/config/win64-mingw-config.py @@ -2,12 +2,12 @@ LCGDIR = '#../lib/mingw64' LIBDIR = "${LCGDIR}" BF_PYTHON = LIBDIR + '/python' -BF_PYTHON_VERSION = '3.2' +BF_PYTHON_VERSION = '3.3' WITH_BF_STATICPYTHON = False BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}' BF_PYTHON_BINARY = 'python' BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}mw' -BF_PYTHON_DLL = 'python32' +BF_PYTHON_DLL = 'python33' BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib' WITH_BF_OPENAL = True diff --git a/doc/blender_file_format/BlendFileDnaExporter_25.py b/doc/blender_file_format/BlendFileDnaExporter_25.py index b7b89c89268..837b67c6eed 100755 --- a/doc/blender_file_format/BlendFileDnaExporter_25.py +++ b/doc/blender_file_format/BlendFileDnaExporter_25.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.2 +#!/usr/bin/env python3 # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/doc/blender_file_format/BlendFileReader.py b/doc/blender_file_format/BlendFileReader.py index b7091ad8ff5..a4d2f494c5b 100644 --- a/doc/blender_file_format/BlendFileReader.py +++ b/doc/blender_file_format/BlendFileReader.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.2 +#!/usr/bin/env python3 # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/source/blender/makesrna/rna_cleanup/rna_cleaner.py b/source/blender/makesrna/rna_cleanup/rna_cleaner.py index 0231e57fcfd..8b4b10c490e 100755 --- a/source/blender/makesrna/rna_cleanup/rna_cleaner.py +++ b/source/blender/makesrna/rna_cleanup/rna_cleaner.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.2 +#!/usr/bin/env python3 """ This script is used to help cleaning RNA api. diff --git a/source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py b/source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py index 75851105991..17ea5f9b0bd 100755 --- a/source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py +++ b/source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.2 +#!/usr/bin/env python3 import sys -- cgit v1.2.3 From 444d43f72cf412aa0f76e23308b827ffd8ae03ee Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 26 Nov 2012 14:15:41 +0000 Subject: Fix #33293L VSE: strip - separate images [Y] dialog "image duration" missing --- source/blender/editors/space_sequencer/sequencer_edit.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 00d4a943626..4e2bf982ff3 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -1850,6 +1850,7 @@ void SEQUENCER_OT_images_separate(wmOperatorType *ot) /* api callbacks */ ot->exec = sequencer_separate_images_exec; + ot->invoke = WM_operator_props_popup; ot->poll = sequencer_edit_poll; /* flags */ -- cgit v1.2.3 From f9bed10d1f4c837fb7b48d1838ad40d341c4ed26 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Mon, 26 Nov 2012 14:47:34 +0000 Subject: Enable python 3.3 for MinGW/CMake. MinGW32 python libs will be commited later in the day --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b826b8eeb76..48da0203318 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1292,9 +1292,9 @@ elseif(WIN32) if(WITH_PYTHON) # normally cached but not since we include them with blender - set(PYTHON_VERSION 3.2) # CACHE STRING) + set(PYTHON_VERSION 3.3) # CACHE STRING) set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}") # CACHE PATH) - set(PYTHON_LIBRARY "${LIBDIR}/python/lib/python32mw.lib") # CACHE FILEPATH) + set(PYTHON_LIBRARY "${LIBDIR}/python/lib/python33mw.lib") # CACHE FILEPATH) # uncached vars set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}") -- cgit v1.2.3 From 3509dd9d7f25913df2a110a86576910863bcd1b5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 Nov 2012 15:12:17 +0000 Subject: fix for changing images in UV editmode with sync-selection enabled, this was switching all images even those from unselected faces. --- source/blender/editors/uvedit/uvedit_ops.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 0feaec514d2..47791ce71e7 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -224,7 +224,9 @@ void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *im BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); - if (uvedit_face_visible_test(scene, previma, efa, tf)) { + if (uvedit_face_visible_test(scene, previma, efa, tf) && + (selected == TRUE || uvedit_face_select_test(scene, em, efa))) + { if (ima) { tf->tpage = ima; -- cgit v1.2.3 From f8759797e6f47a9c788cdf5ee77a1b1d0992b524 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 Nov 2012 16:20:35 +0000 Subject: fix for crash copying nodes, regression since last release. --- source/blender/blenkernel/intern/node.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 06b846a6df9..e5500108f46 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -406,13 +406,14 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) /* only shader nodes get pleasant preview updating this way, compo uses own system */ if (node->preview) { - if (ntree->type == NTREE_SHADER) { + if (ntree && (ntree->type == NTREE_SHADER)) { nnode->preview = MEM_dupallocN(node->preview); if (node->preview->rect) nnode->preview->rect = MEM_dupallocN(node->preview->rect); } - else + else { nnode->preview = NULL; + } } if (ntree) -- cgit v1.2.3 From 233e0b24721a83000f7a56a88dc00bc2dbca3362 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 Nov 2012 16:55:44 +0000 Subject: fix uv lasso and circle select - both were not working with uv-face-select mode. now face select with/without sync-select work, with sticky options too. --- source/blender/editors/uvedit/uvedit_ops.c | 100 +++++++++++++++++++---------- 1 file changed, 67 insertions(+), 33 deletions(-) diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 47791ce71e7..a384c777aab 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -2669,10 +2669,12 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s else { /* SI_STICKY_DISABLE or ts->uv_flag & UV_SYNC_SELECTION */ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { - if (select) + if (select) { uvedit_face_select_enable(scene, em, efa, FALSE); - else + } + else { uvedit_face_select_disable(scene, em, efa); + } } } } @@ -2694,7 +2696,10 @@ static int border_select_exec(bContext *C, wmOperator *op) MLoopUV *luv; rcti rect; rctf rectf; - int change, pinned, select, faces, extend; + int change, pinned, select, extend; + const int use_face_center = (ts->uv_flag & UV_SYNC_SELECTION) ? + (ts->selectmode == SCE_SELECT_FACE) : + (ts->uv_selectmode == UV_SELECT_FACE); /* get rectangle from operator */ WM_operator_properties_border_to_rcti(op, &rect); @@ -2709,14 +2714,9 @@ static int border_select_exec(bContext *C, wmOperator *op) if (!extend) select_all_perform(scene, ima, em, SEL_DESELECT); - - if (ts->uv_flag & UV_SYNC_SELECTION) - faces = (ts->selectmode == SCE_SELECT_FACE); - else - faces = (ts->uv_selectmode == UV_SELECT_FACE); /* do actual selection */ - if (faces && !pinned) { + if (use_face_center && !pinned) { /* handle face selection mode */ float cent[2]; @@ -2737,8 +2737,9 @@ static int border_select_exec(bContext *C, wmOperator *op) } /* (de)selects all tagged faces and deals with sticky modes */ - if (change) + if (change) { uv_faces_do_sticky(sima, scene, obedit, select); + } } else { /* other selection modes */ @@ -2807,19 +2808,19 @@ static void UV_OT_select_border(wmOperatorType *ot) /* ******************** circle select operator **************** */ -static int select_uv_inside_ellipse(BMEditMesh *em, SpaceImage *UNUSED(sima), Scene *scene, int select, - float *offset, float *ell, BMLoop *l, MLoopUV *luv) +static int uv_inside_circle(const float uv[2], const float offset[2], const float ellipse[2]) { /* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */ - float x, y, r2, *uv; - - uv = luv->uv; - - x = (uv[0] - offset[0]) * ell[0]; - y = (uv[1] - offset[1]) * ell[1]; + float x, y; + x = (uv[0] - offset[0]) * ellipse[0]; + y = (uv[1] - offset[1]) * ellipse[1]; + return ((x * x + y * y) < 1.0f); +} - r2 = x * x + y * y; - if (r2 < 1.0f) { +static int select_uv_inside_ellipse(BMEditMesh *em, Scene *scene, const int select, + const float offset[2], const float ellipse[2], BMLoop *l, MLoopUV *luv) +{ + if (uv_inside_circle(luv->uv, offset, ellipse)) { if (select) uvedit_uv_select_enable(em, scene, l, FALSE); else uvedit_uv_select_disable(em, scene, l); return TRUE; @@ -2845,6 +2846,9 @@ static int circle_select_exec(bContext *C, wmOperator *op) float zoomx, zoomy, offset[2], ellipse[2]; int gesture_mode = RNA_int_get(op->ptr, "gesture_mode"); int change = FALSE; + const int use_face_center = (ts->uv_flag & UV_SYNC_SELECTION) ? + (ts->selectmode == SCE_SELECT_FACE) : + (ts->uv_selectmode == UV_SELECT_FACE); /* get operator properties */ select = (gesture_mode == GESTURE_MODAL_SELECT); @@ -2863,10 +2867,32 @@ static int circle_select_exec(bContext *C, wmOperator *op) UI_view2d_region_to_view(&ar->v2d, x, y, &offset[0], &offset[1]); /* do selection */ - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - change |= select_uv_inside_ellipse(em, sima, scene, select, offset, ellipse, l, luv); + if (use_face_center) { + change = FALSE; + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + BM_elem_flag_disable(efa, BM_ELEM_TAG); + /* assume not touched */ + if ((select) != (uvedit_face_select_test(scene, em, efa))) { + float cent[2]; + uv_poly_center(em, efa, cent); + if (uv_inside_circle(cent, offset, ellipse)) { + BM_elem_flag_enable(efa, BM_ELEM_TAG); + change = TRUE; + } + } + } + + /* (de)selects all tagged faces and deals with sticky modes */ + if (change) { + uv_faces_do_sticky(sima, scene, obedit, select); + } + } + else { + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + change |= select_uv_inside_ellipse(em, scene, select, offset, ellipse, l, luv); + } } } @@ -2908,12 +2934,16 @@ static void UV_OT_circle_select(wmOperatorType *ot) static int do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short moves, short select) { + SpaceImage *sima = CTX_wm_space_image(C); Image *ima = CTX_data_edit_image(C); ARegion *ar = CTX_wm_region(C); Object *obedit = CTX_data_edit_object(C); Scene *scene = CTX_data_scene(C); ToolSettings *ts = scene->toolsettings; BMEditMesh *em = BMEdit_FromObject(obedit); + const int use_face_center = (ts->uv_flag & UV_SYNC_SELECTION) ? + (ts->selectmode == SCE_SELECT_FACE) : + (ts->uv_selectmode == UV_SELECT_FACE); BMIter iter, liter; @@ -2925,9 +2955,10 @@ static int do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mov BLI_lasso_boundbox(&rect, mcords, moves); - if (ts->uv_selectmode == UV_SELECT_FACE) { /* Face Center Sel */ + if (use_face_center) { /* Face Center Sel */ change = FALSE; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + BM_elem_flag_disable(efa, BM_ELEM_TAG); /* assume not touched */ if ((select) != (uvedit_face_select_test(scene, em, efa))) { float cent[2]; @@ -2936,11 +2967,16 @@ static int do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mov if (BLI_rcti_isect_pt_v(&rect, screen_uv) && BLI_lasso_is_point_inside(mcords, moves, screen_uv[0], screen_uv[1], V2D_IS_CLIPPED)) { - uvedit_face_select_enable(scene, em, efa, FALSE); + BM_elem_flag_enable(efa, BM_ELEM_TAG); change = TRUE; } } } + + /* (de)selects all tagged faces and deals with sticky modes */ + if (change) { + uv_faces_do_sticky(sima, scene, obedit, select); + } } else { /* Vert Sel */ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { @@ -3397,7 +3433,7 @@ static int hide_exec(bContext *C, wmOperator *op) MTexPoly *tf; int swap = RNA_boolean_get(op->ptr, "unselected"); Image *ima = sima ? sima->image : NULL; - int facemode = (ts->uv_selectmode == UV_SELECT_FACE); + const int use_face_center = (ts->uv_selectmode == UV_SELECT_FACE); if (ts->uv_flag & UV_SYNC_SELECTION) { EDBM_mesh_hide(em, swap); @@ -3427,7 +3463,7 @@ static int hide_exec(bContext *C, wmOperator *op) if (hide) { /* note, a special case for edges could be used, * for now edges act like verts and get flushed */ - if (facemode) { + if (use_face_center) { if (em->selectmode == SCE_SELECT_FACE) { /* check that every UV is selected */ if (bm_face_is_all_uv_sel(em->bm, efa, TRUE) == !swap) { @@ -3445,8 +3481,6 @@ static int hide_exec(bContext *C, wmOperator *op) } } if (!swap) uvedit_face_select_disable(scene, em, efa); - - } } else if (em->selectmode == SCE_SELECT_FACE) { @@ -3509,8 +3543,8 @@ static int reveal_exec(bContext *C, wmOperator *UNUSED(op)) BMLoop *l; BMIter iter, liter; MLoopUV *luv; - int facemode = (ts->uv_selectmode == UV_SELECT_FACE); - int stickymode = sima ? (sima->sticky != SI_STICKY_DISABLE) : 1; + const int use_face_center = (ts->uv_selectmode == UV_SELECT_FACE); + const int stickymode = sima ? (sima->sticky != SI_STICKY_DISABLE) : 1; /* note on tagging, selecting faces needs to be delayed so it doesn't select the verts and * confuse our checks on selected verts. */ @@ -3522,7 +3556,7 @@ static int reveal_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } - if (facemode) { + if (use_face_center) { if (em->selectmode == SCE_SELECT_FACE) { BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BM_elem_flag_disable(efa, BM_ELEM_TAG); -- cgit v1.2.3 From c71ab7e774aa17651d4604110eba894dc1c009ba Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 26 Nov 2012 17:38:03 +0000 Subject: Fix wrong color space used for generated float images --- source/blender/blenkernel/intern/image.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index e4b9edacc7e..f09f128e874 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -663,6 +663,13 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char BKE_image_buf_fill_color(rect, rect_float, width, height, color); } + if (rect_float) { + /* both byte and float buffers are filling in sRGB space, need to linearize float buffer after BKE_image_buf_fill* functions */ + + IMB_buffer_float_from_float(rect_float, rect_float, ibuf->channels, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB, + ibuf->flags & IB_cm_predivide, ibuf->x, ibuf->y, ibuf->x, ibuf->x); + } + return ibuf; } -- cgit v1.2.3 From 864c4112e9ac6891b58e94e563e2342ea1d895b8 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 26 Nov 2012 19:10:34 +0000 Subject: Fix #33316: mesh edge short path select was wrong on large/small objects. --- source/blender/editors/mesh/editmesh_select.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index a6b798c8887..b46961a95d7 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -1267,12 +1267,12 @@ static float step_cost_3_v3(const float v1[3], const float v2[3], const float v3 /* The cost is based on the simple sum of the length of the two edgees... */ sub_v3_v3v3(d1, v2, v1); sub_v3_v3v3(d2, v3, v2); - cost = len_v3(d1) + len_v3(d2); + cost = normalize_v3(d1) + normalize_v3(d2); /* but is biased to give higher values to sharp turns, so that it will take * paths with fewer "turns" when selecting between equal-weighted paths between * the two edges */ - cost = cost + 0.5f * cost * (2.0f - sqrtf(fabsf(dot_v3v3(d1, d2)))); + cost = cost * (1.0f + 0.5f * (2.0f - sqrtf(fabsf(dot_v3v3(d1, d2))))); return cost; } -- cgit v1.2.3 From 5393922d1dd61720d3fc85fb04001749f366b765 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Mon, 26 Nov 2012 19:50:08 +0000 Subject: Remove non existent pthread include directory for MinGW, also slight message correction for 64 bit MinGW --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 48da0203318..cb42f081b2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -872,7 +872,7 @@ elseif(WIN32) # Setup 64bit and 64bit windows systems if(WITH_MINGW64) - message("Set 64 bit compiler for MinGW.") + message("Compiling for 64 bit with MinGW-w64.") set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/mingw64) endif() else() @@ -1220,7 +1220,7 @@ elseif(WIN32) #comes with own pthread library if(NOT WITH_MINGW64) set(PTHREADS ${LIBDIR}/pthreads) - set(PTHREADS_INCLUDE_DIRS ${PTHREADS}/include) + #set(PTHREADS_INCLUDE_DIRS ${PTHREADS}/include) set(PTHREADS_LIBPATH ${PTHREADS}/lib) set(PTHREADS_LIBRARIES pthreadGC2) endif() -- cgit v1.2.3 From 42dc0dc5efce87d0dbe96ba7892136774db34746 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 26 Nov 2012 20:37:04 +0000 Subject: Fix #33226: error loading .blend files with different endian on Mac. The cause was wrong inline and pure attributes on the endian switch function. --- source/blender/blenlib/BLI_endian_switch.h | 3 +-- source/blender/blenlib/BLI_rect.h | 14 +++----------- source/blender/blenlib/BLI_utildefines.h | 10 ++++++---- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/source/blender/blenlib/BLI_endian_switch.h b/source/blender/blenlib/BLI_endian_switch.h index 7cb2790525d..f48b1b072c3 100644 --- a/source/blender/blenlib/BLI_endian_switch.h +++ b/source/blender/blenlib/BLI_endian_switch.h @@ -29,8 +29,7 @@ #ifdef __GNUC__ # define ATTR_ENDIAN_SWITCH \ - __attribute__((nonnull(1))) \ - __attribute__((pure)) + __attribute__((nonnull(1))) #else # define ATTR_ENDIAN_SWITCH #endif diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h index f84820e94f3..f2e26093711 100644 --- a/source/blender/blenlib/BLI_rect.h +++ b/source/blender/blenlib/BLI_rect.h @@ -33,6 +33,9 @@ * \ingroup bli */ +#include "DNA_vec_types.h" +#include "BLI_utildefines.h" + struct rctf; struct rcti; @@ -75,17 +78,6 @@ void BLI_rctf_rcti_copy(struct rctf *dst, const struct rcti *src); void print_rctf(const char *str, const struct rctf *rect); void print_rcti(const char *str, const struct rcti *rect); -/* hrmf, we need to work out this inline stuff */ -#if defined(_MSC_VER) -# define BLI_INLINE static __forceinline -#elif defined(__GNUC__) -# define BLI_INLINE static inline __attribute((always_inline)) -#else -/* #warning "MSC/GNUC defines not found, inline non-functional" */ -# define BLI_INLINE static -#endif - -#include "DNA_vec_types.h" BLI_INLINE float BLI_rcti_cent_x_fl(const struct rcti *rct) { return (float)(rct->xmin + rct->xmax) / 2.0f; } BLI_INLINE float BLI_rcti_cent_y_fl(const struct rcti *rct) { return (float)(rct->ymin + rct->ymax) / 2.0f; } BLI_INLINE int BLI_rcti_cent_x(const struct rcti *rct) { return (rct->xmin + rct->xmax) / 2; } diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index a22aa0c13d7..7c3b70545d6 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -324,11 +324,13 @@ /*little macro so inline keyword works*/ #if defined(_MSC_VER) # define BLI_INLINE static __forceinline -#elif defined(__GNUC__) -# define BLI_INLINE static inline __attribute((always_inline)) #else -/* #warning "MSC/GNUC defines not found, inline non-functional" */ -# define BLI_INLINE static +# if (defined(__APPLE__) && defined(__ppc__)) +/* static inline __attribute__ here breaks osx ppc gcc42 build */ +# define BLI_INLINE static __attribute__((always_inline)) +# else +# define BLI_INLINE static inline __attribute__((always_inline)) +# endif #endif -- cgit v1.2.3 From eab58bf994323a53311543d7d706b0be87ffe197 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 26 Nov 2012 21:25:50 +0000 Subject: Spell check updates... --- release/scripts/modules/bl_i18n_utils/spell_check_utils.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py index 34eab11f9d4..fbe405a61c6 100644 --- a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py +++ b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py @@ -426,12 +426,14 @@ dict_uimsgs = { "fh", "fov", "fft", + "futura", "gfx", "gl", "glsl", "gpl", "gpu", "gpus", "hc", + "hdc", "hdr", "hh", "mm", "ss", "ff", # hh:mm:ss:ff timecode "hsv", "hsva", @@ -442,6 +444,7 @@ dict_uimsgs = { "mux", "ndof", "ppc", + "precisa", "px", "qmc", "rgb", "rgba", -- cgit v1.2.3 From ceed3ef640bb40e1232feeb409220fe19011bc43 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 26 Nov 2012 21:59:41 +0000 Subject: Fix #32907: failure rendering a complex node setup, hitting fixed max number of closures limit. Optimized the code now so it can handle more. Change SVM mix/add closure handling, now we transform the node graph so that the mix weights are fed into the closure nodes directly. --- intern/cycles/kernel/svm/svm_closure.h | 225 +++++++++++++++++++-------------- intern/cycles/render/graph.cpp | 104 ++++++++++++++- intern/cycles/render/graph.h | 17 ++- intern/cycles/render/nodes.cpp | 59 +++++++-- intern/cycles/render/nodes.h | 5 + intern/cycles/render/svm.cpp | 124 ++++-------------- intern/cycles/render/svm.h | 9 +- 7 files changed, 318 insertions(+), 225 deletions(-) diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index a4f8546f62b..7140b4971ea 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -64,11 +64,22 @@ __device_inline ShaderClosure *svm_node_closure_get(ShaderData *sd) #endif } -__device_inline void svm_node_closure_set_mix_weight(ShaderClosure *sc, float mix_weight) +__device_inline ShaderClosure *svm_node_closure_get_weight(ShaderData *sd, float mix_weight) { #ifdef __MULTI_CLOSURE__ + ShaderClosure *sc = &sd->closure[sd->num_closure]; + sc->weight *= mix_weight; sc->sample_weight = fabsf(average(sc->weight)); + + if(sc->sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE) { + sd->num_closure++; + return sc; + } + + return NULL; +#else + return &sd->closure; #endif } @@ -101,33 +112,39 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st switch(type) { case CLOSURE_BSDF_DIFFUSE_ID: { - ShaderClosure *sc = svm_node_closure_get(sd); - sc->N = N; - svm_node_closure_set_mix_weight(sc, mix_weight); + ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); - float roughness = param1; + if(sc) { + sc->N = N; - if(roughness == 0.0f) { - sd->flag |= bsdf_diffuse_setup(sc); - } - else { - sc->data0 = roughness; - sd->flag |= bsdf_oren_nayar_setup(sc); + float roughness = param1; + + if(roughness == 0.0f) { + sd->flag |= bsdf_diffuse_setup(sc); + } + else { + sc->data0 = roughness; + sd->flag |= bsdf_oren_nayar_setup(sc); + } } break; } case CLOSURE_BSDF_TRANSLUCENT_ID: { - ShaderClosure *sc = svm_node_closure_get(sd); - sc->N = N; - svm_node_closure_set_mix_weight(sc, mix_weight); - sd->flag |= bsdf_translucent_setup(sc); + ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); + + if(sc) { + sc->N = N; + sd->flag |= bsdf_translucent_setup(sc); + } break; } case CLOSURE_BSDF_TRANSPARENT_ID: { - ShaderClosure *sc = svm_node_closure_get(sd); - sc->N = N; - svm_node_closure_set_mix_weight(sc, mix_weight); - sd->flag |= bsdf_transparent_setup(sc); + ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); + + if(sc) { + sc->N = N; + sd->flag |= bsdf_transparent_setup(sc); + } break; } case CLOSURE_BSDF_REFLECTION_ID: @@ -137,18 +154,20 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE)) break; #endif - ShaderClosure *sc = svm_node_closure_get(sd); - sc->N = N; - sc->data0 = param1; - svm_node_closure_set_mix_weight(sc, mix_weight); - - /* setup bsdf */ - if(type == CLOSURE_BSDF_REFLECTION_ID) - sd->flag |= bsdf_reflection_setup(sc); - else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID) - sd->flag |= bsdf_microfacet_beckmann_setup(sc); - else - sd->flag |= bsdf_microfacet_ggx_setup(sc); + ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); + + if(sc) { + sc->N = N; + sc->data0 = param1; + + /* setup bsdf */ + if(type == CLOSURE_BSDF_REFLECTION_ID) + sd->flag |= bsdf_reflection_setup(sc); + else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID) + sd->flag |= bsdf_microfacet_beckmann_setup(sc); + else + sd->flag |= bsdf_microfacet_ggx_setup(sc); + } break; } @@ -159,21 +178,23 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE)) break; #endif - ShaderClosure *sc = svm_node_closure_get(sd); - sc->N = N; - sc->data0 = param1; - svm_node_closure_set_mix_weight(sc, mix_weight); - - float eta = fmaxf(param2, 1.0f + 1e-5f); - sc->data1 = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta; - - /* setup bsdf */ - if(type == CLOSURE_BSDF_REFRACTION_ID) - sd->flag |= bsdf_refraction_setup(sc); - else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) - sd->flag |= bsdf_microfacet_beckmann_refraction_setup(sc); - else - sd->flag |= bsdf_microfacet_ggx_refraction_setup(sc); + ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); + + if(sc) { + sc->N = N; + sc->data0 = param1; + + float eta = fmaxf(param2, 1.0f + 1e-5f); + sc->data1 = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta; + + /* setup bsdf */ + if(type == CLOSURE_BSDF_REFRACTION_ID) + sd->flag |= bsdf_refraction_setup(sc); + else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) + sd->flag |= bsdf_microfacet_beckmann_refraction_setup(sc); + else + sd->flag |= bsdf_microfacet_ggx_refraction_setup(sc); + } break; } @@ -195,32 +216,36 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st #ifdef __MULTI_CLOSURE__ /* reflection */ - ShaderClosure *sc = svm_node_closure_get(sd); - sc->N = N; - + ShaderClosure *sc = &sd->closure[sd->num_closure]; float3 weight = sc->weight; float sample_weight = sc->sample_weight; - svm_node_closure_set_mix_weight(sc, mix_weight*fresnel); - svm_node_glass_setup(sd, sc, type, eta, roughness, false); + sc = svm_node_closure_get_weight(sd, mix_weight*fresnel); - /* refraction */ - sc = svm_node_closure_get(sd); - sc->N = N; + if(sc) { + sc->N = N; + svm_node_glass_setup(sd, sc, type, eta, roughness, false); + } + /* refraction */ + sc = &sd->closure[sd->num_closure]; sc->weight = weight; sc->sample_weight = sample_weight; - svm_node_closure_set_mix_weight(sc, mix_weight*(1.0f - fresnel)); - svm_node_glass_setup(sd, sc, type, eta, roughness, true); -#else - ShaderClosure *sc = svm_node_closure_get(sd); - sc->N = N; + sc = svm_node_closure_get_weight(sd, mix_weight*(1.0f - fresnel)); - bool refract = (randb > fresnel); + if(sc) { + sc->N = N; + svm_node_glass_setup(sd, sc, type, eta, roughness, true); + } +#else + ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); - svm_node_closure_set_mix_weight(sc, mix_weight); - svm_node_glass_setup(sd, sc, type, eta, roughness, refract); + if(sc) { + sc->N = N; + bool refract = (randb > fresnel); + svm_node_glass_setup(sd, sc, type, eta, roughness, refract); + } #endif break; @@ -230,46 +255,50 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE)) break; #endif - ShaderClosure *sc = svm_node_closure_get(sd); - sc->N = N; - svm_node_closure_set_mix_weight(sc, mix_weight); + ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); + + if(sc) { + sc->N = N; #ifdef __ANISOTROPIC__ - sc->T = stack_load_float3(stack, data_node.z); + sc->T = stack_load_float3(stack, data_node.z); - /* rotate tangent */ - float rotation = stack_load_float(stack, data_node.w); + /* rotate tangent */ + float rotation = stack_load_float(stack, data_node.w); - if(rotation != 0.0f) - sc->T = rotate_around_axis(sc->T, sc->N, rotation * 2.0f * M_PI_F); + if(rotation != 0.0f) + sc->T = rotate_around_axis(sc->T, sc->N, rotation * 2.0f * M_PI_F); - /* compute roughness */ - float roughness = param1; - float anisotropy = clamp(param2, -0.99f, 0.99f); + /* compute roughness */ + float roughness = param1; + float anisotropy = clamp(param2, -0.99f, 0.99f); - if(anisotropy < 0.0f) { - sc->data0 = roughness/(1.0f + anisotropy); - sc->data1 = roughness*(1.0f + anisotropy); - } - else { - sc->data0 = roughness*(1.0f - anisotropy); - sc->data1 = roughness/(1.0f - anisotropy); - } + if(anisotropy < 0.0f) { + sc->data0 = roughness/(1.0f + anisotropy); + sc->data1 = roughness*(1.0f + anisotropy); + } + else { + sc->data0 = roughness*(1.0f - anisotropy); + sc->data1 = roughness/(1.0f - anisotropy); + } - sd->flag |= bsdf_ward_setup(sc); + sd->flag |= bsdf_ward_setup(sc); #else - sd->flag |= bsdf_diffuse_setup(sc); + sd->flag |= bsdf_diffuse_setup(sc); #endif + } break; } case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: { - ShaderClosure *sc = svm_node_closure_get(sd); - sc->N = N; - svm_node_closure_set_mix_weight(sc, mix_weight); + ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); - /* sigma */ - sc->data0 = clamp(param1, 0.0f, 1.0f); - sd->flag |= bsdf_ashikhmin_velvet_setup(sc); + if(sc) { + sc->N = N; + + /* sigma */ + sc->data0 = clamp(param1, 0.0f, 1.0f); + sd->flag |= bsdf_ashikhmin_velvet_setup(sc); + } break; } default: @@ -298,19 +327,21 @@ __device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float * switch(type) { case CLOSURE_VOLUME_TRANSPARENT_ID: { - ShaderClosure *sc = svm_node_closure_get(sd); - svm_node_closure_set_mix_weight(sc, mix_weight); + ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); - float density = param1; - sd->flag |= volume_transparent_setup(sc, density); + if(sc) { + float density = param1; + sd->flag |= volume_transparent_setup(sc, density); + } break; } case CLOSURE_VOLUME_ISOTROPIC_ID: { - ShaderClosure *sc = svm_node_closure_get(sd); - svm_node_closure_set_mix_weight(sc, mix_weight); + ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); - float density = param1; - sd->flag |= volume_isotropic_setup(sc, density); + if(sc) { + float density = param1; + sd->flag |= volume_isotropic_setup(sc, density); + } break; } default: diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index f71675dbda3..14b219383d0 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -37,7 +37,7 @@ ShaderInput::ShaderInput(ShaderNode *parent_, const char *name_, ShaderSocketTyp value = make_float3(0, 0, 0); stack_offset = SVM_STACK_INVALID; default_value = NONE; - osl_only = false; + usage = USE_ALL; } ShaderOutput::ShaderOutput(ShaderNode *parent_, const char *name_, ShaderSocketType type_) @@ -85,27 +85,29 @@ ShaderOutput *ShaderNode::output(const char *name) return NULL; } -ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float value) +ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float value, int usage) { ShaderInput *input = new ShaderInput(this, name, type); input->value.x = value; + input->usage = usage; inputs.push_back(input); return input; } -ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float3 value) +ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float3 value, int usage) { ShaderInput *input = new ShaderInput(this, name, type); input->value = value; + input->usage = usage; inputs.push_back(input); return input; } -ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, bool osl_only) +ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, int usage) { ShaderInput *input = add_input(name, type); input->default_value = value; - input->osl_only = osl_only; + input->usage = usage; return input; } @@ -219,7 +221,7 @@ void ShaderGraph::disconnect(ShaderInput *to) from->links.erase(remove(from->links.begin(), from->links.end(), to), from->links.end()); } -void ShaderGraph::finalize(bool do_bump, bool do_osl) +void ShaderGraph::finalize(bool do_bump, bool do_osl, bool do_multi_transform) { /* before compiling, the shader graph may undergo a number of modifications. * currently we set default geometry shader inputs, and create automatic bump @@ -234,6 +236,18 @@ void ShaderGraph::finalize(bool do_bump, bool do_osl) if(do_bump) bump_from_displacement(); + if(do_multi_transform) { + ShaderInput *surface_in = output()->input("Surface"); + ShaderInput *volume_in = output()->input("Volume"); + + /* todo: make this work when surface and volume closures are tangled up */ + + if(surface_in->link) + transform_multi_closure(surface_in->link->parent, NULL, false); + if(volume_in->link) + transform_multi_closure(volume_in->link->parent, NULL, true); + } + finalized = true; } } @@ -440,7 +454,7 @@ void ShaderGraph::default_inputs(bool do_osl) foreach(ShaderNode *node, nodes) { foreach(ShaderInput *input, node->inputs) { - if(!input->link && !(input->osl_only && !do_osl)) { + if(!input->link && ((input->usage & ShaderInput::USE_SVM) || do_osl)) { if(input->default_value == ShaderInput::TEXTURE_GENERATED) { if(!texco) texco = new TextureCoordinateNode(); @@ -629,5 +643,81 @@ void ShaderGraph::bump_from_displacement() add(pair.second); } +void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume) +{ + /* for SVM in multi closure mode, this transforms the shader mix/add part of + * the graph into nodes that feed weights into closure nodes. this is too + * avoid building a closure tree and then flattening it, and instead write it + * directly to an array */ + + if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) { + ShaderInput *fin = node->input("Fac"); + ShaderInput *cl1in = node->input("Closure1"); + ShaderInput *cl2in = node->input("Closure2"); + ShaderOutput *weight1_out, *weight2_out; + + if(fin) { + /* mix closure: add node to mix closure weights */ + ShaderNode *mix_node = add(new MixClosureWeightNode()); + ShaderInput *fac_in = mix_node->input("Fac"); + ShaderInput *weight_in = mix_node->input("Weight"); + + if(fin->link) + connect(fin->link, fac_in); + else + fac_in->value = fin->value; + + if(weight_out) + connect(weight_out, weight_in); + + weight1_out = mix_node->output("Weight1"); + weight2_out = mix_node->output("Weight2"); + } + else { + /* add closure: just pass on any weights */ + weight1_out = weight_out; + weight2_out = weight_out; + } + + if(cl1in->link) + transform_multi_closure(cl1in->link->parent, weight1_out, volume); + if(cl2in->link) + transform_multi_closure(cl2in->link->parent, weight2_out, volume); + } + else { + ShaderInput *weight_in = node->input((volume)? "VolumeMixWeight": "SurfaceMixWeight"); + + /* not a closure node? */ + if(!weight_in) + return; + + /* already has a weight connected to it? add weights */ + if(weight_in->link || weight_in->value.x != 0.0f) { + ShaderNode *math_node = add(new MathNode()); + ShaderInput *value1_in = math_node->input("Value1"); + ShaderInput *value2_in = math_node->input("Value2"); + + if(weight_in->link) + connect(weight_in->link, value1_in); + else + value1_in->value = weight_in->value; + + if(weight_out) + connect(weight_out, value2_in); + else + value2_in->value.x = 1.0f; + + weight_out = math_node->output("Value"); + disconnect(weight_in); + } + + /* connected to closure mix weight */ + if(weight_out) + connect(weight_out, weight_in); + else + weight_in->value.x += 1.0f; + } +} + CCL_NAMESPACE_END diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h index 373c7e0eaab..b79167839ab 100644 --- a/intern/cycles/render/graph.h +++ b/intern/cycles/render/graph.h @@ -118,6 +118,12 @@ public: NONE }; + enum Usage { + USE_SVM = 1, + USE_OSL = 2, + USE_ALL = USE_SVM|USE_OSL + }; + ShaderInput(ShaderNode *parent, const char *name, ShaderSocketType type); void set(const float3& v) { value = v; } void set(float f) { value = make_float3(f, 0, 0); } @@ -134,7 +140,7 @@ public: ustring value_string; int stack_offset; /* for SVM compiler */ - bool osl_only; + int usage; }; /* Output @@ -167,9 +173,9 @@ public: ShaderInput *input(const char *name); ShaderOutput *output(const char *name); - ShaderInput *add_input(const char *name, ShaderSocketType type, float value=0.0f); - ShaderInput *add_input(const char *name, ShaderSocketType type, float3 value); - ShaderInput *add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, bool osl_only=false); + ShaderInput *add_input(const char *name, ShaderSocketType type, float value=0.0f, int usage=ShaderInput::USE_ALL); + ShaderInput *add_input(const char *name, ShaderSocketType type, float3 value, int usage=ShaderInput::USE_ALL); + ShaderInput *add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, int usage=ShaderInput::USE_ALL); ShaderOutput *add_output(const char *name, ShaderSocketType type); virtual ShaderNode *clone() const = 0; @@ -227,7 +233,7 @@ public: void connect(ShaderOutput *from, ShaderInput *to); void disconnect(ShaderInput *to); - void finalize(bool do_bump = false, bool do_osl = false); + void finalize(bool do_bump = false, bool do_osl = false, bool do_multi_closure = false); protected: typedef pair NodePair; @@ -241,6 +247,7 @@ protected: void bump_from_displacement(); void refine_bump_nodes(); void default_inputs(bool do_osl); + void transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume); }; CCL_NAMESPACE_END diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 48a8565ed98..12bbc019644 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1257,6 +1257,7 @@ BsdfNode::BsdfNode() add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f)); add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL); + add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM); add_output("BSDF", SHADER_SOCKET_CLOSURE); } @@ -1544,6 +1545,8 @@ EmissionNode::EmissionNode() add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f)); add_input("Strength", SHADER_SOCKET_FLOAT, 10.0f); + add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM); + add_output("Emission", SHADER_SOCKET_CLOSURE); } @@ -1578,6 +1581,8 @@ BackgroundNode::BackgroundNode() { add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f)); add_input("Strength", SHADER_SOCKET_FLOAT, 1.0f); + add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM); + add_output("Background", SHADER_SOCKET_CLOSURE); } @@ -1607,6 +1612,9 @@ void BackgroundNode::compile(OSLCompiler& compiler) HoldoutNode::HoldoutNode() : ShaderNode("holdout") { + add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM); + add_input("VolumeMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM); + add_output("Holdout", SHADER_SOCKET_CLOSURE); } @@ -1625,9 +1633,10 @@ void HoldoutNode::compile(OSLCompiler& compiler) AmbientOcclusionNode::AmbientOcclusionNode() : ShaderNode("ambient_occlusion") { - add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true); - + add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL); add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f)); + add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM); + add_output("AO", SHADER_SOCKET_CLOSURE); } @@ -1659,6 +1668,7 @@ VolumeNode::VolumeNode() add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f)); add_input("Density", SHADER_SOCKET_FLOAT, 1.0f); + add_input("VolumeMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM); add_output("Volume", SHADER_SOCKET_CLOSURE); } @@ -1737,7 +1747,7 @@ void IsotropicVolumeNode::compile(OSLCompiler& compiler) GeometryNode::GeometryNode() : ShaderNode("geometry") { - add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true); + add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL); add_output("Position", SHADER_SOCKET_POINT); add_output("Normal", SHADER_SOCKET_NORMAL); add_output("Tangent", SHADER_SOCKET_NORMAL); @@ -1825,7 +1835,7 @@ void GeometryNode::compile(OSLCompiler& compiler) TextureCoordinateNode::TextureCoordinateNode() : ShaderNode("texture_coordinate") { - add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true); + add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL); add_output("Generated", SHADER_SOCKET_POINT); add_output("Normal", SHADER_SOCKET_NORMAL); add_output("UV", SHADER_SOCKET_POINT); @@ -2315,6 +2325,39 @@ void MixClosureNode::compile(OSLCompiler& compiler) compiler.add(this, "node_mix_closure"); } +/* Mix Closure */ + +MixClosureWeightNode::MixClosureWeightNode() +: ShaderNode("mix_closure_weight") +{ + add_input("Weight", SHADER_SOCKET_FLOAT, 1.0f); + add_input("Fac", SHADER_SOCKET_FLOAT, 1.0f); + add_output("Weight1", SHADER_SOCKET_FLOAT); + add_output("Weight2", SHADER_SOCKET_FLOAT); +} + +void MixClosureWeightNode::compile(SVMCompiler& compiler) +{ + ShaderInput *weight_in = input("Weight"); + ShaderInput *fac_in = input("Fac"); + ShaderOutput *weight1_out = output("Weight1"); + ShaderOutput *weight2_out = output("Weight2"); + + compiler.stack_assign(weight_in); + compiler.stack_assign(fac_in); + compiler.stack_assign(weight1_out); + compiler.stack_assign(weight2_out); + + compiler.add_node(NODE_MIX_CLOSURE, + compiler.encode_uchar4(fac_in->stack_offset, weight_in->stack_offset, + weight1_out->stack_offset, weight2_out->stack_offset)); +} + +void MixClosureWeightNode::compile(OSLCompiler& compiler) +{ + assert(0); +} + /* Invert */ InvertNode::InvertNode() @@ -2680,7 +2723,7 @@ void CameraNode::compile(OSLCompiler& compiler) FresnelNode::FresnelNode() : ShaderNode("Fresnel") { - add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true); + add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL); add_input("IOR", SHADER_SOCKET_FLOAT, 1.45f); add_output("Fac", SHADER_SOCKET_FLOAT); } @@ -2705,7 +2748,7 @@ void FresnelNode::compile(OSLCompiler& compiler) LayerWeightNode::LayerWeightNode() : ShaderNode("LayerWeight") { - add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true); + add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL); add_input("Blend", SHADER_SOCKET_FLOAT, 0.5f); add_output("Fresnel", SHADER_SOCKET_FLOAT); @@ -3080,7 +3123,7 @@ NormalMapNode::NormalMapNode() space = ustring("Tangent"); attribute = ustring(""); - add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true); + add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL); add_input("Strength", SHADER_SOCKET_FLOAT, 1.0f); add_input("Color", SHADER_SOCKET_COLOR); @@ -3185,7 +3228,7 @@ TangentNode::TangentNode() axis = ustring("X"); attribute = ustring(""); - add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true); + add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL); add_output("Tangent", SHADER_SOCKET_NORMAL); } diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 3e89c2286ad..67733142dd1 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -351,6 +351,11 @@ public: SHADER_NODE_CLASS(MixClosureNode) }; +class MixClosureWeightNode : public ShaderNode { +public: + SHADER_NODE_CLASS(MixClosureWeightNode); +}; + class InvertNode : public ShaderNode { public: SHADER_NODE_CLASS(InvertNode) diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index 73904eac41d..50b3bb59ed4 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -487,106 +487,30 @@ void SVMCompiler::generate_closure(ShaderNode *node, set& done) } } -void SVMCompiler::count_closure_users(ShaderNode *node, map& closure_data) -{ - /* here we count the number of times each closure node is used, so that - * the last time we encounter it we can run the actually code with the - * weights from all other places added together */ - - if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) { - ShaderInput *cl1in = node->input("Closure1"); - ShaderInput *cl2in = node->input("Closure2"); - - if(cl1in->link) - count_closure_users(cl1in->link->parent, closure_data); - if(cl2in->link) - count_closure_users(cl2in->link->parent, closure_data); - } - else { - MultiClosureData data; - - if(closure_data.find(node) == closure_data.end()) { - data.stack_offset = SVM_STACK_INVALID; - data.users = 1; - } - else { - data = closure_data[node]; - data.users++; - } - - closure_data[node] = data; - } -} - -void SVMCompiler::generate_multi_closure(ShaderNode *node, set& done, - map& closure_data, uint in_offset) +void SVMCompiler::generate_multi_closure(ShaderNode *node, set& done) { /* todo: the weaks point here is that unlike the single closure sampling * we will evaluate all nodes even if they are used as input for closures * that are unused. it's not clear what would be the best way to skip such * nodes at runtime, especially if they are tangled up */ + + /* only generate once */ + if(done.find(node) != done.end()) + return; + + done.insert(node); if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) { - ShaderInput *fin = node->input("Fac"); + /* weighting is already taken care of in ShaderGraph::transform_multi_closure */ ShaderInput *cl1in = node->input("Closure1"); ShaderInput *cl2in = node->input("Closure2"); - uint out1_offset = SVM_STACK_INVALID; - uint out2_offset = SVM_STACK_INVALID; - - if(fin) { - /* mix closure */ - set dependencies; - find_dependencies(dependencies, done, fin); - generate_svm_nodes(dependencies, done); - - stack_assign(fin); - - if(cl1in->link) - out1_offset = stack_find_offset(SHADER_SOCKET_FLOAT); - if(cl2in->link) - out2_offset = stack_find_offset(SHADER_SOCKET_FLOAT); - - add_node(NODE_MIX_CLOSURE, - encode_uchar4(fin->stack_offset, in_offset, out1_offset, out2_offset)); - } - else { - /* add closure */ - out1_offset = in_offset; - out2_offset = in_offset; - } - if(cl1in->link) - generate_multi_closure(cl1in->link->parent, done, closure_data, out1_offset); - + generate_multi_closure(cl1in->link->parent, done); if(cl2in->link) - generate_multi_closure(cl2in->link->parent, done, closure_data, out2_offset); - - if(in_offset != SVM_STACK_INVALID) - stack_clear_offset(SHADER_SOCKET_FLOAT, in_offset); + generate_multi_closure(cl2in->link->parent, done); } else { - MultiClosureData data = closure_data[node]; - - if(data.stack_offset == SVM_STACK_INVALID) { - /* first time using closure, use stack position for weight */ - data.stack_offset = in_offset; - } - else { - /* not first time using, add weights together */ - add_node(NODE_MATH, NODE_MATH_ADD, data.stack_offset, in_offset); - add_node(NODE_MATH, data.stack_offset); - - stack_clear_offset(SHADER_SOCKET_FLOAT, in_offset); - } - - data.users--; - closure_data[node] = data; - - /* still users coming? skip generating closure code */ - if(data.users > 0) - return; - /* execute dependencies for closure */ foreach(ShaderInput *in, node->inputs) { if(!node_skip_input(node, in) && in->link) { @@ -596,7 +520,16 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set& don } } - mix_weight_offset = data.stack_offset; + /* closure mix weight */ + const char *weight_name = (current_type == SHADER_TYPE_VOLUME)? "VolumeMixWeight": "SurfaceMixWeight"; + ShaderInput *weight_in = node->input(weight_name); + + if(weight_in && (weight_in->link || weight_in->value.x != 1.0f)) { + stack_assign(weight_in); + mix_weight_offset = weight_in->stack_offset; + } + else + mix_weight_offset = SVM_STACK_INVALID; /* compile closure itself */ node->compile(*this); @@ -609,11 +542,6 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set& don current_shader->has_surface_emission = true; if(node->name == ustring("transparent")) current_shader->has_surface_transparent = true; - - /* end node is added outside of this */ - - if(data.stack_offset != SVM_STACK_INVALID) - stack_clear_offset(SHADER_SOCKET_FLOAT, data.stack_offset); } } @@ -685,12 +613,8 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty if(generate) { set done; - if(use_multi_closure) { - map closure_data; - - count_closure_users(clin->link->parent, closure_data); - generate_multi_closure(clin->link->parent, done, closure_data, SVM_STACK_INVALID); - } + if(use_multi_closure) + generate_multi_closure(clin->link->parent, done); else generate_closure(clin->link->parent, done); } @@ -713,9 +637,9 @@ void SVMCompiler::compile(Shader *shader, vector& global_svm_nodes, int in shader->graph_bump = shader->graph->copy(); /* finalize */ - shader->graph->finalize(false, false); + shader->graph->finalize(false, false, use_multi_closure); if(shader->graph_bump) - shader->graph_bump->finalize(true, false); + shader->graph_bump->finalize(true, false, use_multi_closure); current_shader = shader; diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h index c7b66d97289..720531c8c4b 100644 --- a/intern/cycles/render/svm.h +++ b/intern/cycles/render/svm.h @@ -130,14 +130,7 @@ protected: void generate_closure(ShaderNode *node, set& done); /* multi closure */ - struct MultiClosureData { - int stack_offset; - int users; - }; - - void generate_multi_closure(ShaderNode *node, set& done, - map& closure_data, uint in_offset); - void count_closure_users(ShaderNode *node, map& closure_data); + void generate_multi_closure(ShaderNode *node, set& done); /* compile */ void compile_type(Shader *shader, ShaderGraph *graph, ShaderType type); -- cgit v1.2.3 From f9e339ef005144ace447d686c4cecaa66f40cf1c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 Nov 2012 23:18:04 +0000 Subject: fix/workaround [#33281] script goes into not responding scanfill remove-doubles pass assumes ordered edges (as with curves), otherwise it can hang. workaround this problem by skipping removing-doubles for mesh ngons, since this isnt such a common case as it is with curves and we can just not support it. --- source/blender/blenkernel/intern/displist.c | 2 +- source/blender/blenkernel/intern/editderivedmesh.c | 2 +- source/blender/blenkernel/intern/mask_rasterize.c | 2 +- source/blender/blenkernel/intern/mesh.c | 2 +- source/blender/blenlib/BLI_scanfill.h | 13 +- source/blender/blenlib/intern/scanfill.c | 145 ++++++++++++--------- source/blender/bmesh/operators/bmo_triangulate.c | 2 +- source/blender/editors/uvedit/uvedit_unwrap_ops.c | 2 +- source/blender/windowmanager/intern/wm_gesture.c | 2 +- 9 files changed, 99 insertions(+), 73 deletions(-) diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index a78a9af54ae..083cb02fd3d 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -487,7 +487,7 @@ void BKE_displist_fill(ListBase *dispbase, ListBase *to, int flipnormal) } /* XXX (obedit && obedit->actcol)?(obedit->actcol-1):0)) { */ - if (totvert && (tot = BLI_scanfill_calc(&sf_ctx, FALSE))) { + if (totvert && (tot = BLI_scanfill_calc(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES))) { if (tot) { dlnew = MEM_callocN(sizeof(DispList), "filldisplist"); dlnew->type = DL_INDEX3; diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 8d430eb58b5..321a61ce238 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -215,7 +215,7 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm) /* complete the loop */ BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert); - totfilltri = BLI_scanfill_calc_ex(&sf_ctx, FALSE, efa->no); + totfilltri = BLI_scanfill_calc_ex(&sf_ctx, 0, efa->no); BLI_array_grow_items(looptris, totfilltri); for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) { diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 88393fab79c..2fa928e7c07 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -933,7 +933,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas } /* main scan-fill */ - sf_tri_tot = BLI_scanfill_calc_ex(&sf_ctx, FALSE, zvec); + sf_tri_tot = BLI_scanfill_calc_ex(&sf_ctx, 0, zvec); face_array = MEM_mallocN(sizeof(*face_array) * (sf_tri_tot + tot_feather_quads), "maskrast_face_index"); face_index = 0; diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index fd5af6a20bb..036f8f5e673 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -2607,7 +2607,7 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, } BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert_first); - totfilltri = BLI_scanfill_calc(&sf_ctx, FALSE); + totfilltri = BLI_scanfill_calc(&sf_ctx, 0); if (totfilltri) { BLI_array_grow_items(mface_to_poly_map, totfilltri); BLI_array_grow_items(mface, totfilltri); diff --git a/source/blender/blenlib/BLI_scanfill.h b/source/blender/blenlib/BLI_scanfill.h index 892afdd0b27..c8fd72bbbd2 100644 --- a/source/blender/blenlib/BLI_scanfill.h +++ b/source/blender/blenlib/BLI_scanfill.h @@ -94,9 +94,18 @@ typedef struct ScanFillFace { struct ScanFillVert *BLI_scanfill_vert_add(ScanFillContext *sf_ctx, const float vec[3]); struct ScanFillEdge *BLI_scanfill_edge_add(ScanFillContext *sf_ctx, struct ScanFillVert *v1, struct ScanFillVert *v2); +enum { + BLI_SCANFILL_CALC_QUADTRI_FASTPATH = (1 << 0), + + /* note: using BLI_SCANFILL_CALC_REMOVE_DOUBLES + * Assumes ordered edges, otherwise we risk an eternal loop + * removing double verts. - campbell */ + BLI_SCANFILL_CALC_REMOVE_DOUBLES = (1 << 1), +}; + int BLI_scanfill_begin(ScanFillContext *sf_ctx); -int BLI_scanfill_calc(ScanFillContext *sf_ctx, const short do_quad_tri_speedup); -int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const short do_quad_tri_speedup, +int BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag); +int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float nor_proj[3]); void BLI_scanfill_end(ScanFillContext *sf_ctx); diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c index 1b7858f7f88..defe500cb21 100644 --- a/source/blender/blenlib/intern/scanfill.c +++ b/source/blender/blenlib/intern/scanfill.c @@ -503,8 +503,7 @@ static void splitlist(ScanFillContext *sf_ctx, ListBase *tempve, ListBase *tempe } } - -static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf) +static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag) { ScanFillVertLink *sc = NULL, *sc1; ScanFillVert *eve, *v1, *v2, *v3; @@ -530,26 +529,28 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf) #endif /* STEP 0: remove zero sized edges */ - eed = sf_ctx->filledgebase.first; - while (eed) { - if (equals_v2v2(eed->v1->xy, eed->v2->xy)) { - if (eed->v1->f == SF_VERT_ZERO_LEN && eed->v2->f != SF_VERT_ZERO_LEN) { - eed->v2->f = SF_VERT_ZERO_LEN; - eed->v2->tmp.v = eed->v1->tmp.v; - } - else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f != SF_VERT_ZERO_LEN) { - eed->v1->f = SF_VERT_ZERO_LEN; - eed->v1->tmp.v = eed->v2->tmp.v; - } - else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f == SF_VERT_ZERO_LEN) { - eed->v1->tmp.v = eed->v2->tmp.v; - } - else { - eed->v2->f = SF_VERT_ZERO_LEN; - eed->v2->tmp.v = eed->v1; + if (flag & BLI_SCANFILL_CALC_REMOVE_DOUBLES) { + eed = sf_ctx->filledgebase.first; + while (eed) { + if (equals_v2v2(eed->v1->xy, eed->v2->xy)) { + if (eed->v1->f == SF_VERT_ZERO_LEN && eed->v2->f != SF_VERT_ZERO_LEN) { + eed->v2->f = SF_VERT_ZERO_LEN; + eed->v2->tmp.v = eed->v1->tmp.v; + } + else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f != SF_VERT_ZERO_LEN) { + eed->v1->f = SF_VERT_ZERO_LEN; + eed->v1->tmp.v = eed->v2->tmp.v; + } + else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f == SF_VERT_ZERO_LEN) { + eed->v1->tmp.v = eed->v2->tmp.v; + } + else { + eed->v2->f = SF_VERT_ZERO_LEN; + eed->v2->tmp.v = eed->v1; + } } + eed = eed->next; } - eed = eed->next; } /* STEP 1: make using FillVert and FillEdge lists a sorted @@ -572,28 +573,42 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf) qsort(sf_ctx->_scdata, verts, sizeof(ScanFillVertLink), vergscdata); - eed = sf_ctx->filledgebase.first; - while (eed) { - nexted = eed->next; - BLI_remlink(&sf_ctx->filledgebase, eed); - /* This code is for handling zero-length edges that get - * collapsed in step 0. It was removed for some time to - * fix trunk bug #4544, so if that comes back, this code - * may need some work, or there will have to be a better - * fix to #4544. */ - if (eed->v1->f == SF_VERT_ZERO_LEN) { - v1 = eed->v1; - while ((eed->v1->f == SF_VERT_ZERO_LEN) && (eed->v1->tmp.v != v1) && (eed->v1 != eed->v1->tmp.v)) - eed->v1 = eed->v1->tmp.v; + if (flag & BLI_SCANFILL_CALC_REMOVE_DOUBLES) { + for (eed = sf_ctx->filledgebase.first; eed; eed = nexted) { + nexted = eed->next; + BLI_remlink(&sf_ctx->filledgebase, eed); + /* This code is for handling zero-length edges that get + * collapsed in step 0. It was removed for some time to + * fix trunk bug #4544, so if that comes back, this code + * may need some work, or there will have to be a better + * fix to #4544. + * + * warning, this can hang on un-ordered edges, see: [#33281] + * for now disable 'BLI_SCANFILL_CALC_REMOVE_DOUBLES' for ngons. + */ + if (eed->v1->f == SF_VERT_ZERO_LEN) { + v1 = eed->v1; + while ((eed->v1->f == SF_VERT_ZERO_LEN) && (eed->v1->tmp.v != v1) && (eed->v1 != eed->v1->tmp.v)) + eed->v1 = eed->v1->tmp.v; + } + if (eed->v2->f == SF_VERT_ZERO_LEN) { + v2 = eed->v2; + while ((eed->v2->f == SF_VERT_ZERO_LEN) && (eed->v2->tmp.v != v2) && (eed->v2 != eed->v2->tmp.v)) + eed->v2 = eed->v2->tmp.v; + } + if (eed->v1 != eed->v2) { + addedgetoscanlist(sf_ctx, eed, verts); + } } - if (eed->v2->f == SF_VERT_ZERO_LEN) { - v2 = eed->v2; - while ((eed->v2->f == SF_VERT_ZERO_LEN) && (eed->v2->tmp.v != v2) && (eed->v2 != eed->v2->tmp.v)) - eed->v2 = eed->v2->tmp.v; + } + else { + for (eed = sf_ctx->filledgebase.first; eed; eed = nexted) { + nexted = eed->next; + BLI_remlink(&sf_ctx->filledgebase, eed); + if (eed->v1 != eed->v2) { + addedgetoscanlist(sf_ctx, eed, verts); + } } - if (eed->v1 != eed->v2) addedgetoscanlist(sf_ctx, eed, verts); - - eed = nexted; } #if 0 sc = scdata; @@ -775,12 +790,12 @@ int BLI_scanfill_begin(ScanFillContext *sf_ctx) return 1; } -int BLI_scanfill_calc(ScanFillContext *sf_ctx, const short do_quad_tri_speedup) +int BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag) { - return BLI_scanfill_calc_ex(sf_ctx, do_quad_tri_speedup, NULL); + return BLI_scanfill_calc_ex(sf_ctx, flag, NULL); } -int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const short do_quad_tri_speedup, const float nor_proj[3]) +int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float nor_proj[3]) { /* * - fill works with its own lists, so create that first (no faces!) @@ -810,30 +825,32 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const short do_quad_tri_speedu a += 1; } - if (do_quad_tri_speedup && (a == 3)) { - eve = sf_ctx->fillvertbase.first; + if (flag & BLI_SCANFILL_CALC_QUADTRI_FASTPATH) { + if (a == 3) { + eve = sf_ctx->fillvertbase.first; - addfillface(sf_ctx, eve, eve->next, eve->next->next); - return 1; - } - else if (do_quad_tri_speedup && (a == 4)) { - float vec1[3], vec2[3]; - - eve = sf_ctx->fillvertbase.first; - /* no need to check 'eve->next->next->next' is valid, already counted */ - /* use shortest diagonal for quad */ - sub_v3_v3v3(vec1, eve->co, eve->next->next->co); - sub_v3_v3v3(vec2, eve->next->co, eve->next->next->next->co); - - if (dot_v3v3(vec1, vec1) < dot_v3v3(vec2, vec2)) { addfillface(sf_ctx, eve, eve->next, eve->next->next); - addfillface(sf_ctx, eve->next->next, eve->next->next->next, eve); + return 1; } - else { - addfillface(sf_ctx, eve->next, eve->next->next, eve->next->next->next); - addfillface(sf_ctx, eve->next->next->next, eve, eve->next); + else if (a == 4) { + float vec1[3], vec2[3]; + + eve = sf_ctx->fillvertbase.first; + /* no need to check 'eve->next->next->next' is valid, already counted */ + /* use shortest diagonal for quad */ + sub_v3_v3v3(vec1, eve->co, eve->next->next->co); + sub_v3_v3v3(vec2, eve->next->co, eve->next->next->next->co); + + if (dot_v3v3(vec1, vec1) < dot_v3v3(vec2, vec2)) { + addfillface(sf_ctx, eve, eve->next, eve->next->next); + addfillface(sf_ctx, eve->next->next, eve->next->next->next, eve); + } + else { + addfillface(sf_ctx, eve->next, eve->next->next, eve->next->next->next); + addfillface(sf_ctx, eve->next->next->next, eve, eve->next); + } + return 2; } - return 2; } /* first test vertices if they are in edges */ @@ -1091,7 +1108,7 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const short do_quad_tri_speedu for (a = 0; a < poly; a++) { if (pf->edges > 1) { splitlist(sf_ctx, &tempve, &temped, pf->nr); - totfaces += scanfill(sf_ctx, pf); + totfaces += scanfill(sf_ctx, pf, flag); } pf++; } diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c index 46f08d8ead7..2f375710959 100644 --- a/source/blender/bmesh/operators/bmo_triangulate.c +++ b/source/blender/bmesh/operators/bmo_triangulate.c @@ -190,7 +190,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op) /* sf_edge->tmp.p = e; */ /* UNUSED */ } - BLI_scanfill_calc(&sf_ctx, FALSE); + BLI_scanfill_calc(&sf_ctx, 0); for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) { BMFace *f = BM_face_create_quad_tri(bm, diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index efe9d1fedfe..1eec06eee75 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -306,7 +306,7 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert); - BLI_scanfill_calc_ex(&sf_ctx, TRUE, efa->no); + BLI_scanfill_calc_ex(&sf_ctx, 0, efa->no); for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) { int i; ls[0] = sf_tri->v1->tmp.p; diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index b3ffb80243a..a80386e9860 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -255,7 +255,7 @@ static void draw_filled_lasso(wmGesture *gt) if (sf_vert_first) { const float zvec[3] = {0.0f, 0.0f, 1.0f}; BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert); - BLI_scanfill_calc_ex(&sf_ctx, FALSE, zvec); + BLI_scanfill_calc_ex(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES, zvec); glEnable(GL_BLEND); glColor4f(1.0, 1.0, 1.0, 0.05); -- cgit v1.2.3 From f8bc346effae72fc9ef27e3e750f4983286a2012 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 Nov 2012 00:50:59 +0000 Subject: bmesh/py operator api: add type checking for element buffers, there was nothing stopping python from passing any element type into an argument when in some cases only verts/edges/faces were expected. now operator args define which types they support. --- source/blender/bmesh/bmesh_class.h | 1 + source/blender/bmesh/intern/bmesh_opdefines.c | 291 ++++++++++----------- source/blender/bmesh/intern/bmesh_operator_api.h | 58 ++-- .../bmesh/intern/bmesh_operator_api_inline.h | 22 +- source/blender/bmesh/intern/bmesh_operators.c | 30 ++- source/blender/bmesh/operators/bmo_dupe.c | 10 +- source/blender/bmesh/operators/bmo_extrude.c | 2 +- source/blender/bmesh/operators/bmo_mirror.c | 4 +- source/blender/bmesh/operators/bmo_subdivide.c | 8 +- source/blender/bmesh/operators/bmo_utils.c | 4 +- source/blender/editors/mesh/editmesh_knife.c | 2 +- source/blender/editors/mesh/editmesh_select.c | 6 +- source/blender/editors/mesh/editmesh_slide.c | 4 +- source/blender/editors/mesh/editmesh_tools.c | 10 +- source/blender/editors/mesh/editmesh_utils.c | 6 +- source/blender/python/bmesh/bmesh_py_ops.c | 29 +- 16 files changed, 262 insertions(+), 225 deletions(-) diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index f9dbf51a629..9d797c1e602 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -226,6 +226,7 @@ enum { }; #define BM_ALL (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE) +#define BM_ALL_NOLOOP (BM_VERT | BM_EDGE | BM_FACE) /* BMHeader->hflag (char) */ enum { diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index d8f29c082a4..f14fac64ba3 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -100,7 +100,7 @@ static BMOpDefine bmo_smooth_vert_def = { "smooth_vert", /* slots_in */ - {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {"mirror_clip_x", BMO_OP_SLOT_BOOL}, /* set vertices close to the x axis before the operation to 0 */ {"mirror_clip_y", BMO_OP_SLOT_BOOL}, /* set vertices close to the y axis before the operation to 0 */ {"mirror_clip_z", BMO_OP_SLOT_BOOL}, /* set vertices close to the z axis before the operation to 0 */ @@ -123,7 +123,7 @@ static BMOpDefine bmo_smooth_vert_def = { static BMOpDefine bmo_smooth_laplacian_vert_def = { "smooth_laplacian_vert", /* slots_in */ - {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {"lambda", BMO_OP_SLOT_FLT}, /* lambda param */ {"lambda_border", BMO_OP_SLOT_FLT}, /* lambda param in border */ {"use_x", BMO_OP_SLOT_BOOL}, /* Smooth object along X axis */ @@ -146,7 +146,7 @@ static BMOpDefine bmo_smooth_laplacian_vert_def = { static BMOpDefine bmo_recalc_face_normals_def = { "recalc_face_normals", /* slots_in */ - {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, + {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, {"use_flip", BMO_OP_SLOT_BOOL}, /* internal flag, used by bmesh_rationalize_normals */ {{'\0'}}, }, @@ -168,13 +168,13 @@ static BMOpDefine bmo_recalc_face_normals_def = { static BMOpDefine bmo_region_extend_def = { "region_extend", /* slots_in */ - {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, /* input geometry */ + {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */ {"use_constrict", BMO_OP_SLOT_BOOL}, /* find boundary inside the regions, not outside. */ {"use_faces", BMO_OP_SLOT_BOOL}, /* extend from faces instead of edges */ {{'\0'}}, }, /* slots_out */ - {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output slot, computed boundary geometry. */ + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output slot, computed boundary geometry. */ {{'\0'}}, }, bmo_region_extend_exec, @@ -190,12 +190,12 @@ static BMOpDefine bmo_region_extend_def = { static BMOpDefine bmo_rotate_edges_def = { "rotate_edges", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edges */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */ {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate edge counter-clockwise if true, othewise clockwise */ {{'\0'}}, }, /* slots_out */ - {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, /* newly spun edges */ + {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* newly spun edges */ {{'\0'}}, }, bmo_rotate_edges_exec, @@ -211,7 +211,7 @@ static BMOpDefine bmo_rotate_edges_def = { static BMOpDefine bmo_reverse_faces_def = { "reverse_faces", /* slots_in */ - {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -228,12 +228,12 @@ static BMOpDefine bmo_reverse_faces_def = { static BMOpDefine bmo_bisect_edges_def = { "bisect_edges", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edges */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */ {"cuts", BMO_OP_SLOT_INT}, /* number of cuts */ {{'\0'}}, }, /* slots_out */ - {{"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF}, /* newly created vertices and edges */ + {{"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* newly created vertices and edges */ {{'\0'}}, }, bmo_bisect_edges_exec, @@ -251,7 +251,7 @@ static BMOpDefine bmo_bisect_edges_def = { static BMOpDefine bmo_mirror_def = { "mirror", /* slots_in */ - {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, /* input geometry */ + {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */ {"mat", BMO_OP_SLOT_MAT}, /* matrix defining the mirror transformation */ {"merge_dist", BMO_OP_SLOT_FLT}, /* maximum distance for merging. does no merging if 0. */ {"axis", BMO_OP_SLOT_INT}, /* the axis to use, 0, 1, or 2 for x, y, z */ @@ -260,7 +260,7 @@ static BMOpDefine bmo_mirror_def = { {{'\0'}}, }, /* slots_out */ - {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output geometry, mirrored */ + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output geometry, mirrored */ {{'\0'}}, }, bmo_mirror_exec, @@ -279,13 +279,13 @@ static BMOpDefine bmo_mirror_def = { static BMOpDefine bmo_find_doubles_def = { "find_doubles", /* slots_in */ - {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ - {"keep_verts", BMO_OP_SLOT_ELEMENT_BUF}, /* list of verts to keep */ + {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ + {"keep_verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* list of verts to keep */ {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */ {{'\0'}}, }, /* slots_out */ - {{"targetmap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM}, + {{"targetmap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, {{'\0'}}, }, bmo_find_doubles_exec, @@ -301,7 +301,7 @@ static BMOpDefine bmo_find_doubles_def = { static BMOpDefine bmo_remove_doubles_def = { "remove_doubles", /* slots_in */ - {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input verts */ + {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input verts */ {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */ {{'\0'}}, }, @@ -320,7 +320,7 @@ static BMOpDefine bmo_remove_doubles_def = { static BMOpDefine bmo_automerge_def = { "automerge", /* slots_in */ - {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input verts */ + {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input verts */ {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */ {{'\0'}}, }, @@ -337,7 +337,7 @@ static BMOpDefine bmo_automerge_def = { static BMOpDefine bmo_collapse_def = { "collapse", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edge */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -354,8 +354,8 @@ static BMOpDefine bmo_collapse_def = { static BMOpDefine bmo_pointmerge_facedata_def = { "pointmerge_facedata", /* slots_in */ - {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ - {"snapv", BMO_OP_SLOT_ELEMENT_BUF}, /* snap vertex */ + {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ + {"snapv", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, /* snap vertex */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -373,7 +373,7 @@ static BMOpDefine bmo_pointmerge_facedata_def = { static BMOpDefine bmo_average_vert_facedata_def = { "average_vert_facedata", /* slots_in */ - {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertice */ + {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertice */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -389,7 +389,7 @@ static BMOpDefine bmo_average_vert_facedata_def = { static BMOpDefine bmo_pointmerge_def = { "pointmerge", /* slots_in */ - {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertice */ + {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertice */ {"merge_co", BMO_OP_SLOT_VEC}, {{'\0'}}, }, @@ -406,7 +406,7 @@ static BMOpDefine bmo_pointmerge_def = { static BMOpDefine bmo_collapse_uvs_def = { "collapse_uvs", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edge */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -425,7 +425,7 @@ static BMOpDefine bmo_weld_verts_def = { "weld_verts", /* slots_in */ /* maps welded vertices to verts they should weld to */ - {{"targetmap", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM}, + {{"targetmap", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -446,7 +446,7 @@ static BMOpDefine bmo_create_vert_def = { {{'\0'}}, }, /* slots_out */ - {{"vert.out", BMO_OP_SLOT_ELEMENT_BUF}, /* the new vert */ + {{"vert.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* the new vert */ {{'\0'}}, }, bmo_create_vert_exec, @@ -462,7 +462,7 @@ static BMOpDefine bmo_create_vert_def = { static BMOpDefine bmo_join_triangles_def = { "join_triangles", /* slots_in */ - {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input geometry. */ + {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input geometry. */ {"cmp_sharp", BMO_OP_SLOT_BOOL}, {"cmp_uvs", BMO_OP_SLOT_BOOL}, {"cmp_vcols", BMO_OP_SLOT_BOOL}, @@ -471,7 +471,7 @@ static BMOpDefine bmo_join_triangles_def = { {{'\0'}}, }, /* slots_out */ - {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* joined faces */ + {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* joined faces */ {{'\0'}}, }, bmo_join_triangles_exec, @@ -492,15 +492,15 @@ static BMOpDefine bmo_join_triangles_def = { static BMOpDefine bmo_contextual_create_def = { "contextual_create", /* slots_in */ - {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, /* input geometry. */ + {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry. */ {"mat_nr", BMO_OP_SLOT_INT}, /* material to use */ {"use_smooth", BMO_OP_SLOT_BOOL}, /* smooth to use */ {{'\0'}}, }, /* slots_out */ - {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* newly-made face(s) */ + {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* newly-made face(s) */ /* note, this is for stand-alone edges only, not edges which are apart of newly created faces */ - {"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, /* newly-made edge(s) */ + {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* newly-made edge(s) */ {{'\0'}}, }, bmo_contextual_create_exec, @@ -513,13 +513,13 @@ static BMOpDefine bmo_contextual_create_def = { static BMOpDefine bmo_bridge_loops_def = { "bridge_loops", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edge */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */ {"use_merge", BMO_OP_SLOT_BOOL}, {"merge_factor", BMO_OP_SLOT_FLT}, {{'\0'}}, }, /* slots_out */ - {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* new faces */ + {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */ {{'\0'}}, }, bmo_bridge_loops_exec, @@ -529,20 +529,20 @@ static BMOpDefine bmo_bridge_loops_def = { static BMOpDefine bmo_edgenet_fill_def = { "edgenet_fill", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edge */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */ /* restricts edges to groups. maps edges to integer */ - {"restrict", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_BOOL}, + {"restrict", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_BOOL}}, {"use_restrict", BMO_OP_SLOT_BOOL}, {"use_fill_check", BMO_OP_SLOT_BOOL}, - {"exclude_faces", BMO_OP_SLOT_ELEMENT_BUF}, /* list of faces to ignore for manifold check */ + {"exclude_faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* list of faces to ignore for manifold check */ {"mat_nr", BMO_OP_SLOT_INT}, /* material to use */ {"use_smooth", BMO_OP_SLOT_BOOL}, /* material to use */ {{'\0'}}, }, /* slots_out */ /* maps new faces to the group numbers they came from */ - {{"face_groupmap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM}, - {"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* new face */ + {{"face_groupmap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, + {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new face */ {{'\0'}}, }, bmo_edgenet_fill_exec, @@ -562,11 +562,11 @@ static BMOpDefine bmo_edgenet_fill_def = { static BMOpDefine bmo_edgenet_prepare_def = { "edgenet_prepare", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edges */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */ {{'\0'}}, }, /* slots_out */ - {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, /* new edges */ + {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* new edges */ {{'\0'}}, }, bmo_edgenet_prepare, @@ -584,7 +584,7 @@ static BMOpDefine bmo_rotate_def = { /* slots_in */ {{"cent", BMO_OP_SLOT_VEC}, /* center of rotation */ {"mat", BMO_OP_SLOT_MAT}, /* matrix defining rotation */ - {"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -602,7 +602,7 @@ static BMOpDefine bmo_translate_def = { "translate", /* slots_in */ {{"vec", BMO_OP_SLOT_VEC}, /* translation offset */ - {"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -619,7 +619,7 @@ static BMOpDefine bmo_scale_def = { "scale", /* slots_in */ {{"vec", BMO_OP_SLOT_VEC}, /* scale factor */ - {"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -638,7 +638,7 @@ static BMOpDefine bmo_transform_def = { "transform", /* slots_in */ {{"mat", BMO_OP_SLOT_MAT}, /* transform matrix */ - {"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -655,8 +655,8 @@ static BMOpDefine bmo_transform_def = { static BMOpDefine bmo_object_load_bmesh_def = { "object_load_bmesh", /* slots_in */ - {{"scene", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_SCENE}, - {"object", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}, + {{"scene", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_SCENE}}, + {"object", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}}, {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -675,9 +675,9 @@ static BMOpDefine bmo_bmesh_to_mesh_def = { /* slots_in */ { /* pointer to a mesh structure to fill in */ - {"mesh", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_MESH}, + {"mesh", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_MESH}}, /* pointer to an object structure */ - {"object", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}, + {"object", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}}, {"skip_tessface", BMO_OP_SLOT_BOOL}, /* don't calculate mfaces */ {{'\0'}}, }, @@ -697,9 +697,9 @@ static BMOpDefine bmo_mesh_to_bmesh_def = { /* slots_in */ { /* pointer to a Mesh structure */ - {"mesh", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_MESH}, + {"mesh", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_MESH}}, /* pointer to an Object structure */ - {"object", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}, + {"object", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}}, {"use_shapekey", BMO_OP_SLOT_BOOL}, /* load active shapekey coordinates into verts */ {{'\0'}}, }, @@ -716,12 +716,11 @@ static BMOpDefine bmo_mesh_to_bmesh_def = { static BMOpDefine bmo_extrude_discrete_faces_def = { "extrude_discrete_faces", /* slots_in */ - {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */ {{'\0'}}, }, /* slots_out */ - {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output faces */ - {"geom_skirt.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output skirt geometry, faces and edges */ + {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */ {{'\0'}}, }, bmo_extrude_discrete_faces_exec, @@ -737,11 +736,11 @@ static BMOpDefine bmo_extrude_discrete_faces_def = { static BMOpDefine bmo_extrude_edge_only_def = { "extrude_edge_only", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input vertices */ {{'\0'}}, }, /* slots_out */ - {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output geometry */ + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output geometry */ {{'\0'}}, }, bmo_extrude_edge_only_exec, @@ -756,12 +755,12 @@ static BMOpDefine bmo_extrude_edge_only_def = { static BMOpDefine bmo_extrude_vert_indiv_def = { "extrude_vert_indiv", /* slots_in */ - {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {{'\0'}}, }, /* slots_out */ - {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output wire edges */ - {"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output vertices */ + {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output wire edges */ + {"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output vertices */ {{'\0'}}, }, bmo_extrude_vert_indiv_exec, @@ -771,11 +770,11 @@ static BMOpDefine bmo_extrude_vert_indiv_def = { static BMOpDefine bmo_connect_verts_def = { "connect_verts", /* slots_in */ - {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, + {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, {{'\0'}}, }, /* slots_out */ - {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, {{'\0'}}, }, bmo_connect_verts_exec, @@ -785,13 +784,13 @@ static BMOpDefine bmo_connect_verts_def = { static BMOpDefine bmo_extrude_face_region_def = { "extrude_face_region", /* slots_in */ - {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, /* edges and faces */ - {"edges_exclude", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_EMPTY}, + {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* edges and faces */ + {"edges_exclude", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_EMPTY}}, {"use_keep_orig", BMO_OP_SLOT_BOOL}, /* keep original geometry */ {{'\0'}}, }, /* slots_out */ - {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, {{'\0'}}, }, bmo_extrude_face_region_exec, @@ -801,7 +800,7 @@ static BMOpDefine bmo_extrude_face_region_def = { static BMOpDefine bmo_dissolve_verts_def = { "dissolve_verts", /* slots_in */ - {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, + {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -812,12 +811,12 @@ static BMOpDefine bmo_dissolve_verts_def = { static BMOpDefine bmo_dissolve_edges_def = { "dissolve_edges", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, {"use_verts", BMO_OP_SLOT_BOOL}, /* dissolve verts left between only 2 edges. */ {{'\0'}}, }, /* slots_out */ - {{"region.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, {{'\0'}}, }, bmo_dissolve_edges_exec, @@ -827,11 +826,11 @@ static BMOpDefine bmo_dissolve_edges_def = { static BMOpDefine bmo_dissolve_edge_loop_def = { "dissolve_edge_loop", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, {{'\0'}}, }, /* slots_out */ - {{"region.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, {{'\0'}}, }, bmo_dissolve_edgeloop_exec, @@ -841,12 +840,12 @@ static BMOpDefine bmo_dissolve_edge_loop_def = { static BMOpDefine bmo_dissolve_faces_def = { "dissolve_faces", /* slots_in */ - {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, + {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, {"use_verts", BMO_OP_SLOT_BOOL}, /* dissolve verts left between only 2 edges. */ {{'\0'}}, }, /* slots_out */ - {{"region.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, {{'\0'}}, }, bmo_dissolve_faces_exec, @@ -858,8 +857,8 @@ static BMOpDefine bmo_dissolve_limit_def = { /* slots_in */ {{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (degrees) */ {"use_dissolve_boundaries", BMO_OP_SLOT_BOOL}, - {"verts", BMO_OP_SLOT_ELEMENT_BUF}, - {"edges", BMO_OP_SLOT_ELEMENT_BUF}, + {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, + {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -870,14 +869,14 @@ static BMOpDefine bmo_dissolve_limit_def = { static BMOpDefine bmo_triangulate_def = { "triangulate", /* slots_in */ - {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, + {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, {"use_beauty", BMO_OP_SLOT_BOOL}, {{'\0'}}, }, /* slots_out */ - {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, - {"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, - {"facemap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM}, + {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, + {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, + {"facemap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, {{'\0'}}, }, bmo_triangulate_exec, @@ -887,7 +886,7 @@ static BMOpDefine bmo_triangulate_def = { static BMOpDefine bmo_unsubdivide_def = { "unsubdivide", /* slots_in */ - {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {"iterations", BMO_OP_SLOT_INT}, {{'\0'}}, }, @@ -899,14 +898,14 @@ static BMOpDefine bmo_unsubdivide_def = { static BMOpDefine bmo_subdivide_edges_def = { "subdivide_edges", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, {"smooth", BMO_OP_SLOT_FLT}, {"fractal", BMO_OP_SLOT_FLT}, {"along_normal", BMO_OP_SLOT_FLT}, {"cuts", BMO_OP_SLOT_INT}, {"seed", BMO_OP_SLOT_INT}, - {"custompatterns", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL}, /* uses custom pointers */ - {"edgepercents", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_FLOAT}, + {"custompatterns", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL}}, /* uses custom pointers */ + {"edgepercents", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_FLOAT}}, {"quad_corner_type", BMO_OP_SLOT_INT}, /* quad corner type, see bmesh_operators.h */ {"use_gridfill", BMO_OP_SLOT_BOOL}, /* fill in fully-selected faces with a grid */ @@ -917,9 +916,9 @@ static BMOpDefine bmo_subdivide_edges_def = { }, /* slots_out */ {/* these next three can have multiple types of elements in them */ - {"geom_inner.out", BMO_OP_SLOT_ELEMENT_BUF}, - {"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF}, - {"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, /* contains all output geometr */ + {"geom_inner.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, + {"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, + {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* contains all output geometr */ {{'\0'}}, }, bmo_subdivide_edges_exec, @@ -929,7 +928,7 @@ static BMOpDefine bmo_subdivide_edges_def = { static BMOpDefine bmo_delete_def = { "delete", /* slots_in */ - {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, + {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, {"context", BMO_OP_SLOT_INT}, {{'\0'}}, }, @@ -941,19 +940,19 @@ static BMOpDefine bmo_delete_def = { static BMOpDefine bmo_duplicate_def = { "duplicate", /* slots_in */ - {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, + {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* destination bmesh, if NULL will use current on */ - {"dest", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_BMESH}, + {"dest", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_BMESH}}, {{'\0'}}, }, /* slots_out */ - {{"geom_orig.out", BMO_OP_SLOT_ELEMENT_BUF}, - {"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{"geom_orig.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, + {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* facemap maps from source faces to dupe * faces, and from dupe faces to source faces */ - {"facemap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM}, - {"boundarymap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM}, - {"isovertmap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM}, + {"facemap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, + {"boundarymap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, + {"isovertmap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, {{'\0'}}, }, bmo_duplicate_exec, @@ -963,16 +962,16 @@ static BMOpDefine bmo_duplicate_def = { static BMOpDefine bmo_split_def = { "split", /* slots_in */ - {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, + {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* destination bmesh, if NULL will use current one */ - {"dest", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_BMESH}, + {"dest", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_BMESH}}, {"use_only_faces", BMO_OP_SLOT_BOOL}, /* when enabled. don't duplicate loose verts/edges */ {{'\0'}}, }, /* slots_out */ - {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, - {"boundarymap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM}, - {"isovertmap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM}, + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, + {"boundarymap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, + {"isovertmap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, {{'\0'}}, }, bmo_split_exec, @@ -988,7 +987,7 @@ static BMOpDefine bmo_split_def = { static BMOpDefine bmo_spin_def = { "spin", /* slots_in */ - {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, + {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, {"cent", BMO_OP_SLOT_VEC}, /* rotation center */ {"axis", BMO_OP_SLOT_VEC}, /* rotation axis */ {"dvec", BMO_OP_SLOT_VEC}, /* translation delta per step */ @@ -998,7 +997,7 @@ static BMOpDefine bmo_spin_def = { {{'\0'}}, }, /* slots_out */ - {{"geom_last.out", BMO_OP_SLOT_ELEMENT_BUF}, /* result of last step */ + {{"geom_last.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* result of last step */ {{'\0'}}, }, bmo_spin_exec, @@ -1014,14 +1013,14 @@ static BMOpDefine bmo_spin_def = { static BMOpDefine bmo_similar_faces_def = { "similar_faces", /* slots_in */ - {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */ {"type", BMO_OP_SLOT_INT}, /* type of selection */ {"thresh", BMO_OP_SLOT_FLT}, /* threshold of selection */ {"compare", BMO_OP_SLOT_INT}, /* comparison method */ {{'\0'}}, }, /* slots_out */ - {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output faces */ + {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */ {{'\0'}}, }, bmo_similar_faces_exec, @@ -1036,14 +1035,14 @@ static BMOpDefine bmo_similar_faces_def = { static BMOpDefine bmo_similar_edges_def = { "similar_edges", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edges */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */ {"type", BMO_OP_SLOT_INT}, /* type of selection */ {"thresh", BMO_OP_SLOT_FLT}, /* threshold of selection */ {"compare", BMO_OP_SLOT_INT}, /* comparison method */ {{'\0'}}, }, /* slots_out */ - {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output edges */ + {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output edges */ {{'\0'}}, }, bmo_similar_edges_exec, @@ -1058,14 +1057,14 @@ static BMOpDefine bmo_similar_edges_def = { static BMOpDefine bmo_similar_verts_def = { "similar_verts", /* slots_in */ - {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */ + {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {"type", BMO_OP_SLOT_INT}, /* type of selection */ {"thresh", BMO_OP_SLOT_FLT}, /* threshold of selection */ {"compare", BMO_OP_SLOT_INT}, /* comparison method */ {{'\0'}}, }, /* slots_out */ - {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output vertices */ + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output vertices */ {{'\0'}}, }, bmo_similar_verts_exec, @@ -1079,7 +1078,7 @@ static BMOpDefine bmo_similar_verts_def = { static BMOpDefine bmo_rotate_uvs_def = { "rotate_uvs", /* slots_in */ - {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */ {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, othewise clockwise */ {{'\0'}}, }, @@ -1096,7 +1095,7 @@ static BMOpDefine bmo_rotate_uvs_def = { static BMOpDefine bmo_reverse_uvs_def = { "reverse_uvs", /* slots_in */ - {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -1111,7 +1110,7 @@ static BMOpDefine bmo_reverse_uvs_def = { static BMOpDefine bmo_rotate_colors_def = { "rotate_colors", /* slots_in */ - {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */ {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, othewise clockwise */ {{'\0'}}, }, @@ -1127,7 +1126,7 @@ static BMOpDefine bmo_rotate_colors_def = { static BMOpDefine bmo_reverse_colors_def = { "reverse_colors", /* slots_in */ - {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -1143,13 +1142,13 @@ static BMOpDefine bmo_reverse_colors_def = { static BMOpDefine bmo_shortest_path_def = { "shortest_path", /* slots_in */ - {{"startv", BMO_OP_SLOT_ELEMENT_BUF}, /* start vertex */ - {"endv", BMO_OP_SLOT_ELEMENT_BUF}, /* end vertex */ + {{"startv", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, /* start vertex */ + {"endv", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, /* end vertex */ {"type", BMO_OP_SLOT_INT}, /* type of selection */ {{'\0'}}, }, /* slots_out */ - {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output vertices */ + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output vertices */ {{'\0'}}, }, bmo_shortest_path_exec, @@ -1164,14 +1163,14 @@ static BMOpDefine bmo_shortest_path_def = { static BMOpDefine bmo_split_edges_def = { "split_edges", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edges */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */ /* needed for vertex rip so we can rip only half an edge at a boundary wich would otherwise split off */ - {"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* optional tag verts, use to have greater control of splits */ + {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* optional tag verts, use to have greater control of splits */ {"use_verts", BMO_OP_SLOT_BOOL}, /* use 'verts' for splitting, else just find verts to split from edges */ {{'\0'}}, }, /* slots_out */ - {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, /* old output disconnected edges */ + {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* old output disconnected edges */ {{'\0'}}, }, bmo_split_edges_exec, @@ -1193,7 +1192,7 @@ static BMOpDefine bmo_create_grid_def = { {{'\0'}}, }, /* slots_out */ - {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */ + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */ {{'\0'}}, }, bmo_create_grid_exec, @@ -1215,7 +1214,7 @@ static BMOpDefine bmo_create_uvsphere_def = { {{'\0'}}, }, /* slots_out */ - {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */ + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */ {{'\0'}}, }, bmo_create_uvsphere_exec, @@ -1236,7 +1235,7 @@ static BMOpDefine bmo_create_icosphere_def = { {{'\0'}}, }, /* slots_out */ - {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */ + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */ {{'\0'}}, }, bmo_create_icosphere_exec, @@ -1255,7 +1254,7 @@ static BMOpDefine bmo_create_monkey_def = { {{'\0'}}, }, /* slots_out */ - {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */ + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */ {{'\0'}}, }, bmo_create_monkey_exec, @@ -1280,7 +1279,7 @@ static BMOpDefine bmo_create_cone_def = { {{'\0'}}, }, /* slots_out */ - {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */ + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */ {{'\0'}}, }, bmo_create_cone_exec, @@ -1301,7 +1300,7 @@ static BMOpDefine bmo_create_circle_def = { {{'\0'}}, }, /* slots_out */ - {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */ + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */ {{'\0'}}, }, bmo_create_circle_exec, @@ -1321,7 +1320,7 @@ static BMOpDefine bmo_create_cube_def = { {{'\0'}}, }, /* slots_out */ - {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */ + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */ {{'\0'}}, }, bmo_create_cube_exec, @@ -1336,19 +1335,19 @@ static BMOpDefine bmo_create_cube_def = { static BMOpDefine bmo_bevel_def = { "bevel", /* slots_in */ - {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, /* input edges and vertices */ + {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input edges and vertices */ {"offset", BMO_OP_SLOT_FLT}, /* amount to offset beveled edge */ {"segments", BMO_OP_SLOT_INT}, /* number of segments in bevel */ {{'\0'}}, }, /* slots_out */ - {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output faces */ + {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */ {{'\0'}}, }, #if 0 /* old bevel*/ - {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, /* input edges and vertices */ - {"face_spans", BMO_OP_SLOT_ELEMENT_BUF}, /* new geometry */ - {"face_holes", BMO_OP_SLOT_ELEMENT_BUF}, /* new geometry */ + {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input edges and vertices */ + {"face_spans", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new geometry */ + {"face_holes", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new geometry */ {"use_lengths", BMO_OP_SLOT_BOOL}, /* grab edge lengths from a PROP_FLT customdata layer */ {"use_even", BMO_OP_SLOT_BOOL}, /* corner vert placement: use shell/angle calculations */ {"use_dist", BMO_OP_SLOT_BOOL}, /* corner vert placement: evaluate percent as a distance, @@ -1370,12 +1369,12 @@ static BMOpDefine bmo_bevel_def = { static BMOpDefine bmo_beautify_fill_def = { "beautify_fill", /* slots_in */ - {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ - {"constrain_edges", BMO_OP_SLOT_ELEMENT_BUF}, /* edges that can't be flipped */ + {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */ + {"constrain_edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* edges that can't be flipped */ {{'\0'}}, }, /* slots_out */ - {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, /* new flipped faces and edges */ + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new flipped faces and edges */ {{'\0'}}, }, bmo_beautify_fill_exec, @@ -1390,11 +1389,11 @@ static BMOpDefine bmo_beautify_fill_def = { static BMOpDefine bmo_triangle_fill_def = { "triangle_fill", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edges */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */ {{'\0'}}, }, /* slots_out */ - {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, /* new faces and edges */ + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new faces and edges */ {{'\0'}}, }, bmo_triangle_fill_exec, @@ -1409,12 +1408,12 @@ static BMOpDefine bmo_triangle_fill_def = { static BMOpDefine bmo_solidify_def = { "solidify", /* slots_in */ - {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, + {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, {"thickness", BMO_OP_SLOT_FLT}, {{'\0'}}, }, /* slots_out */ - {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, {{'\0'}}, }, bmo_solidify_face_region_exec, @@ -1429,7 +1428,7 @@ static BMOpDefine bmo_solidify_def = { static BMOpDefine bmo_inset_def = { "inset", /* slots_in */ - {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */ {"use_boundary", BMO_OP_SLOT_BOOL}, {"use_even_offset", BMO_OP_SLOT_BOOL}, {"use_relative_offset", BMO_OP_SLOT_BOOL}, @@ -1439,7 +1438,7 @@ static BMOpDefine bmo_inset_def = { {{'\0'}}, }, /* slots_out */ - {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output faces */ + {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */ {{'\0'}}, }, bmo_inset_exec, @@ -1454,7 +1453,7 @@ static BMOpDefine bmo_inset_def = { static BMOpDefine bmo_wireframe_def = { "wireframe", /* slots_in */ - {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */ + {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */ {"use_boundary", BMO_OP_SLOT_BOOL}, {"use_even_offset", BMO_OP_SLOT_BOOL}, {"use_crease", BMO_OP_SLOT_BOOL}, @@ -1464,7 +1463,7 @@ static BMOpDefine bmo_wireframe_def = { {{'\0'}}, }, /* slots_out */ - {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output faces */ + {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */ {{'\0'}}, }, bmo_wireframe_exec, @@ -1479,13 +1478,13 @@ static BMOpDefine bmo_wireframe_def = { static BMOpDefine bmo_slide_vert_def = { "slide_vert", /* slots_in */ - {{"vert", BMO_OP_SLOT_ELEMENT_BUF}, - {"edge", BMO_OP_SLOT_ELEMENT_BUF}, + {{"vert", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, + {"edge", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, {"distance_t", BMO_OP_SLOT_FLT}, {{'\0'}}, }, /* slots_out */ - {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, {{'\0'}}, }, bmo_slide_vert_exec, @@ -1511,15 +1510,15 @@ static BMOpDefine bmo_slide_vert_def = { static BMOpDefine bmo_convex_hull_def = { "convex_hull", /* slots_in */ - {{"input", BMO_OP_SLOT_ELEMENT_BUF}, + {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, {"use_existing_faces", BMO_OP_SLOT_BOOL}, {{'\0'}}, }, /* slots_out */ - {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, - {"geom_interior.out", BMO_OP_SLOT_ELEMENT_BUF}, - {"geom_unused.out", BMO_OP_SLOT_ELEMENT_BUF}, - {"geom_holes.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, + {"geom_interior.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, + {"geom_unused.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, + {"geom_holes.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, {{'\0'}}, }, bmo_convex_hull_exec, @@ -1540,12 +1539,12 @@ static BMOpDefine bmo_convex_hull_def = { static BMOpDefine bmo_symmetrize_def = { "symmetrize", /* slots_in */ - {{"input", BMO_OP_SLOT_ELEMENT_BUF}, + {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, {"direction", BMO_OP_SLOT_INT}, {{'\0'}}, }, /* slots_out */ - {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, + {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, {{'\0'}}, }, bmo_symmetrize_exec, diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h index e84883540d6..245a53ebed2 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api.h +++ b/source/blender/bmesh/intern/bmesh_operator_api.h @@ -112,35 +112,43 @@ typedef enum eBMOpSlotType { } eBMOpSlotType; #define BMO_OP_SLOT_TOTAL_TYPES 11 -/* leave zero for invalid/unset */ -typedef enum eBMOpSlotSubType { - /* BMO_OP_SLOT_MAPPING */ -#define BMO_OP_SLOT_SUBTYPE_MAP__FIRST BMO_OP_SLOT_SUBTYPE_MAP_EMPTY - BMO_OP_SLOT_SUBTYPE_MAP_EMPTY = 1, /* use as a set(), unused value */ - BMO_OP_SLOT_SUBTYPE_MAP_ELEM = 2, - BMO_OP_SLOT_SUBTYPE_MAP_FLOAT = 3, - BMO_OP_SLOT_SUBTYPE_MAP_INT = 4, - BMO_OP_SLOT_SUBTYPE_MAP_BOOL = 5, - BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL = 6, /* python can't convert these */ -#define BMO_OP_SLOT_SUBTYPE_MAP__LAST BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL - - /* BMO_OP_SLOT_PTR */ -#define BMO_OP_SLOT_SUBTYPE_PTR__FIRST BMO_OP_SLOT_SUBTYPE_PTR_BMESH - BMO_OP_SLOT_SUBTYPE_PTR_BMESH = 10, - BMO_OP_SLOT_SUBTYPE_PTR_SCENE = 11, - BMO_OP_SLOT_SUBTYPE_PTR_OBJECT = 12, - BMO_OP_SLOT_SUBTYPE_PTR_MESH = 13, -#define BMO_OP_SLOT_SUBTYPE_PTR__LAST BMO_OP_SLOT_SUBTYPE_PTR_MESH - -} eBMOpSlotSubType; +/* don't overlap values to avoid confusion */ +typedef enum eBMOpSlotSubType_Elem { + /* use as flags */ + BMO_OP_SLOT_SUBTYPE_ELEM_VERT = BM_VERT, + BMO_OP_SLOT_SUBTYPE_ELEM_EDGE = BM_EDGE, + BMO_OP_SLOT_SUBTYPE_ELEM_FACE = BM_FACE, + BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE = (BM_FACE << 1), +} eBMOpSlotSubType_Elem; +typedef enum eBMOpSlotSubType_Map { + BMO_OP_SLOT_SUBTYPE_MAP_EMPTY = 64, /* use as a set(), unused value */ + BMO_OP_SLOT_SUBTYPE_MAP_ELEM = 65, + BMO_OP_SLOT_SUBTYPE_MAP_FLOAT = 66, + BMO_OP_SLOT_SUBTYPE_MAP_INT = 67, + BMO_OP_SLOT_SUBTYPE_MAP_BOOL = 68, + BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL = 69, /* python can't convert these */ +} eBMOpSlotSubType_Map; +typedef enum eBMOpSlotSubType_Ptr { + BMO_OP_SLOT_SUBTYPE_PTR_BMESH = 100, + BMO_OP_SLOT_SUBTYPE_PTR_SCENE = 101, + BMO_OP_SLOT_SUBTYPE_PTR_OBJECT = 102, + BMO_OP_SLOT_SUBTYPE_PTR_MESH = 103, +} eBMOpSlotSubType_Ptr; + +typedef union eBMOpSlotSubType_Union { + eBMOpSlotSubType_Map elem; + eBMOpSlotSubType_Map ptr; + eBMOpSlotSubType_Map map; +} eBMOpSlotSubType_Union; /* please ignore all these structures, don't touch them in tool code, except * for when your defining an operator with BMOpDefine.*/ typedef struct BMOpSlot { const char *slot_name; /* pointer to BMOpDefine.slot_args */ - eBMOpSlotType slot_type; - eBMOpSlotSubType slot_subtype; + eBMOpSlotType slot_type; + eBMOpSlotSubType_Union slot_subtype; + int len; // int flag; /* UNUSED */ // int index; /* index within slot array */ /* UNUSED */ @@ -190,8 +198,8 @@ enum { typedef struct BMOSlotType { char name[MAX_SLOTNAME]; - eBMOpSlotType type; - eBMOpSlotSubType subtype; + eBMOpSlotType type; + eBMOpSlotSubType_Union subtype; } BMOSlotType; typedef struct BMOpDefine { diff --git a/source/blender/bmesh/intern/bmesh_operator_api_inline.h b/source/blender/bmesh/intern/bmesh_operator_api_inline.h index 4143c4d0883..96c37b45b05 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api_inline.h +++ b/source/blender/bmesh/intern/bmesh_operator_api_inline.h @@ -72,14 +72,14 @@ BLI_INLINE void _bmo_elem_flag_toggle(BMesh *bm, BMFlagLayer *oflags, const shor BLI_INLINE void BMO_slot_map_int_insert(BMOperator *op, BMOpSlot *slot, void *element, const int val) { - BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_INT); + BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INT); BMO_slot_map_insert(op, slot, element, &val, sizeof(int)); } BLI_INLINE void BMO_slot_map_bool_insert(BMOperator *op, BMOpSlot *slot, void *element, const int val) { - BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_BOOL); + BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL); BLI_assert(val == FALSE || val == TRUE); BMO_slot_map_insert(op, slot, element, &val, sizeof(int)); } @@ -87,7 +87,7 @@ BLI_INLINE void BMO_slot_map_bool_insert(BMOperator *op, BMOpSlot *slot, BLI_INLINE void BMO_slot_map_float_insert(BMOperator *op, BMOpSlot *slot, void *element, const float val) { - BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_FLOAT); + BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLOAT); BMO_slot_map_insert(op, slot, element, &val, sizeof(float)); } @@ -100,14 +100,14 @@ BLI_INLINE void BMO_slot_map_float_insert(BMOperator *op, BMOpSlot *slot, BLI_INLINE void BMO_slot_map_ptr_insert(BMOperator *op, BMOpSlot *slot, const void *element, void *val) { - BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL); + BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL); BMO_slot_map_insert(op, slot, element, &val, sizeof(void *)); } BLI_INLINE void BMO_slot_map_elem_insert(BMOperator *op, BMOpSlot *slot, const void *element, void *val) { - BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_ELEM); + BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_ELEM); BMO_slot_map_insert(op, slot, element, &val, sizeof(void *)); } @@ -116,7 +116,7 @@ BLI_INLINE void BMO_slot_map_elem_insert(BMOperator *op, BMOpSlot *slot, BLI_INLINE void BMO_slot_map_empty_insert(BMOperator *op, BMOpSlot *slot, const void *element) { - BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_EMPTY); + BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_EMPTY); BMO_slot_map_insert(op, slot, element, NULL, 0); } @@ -154,7 +154,7 @@ BLI_INLINE void *BMO_slot_map_data_get(BMOpSlot *slot, const void *element) BLI_INLINE float BMO_slot_map_float_get(BMOpSlot *slot, const void *element) { float *val; - BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_FLOAT); + BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLOAT); val = (float *) BMO_slot_map_data_get(slot, element); if (val) return *val; @@ -165,7 +165,7 @@ BLI_INLINE float BMO_slot_map_float_get(BMOpSlot *slot, const void *element) BLI_INLINE int BMO_slot_map_int_get(BMOpSlot *slot, const void *element) { int *val; - BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_INT); + BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INT); val = (int *) BMO_slot_map_data_get(slot, element); if (val) return *val; @@ -176,7 +176,7 @@ BLI_INLINE int BMO_slot_map_int_get(BMOpSlot *slot, const void *element) BLI_INLINE int BMO_slot_map_bool_get(BMOpSlot *slot, const void *element) { int *val; - BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_BOOL); + BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL); val = (int *) BMO_slot_map_data_get(slot, element); BLI_assert(val == NULL || *val == FALSE || *val == TRUE); @@ -188,7 +188,7 @@ BLI_INLINE int BMO_slot_map_bool_get(BMOpSlot *slot, const void *element) BLI_INLINE void *BMO_slot_map_ptr_get(BMOpSlot *slot, const void *element) { void **val = (void **) BMO_slot_map_data_get(slot, element); - BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL); + BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL); if (val) return *val; return NULL; @@ -197,7 +197,7 @@ BLI_INLINE void *BMO_slot_map_ptr_get(BMOpSlot *slot, const void *element) BLI_INLINE void *BMO_slot_map_elem_get(BMOpSlot *slot, const void *element) { void **val = (void **) BMO_slot_map_data_get(slot, element); - BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_ELEM); + BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_ELEM); if (val) return *val; return NULL; diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 83fd338ef1f..f1bf4fd4d37 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -884,6 +884,7 @@ static void bmo_slot_buffer_from_flag(BMesh *bm, BMOperator *op, totelement = BMO_mesh_disabled_flag_count(bm, htype, oflag); BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF); + BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype); if (totelement) { BMIter iter; @@ -959,6 +960,7 @@ void BMO_slot_buffer_hflag_enable(BMesh *bm, const char do_flush_hide = (do_flush && (hflag & BM_ELEM_HIDDEN)); BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF); + BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype); for (i = 0; i < slot->len; i++, data++) { if (!(htype & (*data)->head.htype)) @@ -993,6 +995,7 @@ void BMO_slot_buffer_hflag_disable(BMesh *bm, const char do_flush_hide = (do_flush && (hflag & BM_ELEM_HIDDEN)); BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF); + BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype); for (i = 0; i < slot->len; i++, data++) { if (!(htype & (*data)->head.htype)) @@ -1043,6 +1046,7 @@ void BMO_slot_buffer_flag_enable(BMesh *bm, int i; BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF); + BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype); for (i = 0; i < slot->len; i++) { if (!(htype & data[i]->htype)) @@ -1066,6 +1070,7 @@ void BMO_slot_buffer_flag_disable(BMesh *bm, int i; BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF); + BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype); for (i = 0; i < slot->len; i++) { if (!(htype & data[i]->htype)) @@ -1256,25 +1261,29 @@ void *BMO_iter_new(BMOIter *iter, void *BMO_iter_step(BMOIter *iter) { - if (iter->slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF) { - BMHeader *h; + BMOpSlot *slot = iter->slot; + if (slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF) { + BMHeader *ele; - if (iter->cur >= iter->slot->len) { + if (iter->cur >= slot->len) { return NULL; } - h = iter->slot->data.buf[iter->cur++]; - while (!(iter->restrictmask & h->htype)) { - if (iter->cur >= iter->slot->len) { + ele = slot->data.buf[iter->cur++]; + while (!(iter->restrictmask & ele->htype)) { + if (iter->cur >= slot->len) { return NULL; } - h = iter->slot->data.buf[iter->cur++]; + ele = slot->data.buf[iter->cur++]; + BLI_assert((ele == NULL) || (slot->slot_subtype.elem & ele->htype)); } - return h; + BLI_assert((ele == NULL) || (slot->slot_subtype.elem & ele->htype)); + + return ele; } - else if (iter->slot->slot_type == BMO_OP_SLOT_MAPPING) { + else if (slot->slot_type == BMO_OP_SLOT_MAPPING) { BMOElemMapping *map; void *ret = BLI_ghashIterator_getKey(&iter->giter); map = BLI_ghashIterator_getValue(&iter->giter); @@ -1285,6 +1294,9 @@ void *BMO_iter_step(BMOIter *iter) return ret; } + else { + BLI_assert(0); + } return NULL; } diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c index 591c758fbb2..f278d3f8896 100644 --- a/source/blender/bmesh/operators/bmo_dupe.c +++ b/source/blender/bmesh/operators/bmo_dupe.c @@ -330,7 +330,7 @@ void bmo_duplicate_exec(BMesh *bm, BMOperator *op) bm2 = bm; /* flag input */ - BMO_slot_buffer_flag_enable(bm, dupeop->slots_in, "geom", BM_ALL, DUPE_INPUT); + BMO_slot_buffer_flag_enable(bm, dupeop->slots_in, "geom", BM_ALL_NOLOOP, DUPE_INPUT); /* use the internal copy function */ bmo_mesh_copy(dupeop, bm, bm2); @@ -341,7 +341,7 @@ void bmo_duplicate_exec(BMesh *bm, BMOperator *op) dupeop, slots_out, "geom_orig.out"); /* Now alloc the new output buffers */ - BMO_slot_buffer_from_enabled_flag(bm, dupeop, dupeop->slots_out, "geom.out", BM_ALL, DUPE_NEW); + BMO_slot_buffer_from_enabled_flag(bm, dupeop, dupeop->slots_out, "geom.out", BM_ALL_NOLOOP, DUPE_NEW); } #if 0 /* UNUSED */ @@ -396,7 +396,7 @@ void bmo_split_exec(BMesh *bm, BMOperator *op) &dupeop, slots_in, "geom"); BMO_op_exec(bm, &dupeop); - BMO_slot_buffer_flag_enable(bm, splitop->slots_in, "geom", BM_ALL, SPLIT_INPUT); + BMO_slot_buffer_flag_enable(bm, splitop->slots_in, "geom", BM_ALL_NOLOOP, SPLIT_INPUT); if (use_only_faces) { BMVert *v; @@ -437,7 +437,7 @@ void bmo_split_exec(BMesh *bm, BMOperator *op) /* connect outputs of dupe to delete, exluding keep geometry */ BMO_slot_int_set(delop.slots_in, "context", DEL_FACES); - BMO_slot_buffer_from_enabled_flag(bm, &delop, delop.slots_in, "geom", BM_ALL, SPLIT_INPUT); + BMO_slot_buffer_from_enabled_flag(bm, &delop, delop.slots_in, "geom", BM_ALL_NOLOOP, SPLIT_INPUT); BMO_op_exec(bm, &delop); @@ -465,7 +465,7 @@ void bmo_delete_exec(BMesh *bm, BMOperator *op) BMOperator *delop = op; /* Mark Buffer */ - BMO_slot_buffer_flag_enable(bm, delop->slots_in, "geom", BM_ALL, DEL_INPUT); + BMO_slot_buffer_flag_enable(bm, delop->slots_in, "geom", BM_ALL_NOLOOP, DEL_INPUT); BMO_remove_tagged_context(bm, DEL_INPUT, BMO_slot_int_get(op->slots_in, "context")); diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c index 25ebf32b25a..aece270b09c 100644 --- a/source/blender/bmesh/operators/bmo_extrude.c +++ b/source/blender/bmesh/operators/bmo_extrude.c @@ -230,7 +230,7 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op) BMO_op_finish(bm, &dupeop); - BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, EXT_KEEP); + BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, EXT_KEEP); } void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op) diff --git a/source/blender/bmesh/operators/bmo_mirror.c b/source/blender/bmesh/operators/bmo_mirror.c index 6435f44f1d6..41cfae579ff 100644 --- a/source/blender/bmesh/operators/bmo_mirror.c +++ b/source/blender/bmesh/operators/bmo_mirror.c @@ -66,7 +66,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op) BMO_op_initf(bm, &dupeop, op->flag, "duplicate geom=%s", op, "geom"); BMO_op_exec(bm, &dupeop); - BMO_slot_buffer_flag_enable(bm, dupeop.slots_out, "geom.out", BM_ALL, ELE_NEW); + BMO_slot_buffer_flag_enable(bm, dupeop.slots_out, "geom.out", BM_ALL_NOLOOP, ELE_NEW); /* create old -> new mappin */ i = 0; @@ -123,7 +123,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op) BMO_op_finish(bm, &weldop); BMO_op_finish(bm, &dupeop); - BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, ELE_NEW); + BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, ELE_NEW); BLI_array_free(vmap); BLI_array_free(emap); diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index 1926e9a0f68..8da1f5ebfe5 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -1082,10 +1082,10 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) BLI_array_free(loops_split); BLI_array_free(loops); - BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_inner.out", BM_ALL, ELE_INNER); - BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL, ELE_SPLIT); + BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_inner.out", BM_ALL_NOLOOP, ELE_INNER); + BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL_NOLOOP, ELE_SPLIT); - BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, ELE_INNER | ELE_SPLIT | SUBD_SPLIT); + BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, ELE_INNER | ELE_SPLIT | SUBD_SPLIT); } /* editmesh-emulating function */ @@ -1182,7 +1182,7 @@ void bmo_bisect_edges_exec(BMesh *bm, BMOperator *op) bm_subdivide_multicut(bm, e, ¶ms, e->v1, e->v2); } - BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL, ELE_SPLIT); + BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL_NOLOOP, ELE_SPLIT); BM_data_layer_free_n(bm, &bm->vdata, CD_SHAPEKEY, skey); } diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index d56b2ca0d73..203acff8332 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -268,14 +268,14 @@ void bmo_region_extend_exec(BMesh *bm, BMOperator *op) int use_faces = BMO_slot_bool_get(op->slots_in, "use_faces"); int constrict = BMO_slot_bool_get(op->slots_in, "use_constrict"); - BMO_slot_buffer_flag_enable(bm, op->slots_in, "geom", BM_ALL, SEL_ORIG); + BMO_slot_buffer_flag_enable(bm, op->slots_in, "geom", BM_ALL_NOLOOP, SEL_ORIG); if (constrict) bmo_region_extend_constrict(bm, op, use_faces); else bmo_region_extend_extend(bm, op, use_faces); - BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, SEL_FLAG); + BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, SEL_FLAG); } /********* righthand faces implementation ****** */ diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index aed16be5b73..47add7afb56 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -2067,7 +2067,7 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd) } } - BLI_scanfill_calc(&sf_ctx, FALSE); + BLI_scanfill_calc(&sf_ctx, 0); for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) { BMVert *v1 = sf_tri->v3->tmp.p, *v2 = sf_tri->v2->tmp.p, *v3 = sf_tri->v1->tmp.p; diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index b46961a95d7..c658272f23f 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -732,7 +732,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op) EDBM_flag_disable_all(em, BM_ELEM_SELECT); /* select the output */ - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_ALL, BM_ELEM_SELECT, TRUE); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE); /* finish the operator */ if (!EDBM_op_finish(em, &bmop, op, TRUE)) { @@ -773,7 +773,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) EDBM_flag_disable_all(em, BM_ELEM_SELECT); /* select the output */ - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_ALL, BM_ELEM_SELECT, TRUE); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE); EDBM_selectmode_flush(em); /* finish the operator */ @@ -817,7 +817,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op) EDBM_flag_disable_all(em, BM_ELEM_SELECT); /* select the output */ - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_ALL, BM_ELEM_SELECT, TRUE); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE); /* finish the operator */ if (!EDBM_op_finish(em, &bmop, op, TRUE)) { diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c index c32033054e0..3f865678a89 100644 --- a/source/blender/editors/mesh/editmesh_slide.c +++ b/source/blender/editors/mesh/editmesh_slide.c @@ -738,10 +738,10 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u BMO_op_exec(bm, &bmop); /* Deselect the input edges */ - BMO_slot_buffer_hflag_disable(bm, bmop.slots_in, "edge", BM_ALL, BM_ELEM_SELECT, TRUE); + BMO_slot_buffer_hflag_disable(bm, bmop.slots_in, "edge", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE); /* Select the output vert */ - BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "verts.out", BM_ALL, BM_ELEM_SELECT, TRUE); + BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "verts.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE); /* Flush the select buffers */ EDBM_selectmode_flush(em); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 335f2a8c829..f28bb753122 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -1343,7 +1343,7 @@ static int edbm_duplicate_exec(bContext *C, wmOperator *op) BMO_op_exec(em->bm, &bmop); EDBM_flag_disable_all(em, BM_ELEM_SELECT); - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL, BM_ELEM_SELECT, TRUE); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE); if (!EDBM_op_finish(em, &bmop, op, TRUE)) { return OPERATOR_CANCELLED; @@ -2317,7 +2317,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op) /* EDBM_flag_disable_all(em, BM_ELEM_SELECT); */ /* select the output */ - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_ALL, BM_ELEM_SELECT, TRUE); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE); /* finish the operator */ if (!EDBM_op_finish(em, &bmop, op, TRUE)) { @@ -3596,7 +3596,7 @@ static int edbm_split_exec(bContext *C, wmOperator *op) EDBM_op_init(em, &bmop, op, "split geom=%hvef use_only_faces=%b", BM_ELEM_SELECT, FALSE); BMO_op_exec(em->bm, &bmop); BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, FALSE); - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL, BM_ELEM_SELECT, TRUE); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE); if (!EDBM_op_finish(em, &bmop, op, TRUE)) { return OPERATOR_CANCELLED; } @@ -3658,7 +3658,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op) } BMO_op_exec(bm, &spinop); EDBM_flag_disable_all(em, BM_ELEM_SELECT); - BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL, BM_ELEM_SELECT, TRUE); + BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE); if (!EDBM_op_finish(em, &spinop, op, TRUE)) { return OPERATOR_CANCELLED; } @@ -3782,7 +3782,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op) } BMO_op_exec(bm, &spinop); EDBM_flag_disable_all(em, BM_ELEM_SELECT); - BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL, BM_ELEM_SELECT, TRUE); + BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE); if (!EDBM_op_finish(em, &spinop, op, TRUE)) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 22c71d5d3ca..639e7668266 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -285,7 +285,7 @@ int EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op, const char *select_ BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, FALSE); - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, select_slot_out, BM_ALL, BM_ELEM_SELECT, TRUE); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, select_slot_out, BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE); va_end(list); return EDBM_op_finish(em, &bmop, op, TRUE); @@ -498,7 +498,7 @@ void EDBM_select_more(BMEditMesh *em) BM_ELEM_SELECT, FALSE, use_faces); BMO_op_exec(em->bm, &bmop); /* don't flush selection in edge/vertex mode */ - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL, BM_ELEM_SELECT, use_faces ? TRUE : FALSE); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? TRUE : FALSE); BMO_op_finish(em->bm, &bmop); EDBM_select_flush(em); @@ -514,7 +514,7 @@ void EDBM_select_less(BMEditMesh *em) BM_ELEM_SELECT, TRUE, use_faces); BMO_op_exec(em->bm, &bmop); /* don't flush selection in edge/vertex mode */ - BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "geom.out", BM_ALL, BM_ELEM_SELECT, use_faces ? TRUE : FALSE); + BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? TRUE : FALSE); BMO_op_finish(em->bm, &bmop); EDBM_selectmode_flush(em); diff --git a/source/blender/python/bmesh/bmesh_py_ops.c b/source/blender/python/bmesh/bmesh_py_ops.c index 84b06504d2e..09dda7261a8 100644 --- a/source/blender/python/bmesh/bmesh_py_ops.c +++ b/source/blender/python/bmesh/bmesh_py_ops.c @@ -242,18 +242,35 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject * return NULL; \ } (void)0 +#define BPY_BM_ELEM_TYPE_TEST(type_string) \ + if ((slot->slot_subtype.elem & BM_VERT) == 0) { \ + PyErr_Format(PyExc_TypeError, \ + "%.200s: keyword \"%.200s\" expected " \ + "a list of %.200s not " type_string, \ + self->opname, slot_name, \ + BPy_BMElem_StringFromHType(slot->slot_subtype.elem & BM_ALL)); \ + return NULL; \ + } (void)0 + if (BPy_BMVertSeq_Check(value)) { BPY_BM_GENERIC_MESH_TEST("verts"); + BPY_BM_ELEM_TYPE_TEST("verts"); + BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_VERT); } else if (BPy_BMEdgeSeq_Check(value)) { BPY_BM_GENERIC_MESH_TEST("edges"); + BPY_BM_ELEM_TYPE_TEST("edges"); BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_EDGE); } else if (BPy_BMFaceSeq_Check(value)) { BPY_BM_GENERIC_MESH_TEST("faces"); + BPY_BM_ELEM_TYPE_TEST("faces"); BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_FACE); } + +#undef BPY_BM_ELEM_TYPE_TEST + else if (BPy_BMElemSeq_Check(value)) { BMIter iter; BMHeader *ele; @@ -281,7 +298,7 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject * Py_ssize_t elem_array_len; elem_array = BPy_BMElem_PySeq_As_Array(&bm, value, 0, PY_SSIZE_T_MAX, - &elem_array_len, BM_VERT | BM_EDGE | BM_FACE, + &elem_array_len, (slot->slot_subtype.elem & BM_ALL_NOLOOP), TRUE, TRUE, slot_name); /* error is set above */ @@ -308,7 +325,7 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject * case BMO_OP_SLOT_MAPPING: { /* first check types */ - if (slot->slot_subtype != BMO_OP_SLOT_SUBTYPE_MAP_EMPTY) { + if (slot->slot_subtype.map != BMO_OP_SLOT_SUBTYPE_MAP_EMPTY) { if (!PyDict_Check(value)) { PyErr_Format(PyExc_TypeError, "%.200s: keyword \"%.200s\" expected " @@ -327,7 +344,7 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject * } } - switch (slot->slot_subtype) { + switch (slot->slot_subtype.map) { /* this could be a static function */ #define BPY_BM_MAPPING_KEY_CHECK(arg_key) \ @@ -467,7 +484,6 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject * break; } case BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL: - default: { /* can't convert from these */ PyErr_Format(PyExc_NotImplementedError, @@ -548,7 +564,7 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject * GHash *slot_hash = BMO_SLOT_AS_GHASH(slot); GHashIterator hash_iter; - switch (slot->slot_subtype) { + switch (slot->slot_subtype.map) { case BMO_OP_SLOT_SUBTYPE_MAP_ELEM: { item = PyDict_New(); @@ -560,6 +576,8 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject * PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); PyObject *py_val = BPy_BMElem_CreatePyObject(bm, *(void **)BMO_OP_SLOT_MAPPING_DATA(ele_val)); + BLI_assert(slot->slot_subtype.elem & ((BPy_BMElem *)py_val)->ele->head.htype); + PyDict_SetItem(ret, py_key, py_val); Py_DECREF(py_key); Py_DECREF(py_val); @@ -638,7 +656,6 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject * break; } case BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL: - default: /* can't convert from these */ item = (Py_INCREF(Py_None), Py_None); break; -- cgit v1.2.3 From 33c92a02e41636302a803cd08d9534b9e8da439c Mon Sep 17 00:00:00 2001 From: Howard Trickey Date: Tue, 27 Nov 2012 01:07:22 +0000 Subject: Bevel: better round profile code. Easier to understand, no touchy intersect code, and works even when arms aren't equal length. Old code ifdef'd for now, will remove soon. --- source/blender/bmesh/tools/bmesh_bevel.c | 61 ++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 7e5eb02fa03..e4509dd0fa9 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -545,6 +545,7 @@ static void get_point_on_round_edge(const float uv[2], #else /* USE_ALTERNATE_ADJ */ +#ifdef OLD_ROUND_EDGE /* * calculation of points on the round profile * r - result, coordinate of point on round profile @@ -632,6 +633,66 @@ static void get_point_on_round_edge(EdgeHalf *e, int k, interp_v3_v3v3(r_co, va, vb, (float)k / (float)n); } } +#else + +/* + * Find the point (/n) of the way around the round profile for e, + * where start point is va, midarc point is vmid, and end point is vb. + * Return the answer in profileco. + * Method: + * Find vo, the origin of the parallelogram with other three points va, vmid, vb. + * Also find vd, which is in direction normal to parallelogram and 1 unit away + * from the origin. + * The quarter circle in first quadrant of unit square will be mapped to the + * quadrant of a sheared ellipse in the parallelgram, using a matrix. + * The matrix mat is calculated to map: + * (0,1,0) -> va + * (1,1,0) -> vmid + * (1,0,0) -> vb + * (0,1,1) -> vd + * However if va -- vmid -- vb is approximately a straight line, just + * interpolate along the line. + */ +static void get_point_on_round_edge(EdgeHalf *e, int k, + const float va[3], const float vmid[3], const float vb[3], + float r_co[3]) +{ + float vo[3], vd[3], vb_vmid[3], va_vmid[3], vddir[3], p[3], angle; + float m[4][4] = MAT4_UNITY; + int n = e->seg; + + sub_v3_v3v3(va_vmid, vmid, va); + sub_v3_v3v3(vb_vmid, vmid, vb); + if (fabs(angle_v3v3(va_vmid, vb_vmid) - (float)M_PI) > 100.f *(float)BEVEL_EPSILON) { + sub_v3_v3v3(vo, va, vb_vmid); + cross_v3_v3v3(vddir, vb_vmid, va_vmid); + normalize_v3(vddir); + add_v3_v3v3(vd, vo, vddir); + + /* The cols of m are: {vmid - va, vmid - vb, vmid + vd - va -vb, va + vb - vmid; + * blender transform matrices are stored such that m[i][*] is ith column; + * the last elements of each col remain as they are in unity matrix */ + sub_v3_v3v3(&m[0][0], vmid, va); + sub_v3_v3v3(&m[1][0], vmid, vb); + add_v3_v3v3(&m[2][0], vmid, vd); + sub_v3_v3(&m[2][0], va); + sub_v3_v3(&m[2][0], vb); + add_v3_v3v3(&m[3][0], va, vb); + sub_v3_v3(&m[3][0], vmid); + + /* Now find point k/(e->seg) along quarter circle from (0,1,0) to (1,0,0) */ + angle = (float)M_PI * (float)k / (2.0f * (float)n); /* angle from y axis */ + p[0] = sinf(angle); + p[1] = cosf(angle); + p[2] = 0.0f; + mul_v3_m4v3(r_co, m, p); + } + else { + /* planar case */ + interp_v3_v3v3(r_co, va, vb, (float)k / (float)n); + } +} +#endif /* ! OLD_ROUND_EDGE */ #endif /* !USE_ALTERNATE_ADJ */ -- cgit v1.2.3 From 9982b283e6f794057d37f9abcda12013b773dcdc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 Nov 2012 02:34:40 +0000 Subject: fix for asserts added in own recent commit with more strict type-checking - BMO_slot_copy now only copies compatible elements. other minor changes - don't use text.format(...), convention for UI scripts is C style string formatting. - rename bmo_edgenet_prepare --> bmo_edgenet_prepare_exec - float/double warning in bevel. --- .../scripts/startup/bl_ui/properties_particle.py | 2 +- source/blender/bmesh/intern/bmesh_opdefines.c | 2 +- source/blender/bmesh/intern/bmesh_operator_api.h | 4 +- source/blender/bmesh/intern/bmesh_operators.c | 46 ++++++++++++++++++++-- .../blender/bmesh/intern/bmesh_operators_private.h | 2 +- source/blender/bmesh/operators/bmo_create.c | 2 +- source/blender/bmesh/tools/bmesh_bevel.c | 2 +- source/blender/editors/mesh/editmesh_utils.c | 7 +++- 8 files changed, 56 insertions(+), 11 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index 6fcd56fb99e..3f672d2a977 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -148,7 +148,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel): #row.label(text="Render") if part.is_fluid: - layout.label(text="{} fluid particles for this frame".format(str(part.count))) + layout.label(text="%d fluid particles for this frame" % part.count) return row = col.row() diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index f14fac64ba3..64b3ce66ca9 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -569,7 +569,7 @@ static BMOpDefine bmo_edgenet_prepare_def = { {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* new edges */ {{'\0'}}, }, - bmo_edgenet_prepare, + bmo_edgenet_prepare_exec, 0, }; diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h index 245a53ebed2..1bb83a12e48 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api.h +++ b/source/blender/bmesh/intern/bmesh_operator_api.h @@ -136,8 +136,8 @@ typedef enum eBMOpSlotSubType_Ptr { } eBMOpSlotSubType_Ptr; typedef union eBMOpSlotSubType_Union { - eBMOpSlotSubType_Map elem; - eBMOpSlotSubType_Map ptr; + eBMOpSlotSubType_Elem elem; + eBMOpSlotSubType_Ptr ptr; eBMOpSlotSubType_Map map; } eBMOpSlotSubType_Union; diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index f1bf4fd4d37..20fffe71636 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -288,9 +288,49 @@ void _bmo_slot_copy(BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS], const char *slot_n slot_dst->data.buf = NULL; slot_dst->len = slot_src->len; if (slot_dst->len) { - const int slot_alloc_size = BMO_OPSLOT_TYPEINFO[slot_dst->slot_type] * slot_dst->len; - slot_dst->data.buf = BLI_memarena_alloc(arena_dst, slot_alloc_size); - memcpy(slot_dst->data.buf, slot_src->data.buf, slot_alloc_size); + /* check dest has all flags enabled that the source has */ + const eBMOpSlotSubType_Elem src_elem_flag = (slot_src->slot_subtype.elem & BM_ALL_NOLOOP); + const eBMOpSlotSubType_Elem dst_elem_flag = (slot_dst->slot_subtype.elem & BM_ALL_NOLOOP); + + if ((src_elem_flag | dst_elem_flag) == dst_elem_flag) { + /* pass */ + } + else { + /* check types */ + const unsigned int tot = slot_src->len; + unsigned int i; + unsigned int out = 0; + BMElem **ele_src = (BMElem **)slot_src->data.buf; + for (i = 0; i < tot; i++, ele_src++) { + if ((*ele_src)->head.htype & dst_elem_flag) { + out++; + } + } + if (out != tot) { + slot_dst->len = out; + } + } + + if (slot_dst->len) { + const int slot_alloc_size = BMO_OPSLOT_TYPEINFO[slot_dst->slot_type] * slot_dst->len; + slot_dst->data.buf = BLI_memarena_alloc(arena_dst, slot_alloc_size); + if (slot_src->len == slot_dst->len) { + memcpy(slot_dst->data.buf, slot_src->data.buf, slot_alloc_size); + } + else { + /* only copy compatible elements */ + const unsigned int tot = slot_src->len; + unsigned int i; + BMElem **ele_src = (BMElem **)slot_src->data.buf; + BMElem **ele_dst = (BMElem **)slot_dst->data.buf; + for (i = 0; i < tot; i++, ele_src++) { + if ((*ele_src)->head.htype & dst_elem_flag) { + *ele_dst = *ele_src; + ele_dst++; + } + } + } + } } } else if (slot_dst->slot_type == BMO_OP_SLOT_MAPPING) { diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h index 65c9cf0c421..9175af1c822 100644 --- a/source/blender/bmesh/intern/bmesh_operators_private.h +++ b/source/blender/bmesh/intern/bmesh_operators_private.h @@ -61,7 +61,7 @@ void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op); void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op); void bmo_duplicate_exec(BMesh *bm, BMOperator *op); void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op); -void bmo_edgenet_prepare(BMesh *bm, BMOperator *op); +void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op); void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op); void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op); void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op); diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c index 987aa8cdf99..a6bbd092760 100644 --- a/source/blender/bmesh/operators/bmo_create.c +++ b/source/blender/bmesh/operators/bmo_create.c @@ -1098,7 +1098,7 @@ static BMEdge *edge_next(BMesh *bm, BMEdge *e) return NULL; } -void bmo_edgenet_prepare(BMesh *bm, BMOperator *op) +void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op) { BMOIter siter; BMEdge *e; diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index e4509dd0fa9..0d16d0af114 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -663,7 +663,7 @@ static void get_point_on_round_edge(EdgeHalf *e, int k, sub_v3_v3v3(va_vmid, vmid, va); sub_v3_v3v3(vb_vmid, vmid, vb); - if (fabs(angle_v3v3(va_vmid, vb_vmid) - (float)M_PI) > 100.f *(float)BEVEL_EPSILON) { + if (fabsf(angle_v3v3(va_vmid, vb_vmid) - (float)M_PI) > 100.f *(float)BEVEL_EPSILON) { sub_v3_v3v3(vo, va, vb_vmid); cross_v3_v3v3(vddir, vb_vmid, va_vmid); normalize_v3(vddir); diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 639e7668266..2cf63586142 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -265,9 +265,11 @@ int EDBM_op_callf(BMEditMesh *em, wmOperator *op, const char *fmt, ...) int EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op, const char *select_slot_out, const char *fmt, ...) { + BMOpSlot *slot_select_out; BMesh *bm = em->bm; BMOperator bmop; va_list list; + char hflag; va_start(list, fmt); @@ -283,9 +285,12 @@ int EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op, const char *select_ BMO_op_exec(bm, &bmop); + slot_select_out = BMO_slot_get(bmop.slots_out, select_slot_out); + hflag = slot_select_out->slot_subtype.elem & BM_ALL_NOLOOP; + BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, FALSE); - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, select_slot_out, BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, select_slot_out, hflag, BM_ELEM_SELECT, TRUE); va_end(list); return EDBM_op_finish(em, &bmop, op, TRUE); -- cgit v1.2.3 From 90666d34369e914e09030e85d497271cf77454db Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 Nov 2012 06:53:26 +0000 Subject: code cleanup: bmesh operator comments, readying for doc-generation. --- source/blender/bmesh/intern/bmesh_opdefines.c | 297 +++++++++++++-------- source/blender/bmesh/operators/bmo_connect.c | 2 + .../editors/interface/interface_templates.c | 2 +- 3 files changed, 185 insertions(+), 116 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 64b3ce66ca9..75f187e3837 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -59,8 +59,10 @@ #include "bmesh.h" #include "intern/bmesh_private.h" -/* ok, I'm going to write a little docgen script. so all - * bmop comments must conform to the following template/rules: +/* The formatting of these bmesh operators is parsed by + * 'doc/python_api/rst_from_bmesh_opdefines.py' + * for use in python docs, so reStructuredText may be used + * rather then doxygen syntax. * * template (py quotes used because nested comments don't work * on all C compilers): @@ -79,21 +81,22 @@ * so the first line is the "title" of the bmop. * subsequent line blocks separated by blank lines * are paragraphs. individual descriptions of slots - * would be extracted from comments - * next to them, e.g. + * are extracted from comments next to them. * - * {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, //output slot, boundary region + * eg: + * {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, """ output slot, boundary region """ * - * the doc generator would automatically detect the presence of "output slot" - * and flag the slot as an output. the same happens for "input slot". also - * note that "edges", "faces", "verts", "loops", and "geometry" are valid - * substitutions for "slot". + * ... or: * - * note that slots default to being input slots. + * """ output slot, boundary region """ + * {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, + * + * Both are acceptable. + * note that '//' comments are ignored. */ /* - * Vertex Smooth + * Vertex Smooth. * * Smooths vertices by using a basic vertex averaging scheme. */ @@ -104,7 +107,7 @@ static BMOpDefine bmo_smooth_vert_def = { {"mirror_clip_x", BMO_OP_SLOT_BOOL}, /* set vertices close to the x axis before the operation to 0 */ {"mirror_clip_y", BMO_OP_SLOT_BOOL}, /* set vertices close to the y axis before the operation to 0 */ {"mirror_clip_z", BMO_OP_SLOT_BOOL}, /* set vertices close to the z axis before the operation to 0 */ - {"clip_dist", BMO_OP_SLOT_FLT}, /* clipping threshod for the above three slots */ + {"clip_dist", BMO_OP_SLOT_FLT}, /* clipping threshold for the above three slots */ {"use_axis_x", BMO_OP_SLOT_BOOL}, /* smooth vertices along X axis */ {"use_axis_y", BMO_OP_SLOT_BOOL}, /* smooth vertices along Y axis */ {"use_axis_z", BMO_OP_SLOT_BOOL}, /* smooth vertices along Z axis */ @@ -116,9 +119,10 @@ static BMOpDefine bmo_smooth_vert_def = { }; /* - * Vertext Smooth Laplacian + * Vertext Smooth Laplacian. + * * Smooths vertices by using Laplacian smoothing propose by. - * Desbrun, et al. Implicit Fairing of Irregular Meshes using Diffusion and Curvature Flow + * Desbrun, et al. Implicit Fairing of Irregular Meshes using Diffusion and Curvature Flow. */ static BMOpDefine bmo_smooth_laplacian_vert_def = { "smooth_laplacian_vert", @@ -138,16 +142,15 @@ static BMOpDefine bmo_smooth_laplacian_vert_def = { }; /* - * Right-Hand Faces + * Right-Hand Faces. * * Computes an "outside" normal for the specified input faces. */ - static BMOpDefine bmo_recalc_face_normals_def = { "recalc_face_normals", /* slots_in */ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, - {"use_flip", BMO_OP_SLOT_BOOL}, /* internal flag, used by bmesh_rationalize_normals */ + {"use_flip", BMO_OP_SLOT_BOOL}, /* Reverse the result */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -156,13 +159,13 @@ static BMOpDefine bmo_recalc_face_normals_def = { }; /* - * Region Extend + * Region Extend. * * used to implement the select more/less tools. * this puts some geometry surrounding regions of * geometry in geom into geom.out. * - * if usefaces is 0 then geom.out spits out verts and edges, + * if use_faces is 0 then geom.out spits out verts and edges, * otherwise it spits out faces. */ static BMOpDefine bmo_region_extend_def = { @@ -182,16 +185,16 @@ static BMOpDefine bmo_region_extend_def = { }; /* - * Edge Rotate + * Edge Rotate. * * Rotates edges topologically. Also known as "spin edge" to some people. - * Simple example: [/] becomes [|] then [\]. + * Simple example: ``[/] becomes [|] then [\]``. */ static BMOpDefine bmo_rotate_edges_def = { "rotate_edges", /* slots_in */ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */ - {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate edge counter-clockwise if true, othewise clockwise */ + {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate edge counter-clockwise if true, otherwise clockwise */ {{'\0'}}, }, /* slots_out */ @@ -203,10 +206,10 @@ static BMOpDefine bmo_rotate_edges_def = { }; /* - * Reverse Faces + * Reverse Faces. * - * Reverses the winding (vertex order) of faces. This has the effect of - * flipping the normal. + * Reverses the winding (vertex order) of faces. + * This has the effect of flipping the normal. */ static BMOpDefine bmo_reverse_faces_def = { "reverse_faces", @@ -220,7 +223,7 @@ static BMOpDefine bmo_reverse_faces_def = { }; /* - * Edge Bisect + * Edge Bisect. * * Splits input edges (but doesn't do anything else). * This creates a 2-valence vert. @@ -241,13 +244,12 @@ static BMOpDefine bmo_bisect_edges_def = { }; /* - * Mirror + * Mirror. * * Mirrors geometry along an axis. The resulting geometry is welded on using * merge_dist. Pairs of original/mirrored vertices are welded using the merge_dist * parameter (which defines the minimum distance for welding to happen). */ - static BMOpDefine bmo_mirror_def = { "mirror", /* slots_in */ @@ -268,10 +270,10 @@ static BMOpDefine bmo_mirror_def = { }; /* - * Find Doubles + * Find Doubles. * - * Takes input verts and find vertices they should weld to. Outputs a - * mapping slot suitable for use with the weld verts bmop. + * Takes input verts and find vertices they should weld to. + * Outputs a mapping slot suitable for use with the weld verts bmop. * * If keep_verts is used, vertices outside that set can only be merged * with vertices in that set. @@ -293,7 +295,7 @@ static BMOpDefine bmo_find_doubles_def = { }; /* - * Remove Doubles + * Remove Doubles. * * Finds groups of vertices closer then dist and merges them together, * using the weld verts bmop. @@ -311,11 +313,11 @@ static BMOpDefine bmo_remove_doubles_def = { }; /* - * Auto Merge + * Auto Merge. * - * Finds groups of vertices closer then dist and merges them together, + * Finds groups of vertices closer then **dist** and merges them together, * using the weld verts bmop. The merges must go from a vert not in - * verts to one in verts. + * **verts** to one in **verts**. */ static BMOpDefine bmo_automerge_def = { "automerge", @@ -330,7 +332,7 @@ static BMOpDefine bmo_automerge_def = { }; /* - * Collapse Connected + * Collapse Connected. * * Collapses connected vertices */ @@ -345,9 +347,8 @@ static BMOpDefine bmo_collapse_def = { BMO_OP_FLAG_UNTAN_MULTIRES, }; - /* - * Facedata point Merge + * Face-Data Point Merge. * * Merge uv/vcols at a specific vertex. */ @@ -364,7 +365,7 @@ static BMOpDefine bmo_pointmerge_facedata_def = { }; /* - * Average Vertices Facevert Data + * Average Vertices Facevert Data. * * Merge uv/vcols associated with the input vertices at * the bounding box center. (I know, it's not averaging but @@ -382,7 +383,7 @@ static BMOpDefine bmo_average_vert_facedata_def = { }; /* - * Point Merge + * Point Merge. * * Merge verts together at a point. */ @@ -399,7 +400,7 @@ static BMOpDefine bmo_pointmerge_def = { }; /* - * Collapse Connected UVs + * Collapse Connected UV's. * * Collapses connected UV vertices. */ @@ -415,9 +416,9 @@ static BMOpDefine bmo_collapse_uvs_def = { }; /* - * Weld Verts + * Weld Verts. * - * Welds verts together (kindof like remove doubles, merge, etc, all of which + * Welds verts together (kind-of like remove doubles, merge, etc, all of which * use or will use this bmop). You pass in mappings from vertices to the vertices * they weld with. */ @@ -434,7 +435,7 @@ static BMOpDefine bmo_weld_verts_def = { }; /* - * Make Vertex + * Make Vertex. * * Creates a single vertex; this bmop was necessary * for click-create-vertex. @@ -454,7 +455,7 @@ static BMOpDefine bmo_create_vert_def = { }; /* - * Join Triangles + * Join Triangles. * * Tries to intelligently join triangles according * to various settings and stuff. @@ -479,12 +480,11 @@ static BMOpDefine bmo_join_triangles_def = { }; /* - * Contextual Create + * Contextual Create. * - * This is basically fkey, it creates + * This is basically F-key, it creates * new faces from vertices, makes stuff from edge nets, - * makes wire edges, etc. It also dissolves - * faces. + * makes wire edges, etc. It also dissolves faces. * * Three verts become a triangle, four become a quad. Two * become a wire edge. @@ -508,7 +508,7 @@ static BMOpDefine bmo_contextual_create_def = { }; /* - * Bridge edge loops with faces + * Bridge edge loops with faces. */ static BMOpDefine bmo_bridge_loops_def = { "bridge_loops", @@ -526,6 +526,11 @@ static BMOpDefine bmo_bridge_loops_def = { 0, }; +/* + * Edge Net Fill. + * + * Create faces defined by enclosed edges. + */ static BMOpDefine bmo_edgenet_fill_def = { "edgenet_fill", /* slots_in */ @@ -550,7 +555,7 @@ static BMOpDefine bmo_edgenet_fill_def = { }; /* - * Edgenet Prepare + * Edgenet Prepare. * * Identifies several useful edge loop cases and modifies them so * they'll become a face when edgenet_fill is called. The cases covered are: @@ -574,7 +579,7 @@ static BMOpDefine bmo_edgenet_prepare_def = { }; /* - * Rotate + * Rotate. * * Rotate vertices around a center, using a 3x3 rotation * matrix. Equivalent of the old rotateflag function. @@ -593,7 +598,7 @@ static BMOpDefine bmo_rotate_def = { }; /* - * Translate + * Translate. * * Translate vertices by an offset. Equivalent of the * old translateflag function. @@ -611,7 +616,7 @@ static BMOpDefine bmo_translate_def = { }; /* - * Scale + * Scale. * * Scales vertices by an offset. */ @@ -629,7 +634,7 @@ static BMOpDefine bmo_scale_def = { /* - * Transform + * Transform. * * Transforms a set of vertices by a matrix. Multiplies * the vertex coordinates with the matrix. @@ -647,7 +652,7 @@ static BMOpDefine bmo_transform_def = { }; /* - * Object Load BMesh + * Object Load BMesh. * * Loads a bmesh into an object/mesh. This is a "private" * bmop. @@ -666,7 +671,7 @@ static BMOpDefine bmo_object_load_bmesh_def = { /* - * BMesh to Mesh + * BMesh to Mesh. * * Converts a bmesh to a Mesh. This is reserved for exiting editmode. */ @@ -687,7 +692,7 @@ static BMOpDefine bmo_bmesh_to_mesh_def = { }; /* - * Mesh to BMesh + * Mesh to BMesh. * * Load the contents of a mesh into the bmesh. this bmop is private, it's * reserved exclusively for entering editmode. @@ -709,7 +714,7 @@ static BMOpDefine bmo_mesh_to_bmesh_def = { }; /* - * Individual Face Extrude + * Individual Face Extrude. * * Extrudes faces individually. */ @@ -728,7 +733,7 @@ static BMOpDefine bmo_extrude_discrete_faces_def = { }; /* - * Extrude Only Edges + * Extrude Only Edges. * * Extrudes Edges into faces, note that this is very simple, there's no fancy * winged extrusion. @@ -748,7 +753,7 @@ static BMOpDefine bmo_extrude_edge_only_def = { }; /* - * Individual Vertex Extrude + * Individual Vertex Extrude. * * Extrudes wire edges from vertices. */ @@ -767,6 +772,11 @@ static BMOpDefine bmo_extrude_vert_indiv_def = { 0 }; +/* + * Connect Verts. + * + * Split faces by adding edges that connect **verts**. + */ static BMOpDefine bmo_connect_verts_def = { "connect_verts", /* slots_in */ @@ -781,6 +791,11 @@ static BMOpDefine bmo_connect_verts_def = { BMO_OP_FLAG_UNTAN_MULTIRES }; +/* + * Extrude Faces. + * + * Extrude operator (does not transform) + */ static BMOpDefine bmo_extrude_face_region_def = { "extrude_face_region", /* slots_in */ @@ -797,6 +812,9 @@ static BMOpDefine bmo_extrude_face_region_def = { 0 }; +/* + * Dissolve Verts. + */ static BMOpDefine bmo_dissolve_verts_def = { "dissolve_verts", /* slots_in */ @@ -808,6 +826,9 @@ static BMOpDefine bmo_dissolve_verts_def = { BMO_OP_FLAG_UNTAN_MULTIRES }; +/* + * Dissolve Edges. + */ static BMOpDefine bmo_dissolve_edges_def = { "dissolve_edges", /* slots_in */ @@ -823,6 +844,9 @@ static BMOpDefine bmo_dissolve_edges_def = { BMO_OP_FLAG_UNTAN_MULTIRES }; +/* + * Dissolve Edge Loop. + */ static BMOpDefine bmo_dissolve_edge_loop_def = { "dissolve_edge_loop", /* slots_in */ @@ -837,6 +861,9 @@ static BMOpDefine bmo_dissolve_edge_loop_def = { BMO_OP_FLAG_UNTAN_MULTIRES }; +/* + * Dissolve Faces. + */ static BMOpDefine bmo_dissolve_faces_def = { "dissolve_faces", /* slots_in */ @@ -852,6 +879,11 @@ static BMOpDefine bmo_dissolve_faces_def = { BMO_OP_FLAG_UNTAN_MULTIRES }; +/* + * Limited Dissolve. + * + * Dissolve planar faces and co-linear edges. + */ static BMOpDefine bmo_dissolve_limit_def = { "dissolve_limit", /* slots_in */ @@ -866,6 +898,9 @@ static BMOpDefine bmo_dissolve_limit_def = { BMO_OP_FLAG_UNTAN_MULTIRES }; +/* + * Triangulate. + */ static BMOpDefine bmo_triangulate_def = { "triangulate", /* slots_in */ @@ -883,6 +918,11 @@ static BMOpDefine bmo_triangulate_def = { BMO_OP_FLAG_UNTAN_MULTIRES }; +/* + * Un-Subdivide. + * + * Reduce detail in geometry containing grids. + */ static BMOpDefine bmo_unsubdivide_def = { "unsubdivide", /* slots_in */ @@ -895,6 +935,12 @@ static BMOpDefine bmo_unsubdivide_def = { BMO_OP_FLAG_UNTAN_MULTIRES }; +/* + * Subdivide Edges. + * + * Advanced operator for subdividing edges + * with options for face patterns, smoothing and randomization. + */ static BMOpDefine bmo_subdivide_edges_def = { "subdivide_edges", /* slots_in */ @@ -925,6 +971,11 @@ static BMOpDefine bmo_subdivide_edges_def = { BMO_OP_FLAG_UNTAN_MULTIRES }; +/* + * Delete Geometry. + * + * Utility operator to delete geometry. + */ static BMOpDefine bmo_delete_def = { "delete", /* slots_in */ @@ -937,6 +988,12 @@ static BMOpDefine bmo_delete_def = { 0 }; +/* + * Duplicate Geometry. + * + * Utility operator to duplicate geometry, + * optionally into a destination mesh. + */ static BMOpDefine bmo_duplicate_def = { "duplicate", /* slots_in */ @@ -959,6 +1016,12 @@ static BMOpDefine bmo_duplicate_def = { 0 }; +/* + * Split Off Geometry. + * + * Disconnect geometry from adjacent edges and faces, + * optionally into a destination mesh. + */ static BMOpDefine bmo_split_def = { "split", /* slots_in */ @@ -979,7 +1042,7 @@ static BMOpDefine bmo_split_def = { }; /* - * Spin + * Spin. * * Extrude or duplicate geometry a number of times, * rotating and possibly translating after each step @@ -1006,7 +1069,7 @@ static BMOpDefine bmo_spin_def = { /* - * Similar faces search + * Similar Faces Search. * * Find similar faces (area/material/perimeter, ...). */ @@ -1028,7 +1091,7 @@ static BMOpDefine bmo_similar_faces_def = { }; /* - * Similar edges search + * Similar Edges Search. * * Find similar edges (length, direction, edge, seam, ...). */ @@ -1050,7 +1113,7 @@ static BMOpDefine bmo_similar_edges_def = { }; /* - * Similar vertices search + * Similar Verts Search. * * Find similar vertices (normal, face, vertex group, ...). */ @@ -1072,14 +1135,15 @@ static BMOpDefine bmo_similar_verts_def = { }; /* - * uv rotation - * cycle the uvs + * UV Rotation. + * + * Cycle the loop UV's */ static BMOpDefine bmo_rotate_uvs_def = { "rotate_uvs", /* slots_in */ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */ - {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, othewise clockwise */ + {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, otherwise clockwise */ {{'\0'}}, }, /* slots_out */ @@ -1089,8 +1153,9 @@ static BMOpDefine bmo_rotate_uvs_def = { }; /* - * uv reverse - * reverse the uvs + * UV Reverse. + * + * Reverse the UV's */ static BMOpDefine bmo_reverse_uvs_def = { "reverse_uvs", @@ -1104,14 +1169,15 @@ static BMOpDefine bmo_reverse_uvs_def = { }; /* - * color rotation - * cycle the colors + * Color Rotation. + * + * Cycle the loop colors */ static BMOpDefine bmo_rotate_colors_def = { "rotate_colors", /* slots_in */ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */ - {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, othewise clockwise */ + {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, otherwise clockwise */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -1120,8 +1186,9 @@ static BMOpDefine bmo_rotate_colors_def = { }; /* - * color reverse - * reverse the colors + * Color Reverse + * + * Reverse the loop colors. */ static BMOpDefine bmo_reverse_colors_def = { "reverse_colors", @@ -1135,9 +1202,9 @@ static BMOpDefine bmo_reverse_colors_def = { }; /* - * Similar vertices search + * Shortest Path. * - * Find similar vertices (normal, face, vertex group, ...). + * Select the shortest path between 2 verts. */ static BMOpDefine bmo_shortest_path_def = { "shortest_path", @@ -1156,7 +1223,7 @@ static BMOpDefine bmo_shortest_path_def = { }; /* - * Edge Split + * Edge Split. * * Disconnects faces along input edges. */ @@ -1178,7 +1245,7 @@ static BMOpDefine bmo_split_edges_def = { }; /* - * Create Grid + * Create Grid. * * Creates a grid with a variable number of subdivisions */ @@ -1200,7 +1267,7 @@ static BMOpDefine bmo_create_grid_def = { }; /* - * Create UV Sphere + * Create UV Sphere. * * Creates a grid with a variable number of subdivisions */ @@ -1222,7 +1289,7 @@ static BMOpDefine bmo_create_uvsphere_def = { }; /* - * Create Ico Sphere + * Create Ico-Sphere. * * Creates a grid with a variable number of subdivisions */ @@ -1243,9 +1310,9 @@ static BMOpDefine bmo_create_icosphere_def = { }; /* - * Create Suzanne + * Create Suzanne. * - * Creates a monkey. Be wary. + * Creates a monkey (standard blender primitive). */ static BMOpDefine bmo_create_monkey_def = { "create_monkey", @@ -1262,14 +1329,14 @@ static BMOpDefine bmo_create_monkey_def = { }; /* - * Create Cone + * Create Cone. * * Creates a cone with variable depth at both ends */ static BMOpDefine bmo_create_cone_def = { "create_cone", /* slots_in */ - {{"cap_ends", BMO_OP_SLOT_BOOL}, /* wheter or not to fill in the ends with faces */ + {{"cap_ends", BMO_OP_SLOT_BOOL}, /* whether or not to fill in the ends with faces */ {"cap_tris", BMO_OP_SLOT_BOOL}, /* fill ends with triangles instead of ngons */ {"segments", BMO_OP_SLOT_INT}, {"diameter1", BMO_OP_SLOT_FLT}, /* diameter of one end */ @@ -1287,12 +1354,12 @@ static BMOpDefine bmo_create_cone_def = { }; /* - * Creates a circle + * Creates a Circle. */ static BMOpDefine bmo_create_circle_def = { "create_circle", /* slots_in */ - {{"cap_ends", BMO_OP_SLOT_BOOL}, /* wheter or not to fill in the ends with faces */ + {{"cap_ends", BMO_OP_SLOT_BOOL}, /* whether or not to fill in the ends with faces */ {"cap_tris", BMO_OP_SLOT_BOOL}, /* fill ends with triangles instead of ngons */ {"segments", BMO_OP_SLOT_INT}, {"diameter", BMO_OP_SLOT_FLT}, /* diameter of one end */ @@ -1308,9 +1375,9 @@ static BMOpDefine bmo_create_circle_def = { }; /* - * Create Cone + * Create Cube * - * Creates a cone with variable depth at both ends + * Creates a cube. */ static BMOpDefine bmo_create_cube_def = { "create_cube", @@ -1328,7 +1395,7 @@ static BMOpDefine bmo_create_cube_def = { }; /* - * Bevel + * Bevel. * * Bevels edges and vertices */ @@ -1344,27 +1411,27 @@ static BMOpDefine bmo_bevel_def = { {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */ {{'\0'}}, }, -#if 0 /* old bevel*/ - {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input edges and vertices */ - {"face_spans", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new geometry */ - {"face_holes", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new geometry */ - {"use_lengths", BMO_OP_SLOT_BOOL}, /* grab edge lengths from a PROP_FLT customdata layer */ - {"use_even", BMO_OP_SLOT_BOOL}, /* corner vert placement: use shell/angle calculations */ - {"use_dist", BMO_OP_SLOT_BOOL}, /* corner vert placement: evaluate percent as a distance, - * modifier uses this. We could do this as another float setting */ - {"lengthlayer", BMO_OP_SLOT_INT}, /* which PROP_FLT layer to us */ - {"percent", BMO_OP_SLOT_FLT}, /* percentage to expand beveled edge */ - {{'\0'}}, - }, -#endif +/* old bevel*/ +// {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input edges and vertices */ +// {"face_spans", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new geometry */ +// {"face_holes", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new geometry */ +// {"use_lengths", BMO_OP_SLOT_BOOL}, /* grab edge lengths from a PROP_FLT customdata layer */ +// {"use_even", BMO_OP_SLOT_BOOL}, /* corner vert placement: use shell/angle calculations */ +// {"use_dist", BMO_OP_SLOT_BOOL}, /* corner vert placement: evaluate percent as a distance, +// * modifier uses this. We could do this as another float setting */ +// {"lengthlayer", BMO_OP_SLOT_INT}, /* which PROP_FLT layer to us */ +// {"percent", BMO_OP_SLOT_FLT}, /* percentage to expand beveled edge */ +// {{'\0'}}, +// }, + bmo_bevel_exec, BMO_OP_FLAG_UNTAN_MULTIRES }; /* - * Beautify Fill + * Beautify Fill. * - * Makes triangle a bit nicer + * Rotate edges to create more evenly spaced triangles. */ static BMOpDefine bmo_beautify_fill_def = { "beautify_fill", @@ -1382,7 +1449,7 @@ static BMOpDefine bmo_beautify_fill_def = { }; /* - * Triangle Fill + * Triangle Fill. * * Fill edges with triangles */ @@ -1401,7 +1468,7 @@ static BMOpDefine bmo_triangle_fill_def = { }; /* - * Solidify + * Solidify. * * Turns a mesh into a shell with thickness */ @@ -1421,9 +1488,9 @@ static BMOpDefine bmo_solidify_def = { }; /* - * Face Inset + * Face Inset. * - * Extrudes faces individually. + * Inset or outset faces. */ static BMOpDefine bmo_inset_def = { "inset", @@ -1446,9 +1513,9 @@ static BMOpDefine bmo_inset_def = { }; /* - * Wire Frame + * Wire Frame. * - * Makes a wire copy of faces. + * Makes a wire-frame copy of faces. */ static BMOpDefine bmo_wireframe_def = { "wireframe", @@ -1471,9 +1538,9 @@ static BMOpDefine bmo_wireframe_def = { }; /* - * Vertex Slide + * Vertex Slide. * - * Translates vertes along an edge + * Translates verts along an edge */ static BMOpDefine bmo_slide_vert_def = { "slide_vert", @@ -1527,9 +1594,9 @@ static BMOpDefine bmo_convex_hull_def = { #endif /* - * Symmetrize + * Symmetrize. * - * Mekes the mesh elements in the "input" slot symmetrical. Unlike + * Makes the mesh elements in the "input" slot symmetrical. Unlike * normal mirroring, it only copies in one direction, as specified by * the "direction" slot. The edges and faces that cross the plane of * symmetry are split as needed to enforce symmetry. diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c index b7bb57bb19d..12edffec213 100644 --- a/source/blender/bmesh/operators/bmo_connect.c +++ b/source/blender/bmesh/operators/bmo_connect.c @@ -54,6 +54,8 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op) BMO_slot_buffer_flag_enable(bm, op->slots_in, "verts", BM_VERT, VERT_INPUT); + /* BMESH_TODO, loop over vert faces: + * faster then looping over all faces, then searching each for flagged verts*/ for (f = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL); f; f = BM_iter_step(&iter)) { BLI_array_empty(loops_split); BLI_array_empty(verts_pair); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 2f1a37dc8ce..61d14bf3bb7 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -786,7 +786,7 @@ static int modifier_can_delete(ModifierData *md) return 1; } -/* Check wheter Modifier is a simulation or not, this is used for switching to the physics/particles context tab */ +/* Check whether Modifier is a simulation or not, this is used for switching to the physics/particles context tab */ static int modifier_is_simulation(ModifierData *md) { /* Physic Tab */ -- cgit v1.2.3 From 9775f1d74301615d7898e70b0e85608d0895b523 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 Nov 2012 06:56:51 +0000 Subject: generate api reference for 'bmesh.ops', restructured text is extracted from bmesh_opdefines.c. see: http://www.blender.org/documentation/blender_python_api_2_64_9/bmesh.ops.html --- doc/python_api/rst_from_bmesh_opdefines.py | 370 +++++++++++++++++++++++++++++ doc/python_api/sphinx_doc_gen.py | 18 +- 2 files changed, 385 insertions(+), 3 deletions(-) create mode 100644 doc/python_api/rst_from_bmesh_opdefines.py diff --git a/doc/python_api/rst_from_bmesh_opdefines.py b/doc/python_api/rst_from_bmesh_opdefines.py new file mode 100644 index 00000000000..5803315ff86 --- /dev/null +++ b/doc/python_api/rst_from_bmesh_opdefines.py @@ -0,0 +1,370 @@ +# ##### 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. +# +# ##### END GPL LICENSE BLOCK ##### + +# + +# This is a quite stupid script which extracts bmesh api docs from +# 'bmesh_opdefines.c' in order to avoid having to add a lot of introspection +# data access into the api. +# +# The script is stupid becase it makes assumptions about formatting... +# that each arg has its own line, that comments above or directly after will be __doc__ etc... +# +# We may want to replace this script with something else one day but for now its good enough. +# if it needs large updates it may be better to rewrite using a real parser or +# add introspection into bmesh.ops. +# - campbell + +import os + +CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) +SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(CURRENT_DIR, "..", "..")))) +FILE_OP_DEFINES_C = os.path.join(SOURCE_DIR, "source", "blender", "bmesh", "intern", "bmesh_opdefines.c") +OUT_RST = os.path.join(CURRENT_DIR, "rst", "bmesh.ops.rst") + +HEADER = r""" +BMesh Operators +=============== + +.. module:: bmesh.ops + +This module gives access to low level bmesh operations. + +Most operators take input and return output, they can be chained together +to perform useful operations. + +.. note:: + + This API us new in 2.65 and not yet well tested. + + +""" + + +def main(): + fsrc = open(FILE_OP_DEFINES_C, 'r', encoding="utf-8") + + blocks = [] + + is_block = False + is_comment = False # /* global comments only */ + + comment_ctx = None + block_ctx = None + + for l in fsrc: + l = l[:-1] + # weak but ok + if ("BMOpDefine" in l and l.split()[1] == "BMOpDefine") and not "bmo_opdefines[]" in l: + is_block = True + block_ctx = [] + blocks.append((comment_ctx, block_ctx)) + elif l.strip().startswith("/*"): + is_comment = True + comment_ctx = [] + + if is_block: + if l.strip().startswith("//"): + pass + else: + # remove c++ comment if we have one + cpp_comment = l.find("//") + if cpp_comment != -1: + l = l[:cpp_comment] + + block_ctx.append(l) + + if l.strip() == "};": + is_block = False + comment_ctx = None + + if is_comment: + c_comment_start = l.find("/*") + if c_comment_start != -1: + l = l[c_comment_start + 2:] + + c_comment_end = l.find("*/") + if c_comment_end != -1: + l = l[:c_comment_end] + + is_comment = False + comment_ctx.append(l) + + fsrc.close() + del fsrc + + + # namespace hack + vars = ( + "BMO_OP_SLOT_ELEMENT_BUF", + "BMO_OP_SLOT_BOOL", + "BMO_OP_SLOT_FLT", + "BMO_OP_SLOT_INT", + "BMO_OP_SLOT_MAT", + "BMO_OP_SLOT_VEC", + "BMO_OP_SLOT_PTR", + "BMO_OP_SLOT_MAPPING", + + "BMO_OP_SLOT_SUBTYPE_MAP_ELEM", + "BMO_OP_SLOT_SUBTYPE_MAP_BOOL", + "BMO_OP_SLOT_SUBTYPE_MAP_INT", + "BMO_OP_SLOT_SUBTYPE_MAP_FLOAT", + "BMO_OP_SLOT_SUBTYPE_MAP_EMPTY", + "BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL", + + "BMO_OP_SLOT_SUBTYPE_PTR_SCENE", + "BMO_OP_SLOT_SUBTYPE_PTR_OBJECT", + "BMO_OP_SLOT_SUBTYPE_PTR_MESH", + "BMO_OP_SLOT_SUBTYPE_PTR_BMESH", + + "BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE", + + "BM_VERT", + "BM_EDGE", + "BM_FACE", + + "BMO_OP_FLAG_UNTAN_MULTIRES", + ) + vars_dict = {} + for i, v in enumerate(vars): + vars_dict[v] = (1 << i) + globals().update(vars_dict) + # reverse lookup + vars_dict_reverse = {v: k for k, v in vars_dict.items()} + # end namespace hack + + blocks_py = [] + for comment, b in blocks: + # magic, translate into python + b[0] = b[0].replace("static BMOpDefine ", "") + + for i, l in enumerate(b): + l = l.strip() + l = l.replace("{", "(") + l = l.replace("}", ")") + + if l.startswith("/*"): + l = l.replace("/*", "'''own <") + else: + l = l.replace("/*", "'''inline <") + l = l.replace("*/", ">''',") + + # exec func. eg: bmo_rotate_edges_exec, + if l.startswith("bmo_") and l.endswith("_exec,"): + l = "None," + b[i] = l + + #for l in b: + # print(l) + + text = "\n".join(b) + global_namespace = { + "__file__": "generated", + "__name__": "__main__", + } + + global_namespace.update(vars_dict) + + text_a, text_b = text.split("=", 1) + text = "result = " + text_b + exec(compile(text, "generated", 'exec'), global_namespace) + # print(global_namespace["result"]) + blocks_py.append((comment, global_namespace["result"])) + + + # --------------------- + # Now convert into rst. + fout = open(OUT_RST, 'w', encoding="utf-8") + fw = fout.write + fw(HEADER) + for comment, b in blocks_py: + args_in = None + args_out = None + for member in b[1:]: + if type(member) == tuple: + if args_in is None: + args_in = member + elif args_out is None: + args_out = member + break + + args_in_index = [] + args_out_index = [] + + if args_in is not None: + args_in_index[:] = [i for (i, a) in enumerate(args_in) if type(a) == tuple] + if args_out is not None: + args_out_index[:] = [i for (i, a) in enumerate(args_out) if type(a) == tuple] + + fw(".. function:: %s(%s)\n\n" % (b[0], ", ".join([args_in[i][0] for i in args_in_index]))) + + # -- wash the comment + comment_washed = [] + for i, l in enumerate(comment): + assert((l.strip() == "") or + (l in {"/*", " *"}) or + (l.startswith(("/* ", " * ")))) + + l = l[3:] + if i == 0 and not l.strip(): + continue + if l.strip(): + l = " " + l + comment_washed.append(l) + + fw("\n".join(comment_washed)) + fw("\n") + # -- done + + + # get the args + def get_args_wash(args, args_index): + args_wash = [] + for i in args_index: + arg = args[i] + if len(arg) == 3: + name, tp, tp_sub = arg + elif len(arg) == 2: + name, tp = arg + tp_sub = None + else: + print(arg) + assert(0) + + tp_str = "" + + comment_prev = "" + comment_next = "" + if i != 0: + comment_prev = args[i + 1] + if type(comment_prev) == str and comment_prev.startswith("our <"): + comment_prev = comment_next[5:-1] # strip inline <...> + else: + comment_prev = "" + + if i + 1 < len(args): + comment_next = args[i + 1] + if type(comment_next) == str and comment_next.startswith("inline <"): + comment_next = comment_next[8:-1] # strip inline <...> + else: + comment_next = "" + + comment = "" + if comment_prev: + comment += comment_prev.strip() + if comment_next: + comment += ("\n" if comment_prev else "") + comment_next.strip() + + if tp == BMO_OP_SLOT_FLT: + tp_str = "float" + elif tp == BMO_OP_SLOT_INT: + tp_str = "int" + elif tp == BMO_OP_SLOT_BOOL: + tp_str = "bool" + elif tp == BMO_OP_SLOT_MAT: + tp_str = "matrix" + elif tp == BMO_OP_SLOT_VEC: + tp_str = "matrix" + elif tp == BMO_OP_SLOT_PTR: + tp_str = "dict" + assert(tp_sub is not None) + if tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_BMESH: + tp_str = "BMesh" + elif tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_SCENE: + tp_str = "Scene" + elif tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_OBJECT: + tp_str = "Object" + elif tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_MESH: + tp_str = "Mesh" + else: + print("Cant find", vars_dict_reverse[tp_sub]) + assert(0) + + elif tp == BMO_OP_SLOT_ELEMENT_BUF: + assert(tp_sub is not None) + + ls = [] + if tp_sub & BM_VERT: ls.append("vert") + if tp_sub & BM_EDGE: ls.append("edge") + if tp_sub & BM_FACE: ls.append("face") + assert(ls) # must be at least one + + if tp_sub & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE: + tp_str = "/".join(ls) + else: + tp_str = ("list of (%s)" % ", ".join(ls)) + + del ls + elif tp == BMO_OP_SLOT_MAPPING: + if tp_sub & BMO_OP_SLOT_SUBTYPE_MAP_EMPTY: + tp_str = "set of vert/edge/face type" + else: + tp_str = "dict mapping vert/edge/face types to " + if tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_BOOL: + tp_str += "bool" + elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_INT: + tp_str += "int" + elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_FLOAT: + tp_str += "float" + elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_ELEM: + tp_str += "vert/edge/face elements" + elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL: + tp_str += "unknown internal data, not compatible with python" + else: + print("Cant find", vars_dict_reverse[tp_sub]) + assert(0) + else: + print("Cant find", vars_dict_reverse[tp]) + assert(0) + + args_wash.append((name, tp_str, comment)) + return args_wash + # end get_args_wash + + + args_in_wash = get_args_wash(args_in, args_in_index) + args_out_wash = get_args_wash(args_out, args_out_index) + + for (name, tp, comment) in args_in_wash: + if comment == "": + comment = "Undocumented." + + fw(" :arg %s: %s\n" % (name, comment)) + fw(" :type %s: %s\n" % (name, tp)) + + if args_out_wash: + fw(" :return:\n\n") + + for (name, tp, comment) in args_out_wash: + assert(name.endswith(".out")) + name = name[:-4] + fw(" - ``%s``: %s\n\n" % (name, comment)) + fw(" **type** %s\n" % tp) + + fw("\n") + fw(" :rtype: dict with string keys\n") + + fw("\n\n") + + fout.close() + del fout + print(OUT_RST) + + +if __name__ == "__main__": + main() diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py index 410612fabd5..1814261fc71 100644 --- a/doc/python_api/sphinx_doc_gen.py +++ b/doc/python_api/sphinx_doc_gen.py @@ -35,7 +35,7 @@ API dump in RST files ./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- --output ../python_api For quick builds: - ./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- --partial + ./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- --partial bmesh.* Sphinx: HTML generation @@ -245,6 +245,7 @@ else: "bgl", "blf", "bmesh", + "bmesh.ops", "bmesh.types", "bmesh.utils", "bpy.app", @@ -297,7 +298,7 @@ try: __import__("aud") except ImportError: BPY_LOGGER.debug("Warning: Built without 'aud' module, docs incomplete...") - EXCLUDE_MODULES = EXCLUDE_MODULES + ("aud", ) + EXCLUDE_MODULES = list(EXCLUDE_MODULES) + ["aud"] # examples EXAMPLES_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "examples")) @@ -1472,6 +1473,11 @@ def write_sphinx_conf_py(basepath): file.close() +def execfile(filepath): + global_namespace = {"__file__": filepath, "__name__": "__main__"} + exec(compile(open(filepath).read(), filepath, 'exec'), global_namespace) + + def write_rst_contents(basepath): ''' Write the rst file of the main page, needed for sphinx (index.html) @@ -1533,13 +1539,17 @@ def write_rst_contents(basepath): # misc "bgl", "blf", "gpu", "aud", "bpy_extras", # bmesh - "bmesh", "bmesh.types", "bmesh.utils", + "bmesh", "bmesh.types", "bmesh.utils", "bmesh.ops", ) for mod in standalone_modules: if mod not in EXCLUDE_MODULES: fw(" %s\n\n" % mod) + # special case, this 'bmesh.ops.rst' is extracted from C source + if "bmesh.ops" not in EXCLUDE_MODULES: + execfile(os.path.join(SCRIPT_DIR, "rst_from_bmesh_opdefines.py")) + # game engine if "bge" not in EXCLUDE_MODULES: fw(title_string("Game Engine Modules", "=", double=True)) @@ -1701,6 +1711,8 @@ def copy_handwritten_rsts(basepath): "bgl", # "Blender OpenGl wrapper" "gpu", # "GPU Shader Module" + "bmesh.ops", # generated by rst_from_bmesh_opdefines.py + # includes... "include__bmesh", ] -- cgit v1.2.3 From 0cd26e6066a071ecd230aa9b865b9223ea4ba13a Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 27 Nov 2012 08:19:34 +0000 Subject: Fix crash opening .blend file with missing lib linked scene and no local scene. --- source/blender/blenkernel/intern/blender.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 40cd5b3d403..03698736459 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -268,7 +268,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath G.winpos = bfd->winpos; G.displaymode = bfd->displaymode; G.fileflags = bfd->fileflags; - CTX_wm_manager_set(C, bfd->main->wm.first); + CTX_wm_manager_set(C, G.main->wm.first); CTX_wm_screen_set(C, bfd->curscreen); CTX_data_scene_set(C, bfd->curscreen->scene); CTX_wm_area_set(C, NULL); @@ -278,7 +278,11 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath /* this can happen when active scene was lib-linked, and doesn't exist anymore */ if (CTX_data_scene(C) == NULL) { - CTX_data_scene_set(C, bfd->main->scene.first); + /* in case we don't even have a local scene, add one */ + if(!G.main->scene.first) + BKE_scene_add("Scene"); + + CTX_data_scene_set(C, G.main->scene.first); CTX_wm_screen(C)->scene = CTX_data_scene(C); curscene = CTX_data_scene(C); } -- cgit v1.2.3 From a9855c227e6bfc955a6b2f15e8ee656218c3f916 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 Nov 2012 09:21:57 +0000 Subject: py/bmesh api - add support for single item buffers (odd feature but used quite a bit with bmesh operators). also add utility functions BMO_slot_buffer_from_single(), BMO_slot_buffer_get_single() --- source/blender/bmesh/intern/bmesh_opdefines.c | 2 +- source/blender/bmesh/intern/bmesh_operator_api.h | 4 + source/blender/bmesh/intern/bmesh_operators.c | 28 +++- source/blender/bmesh/operators/bmo_removedoubles.c | 2 +- source/blender/bmesh/operators/bmo_slide.c | 17 +-- source/blender/bmesh/operators/bmo_utils.c | 12 +- source/blender/editors/mesh/editmesh_slide.c | 6 +- source/blender/python/bmesh/bmesh_py_ops.c | 169 ++++++++++++--------- 8 files changed, 142 insertions(+), 98 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 75f187e3837..2a7757dbfa1 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -1546,7 +1546,7 @@ static BMOpDefine bmo_slide_vert_def = { "slide_vert", /* slots_in */ {{"vert", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, - {"edge", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, + {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, {"distance_t", BMO_OP_SLOT_FLT}, {{'\0'}}, }, diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h index 1bb83a12e48..bebd3215d93 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api.h +++ b/source/blender/bmesh/intern/bmesh_operator_api.h @@ -417,6 +417,10 @@ void BMO_slot_buffer_from_disabled_hflag(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char htype, const char hflag); +void BMO_slot_buffer_from_single(BMOperator *op, BMOpSlot *slot, BMHeader *ele); +void *BMO_slot_buffer_get_single(BMOpSlot *slot); + + /* counts number of elements inside a slot array. */ int BMO_slot_buffer_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name); int BMO_slot_map_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name); diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 20fffe71636..54866c756cb 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -867,6 +867,29 @@ void BMO_slot_buffer_from_disabled_hflag(BMesh *bm, BMOperator *op, bmo_slot_buffer_from_hflag(bm, op, slot_args, slot_name, htype, hflag, FALSE); } +void BMO_slot_buffer_from_single(BMOperator *op, BMOpSlot *slot, BMHeader *ele) +{ + BMO_ASSERT_SLOT_IN_OP(slot, op); + BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF); + BLI_assert(slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE); + BLI_assert(slot->len == 0 || slot->len == 1); + + BLI_assert(slot->slot_subtype.elem & ele->htype); + + slot->data.buf = BLI_memarena_alloc(op->arena, sizeof(void *) * 4); /* XXX, why 'x4' ? */ + slot->len = 1; + *slot->data.buf = ele; +} + +void *BMO_slot_buffer_get_single(BMOpSlot *slot) +{ + BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF); + BLI_assert(slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE); + BLI_assert(slot->len == 0 || slot->len == 1); + + return slot->len ? (BMHeader *)slot->data.buf[0] : NULL; +} + /** * Copies the values from another slot to the end of the output slot. */ @@ -1580,12 +1603,11 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v } case 'e': { + /* XXX we have 'e' but no equivalent for verts/faces - why? we could use (V/E/P)*/ BMHeader *ele = va_arg(vlist, void *); BMOpSlot *slot = BMO_slot_get(op->slots_in, slot_name); - slot->data.buf = BLI_memarena_alloc(op->arena, sizeof(void *) * 4); - slot->len = 1; - *slot->data.buf = ele; + BMO_slot_buffer_from_single(op, slot, ele); state = 1; break; diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c index 06d11c7b19d..7fb78d2d160 100644 --- a/source/blender/bmesh/operators/bmo_removedoubles.c +++ b/source/blender/bmesh/operators/bmo_removedoubles.c @@ -263,7 +263,7 @@ void bmo_pointmerge_facedata_exec(BMesh *bm, BMOperator *op) float fac; int i, tot; - snapv = BMO_iter_new(&siter, op->slots_in, "snapv", BM_VERT); + snapv = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "snapv")); tot = BM_vert_face_count(snapv); if (!tot) diff --git a/source/blender/bmesh/operators/bmo_slide.c b/source/blender/bmesh/operators/bmo_slide.c index 9dde2461364..040c2d41e9c 100644 --- a/source/blender/bmesh/operators/bmo_slide.c +++ b/source/blender/bmesh/operators/bmo_slide.c @@ -56,8 +56,7 @@ void bmo_slide_vert_exec(BMesh *bm, BMOperator *op) const float distance_t = BMO_slot_float_get(op->slots_in, "distance_t"); /* Get start vertex */ - vertex = BMO_iter_new(&oiter, op->slots_in, "vert", BM_VERT); - + vertex = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "vert")); if (!vertex) { if (G.debug & G_DEBUG) { @@ -67,15 +66,13 @@ void bmo_slide_vert_exec(BMesh *bm, BMOperator *op) return; } + /* BMESH_TODO - this is odd, it only uses one edge, why take a list at all? */ /* Count selected edges */ - BMO_ITER (h, &oiter, op->slots_in, "edge", BM_VERT | BM_EDGE) { - switch (h->htype) { - case BM_EDGE: - selected_edges++; - /* Mark all selected edges (cast BMHeader->BMEdge) */ - BMO_elem_flag_enable(bm, (BMElemF *)h, EDGE_MARK); - break; - } + BMO_ITER (h, &oiter, op->slots_in, "edges", BM_EDGE) { + selected_edges++; + /* Mark all selected edges (cast BMHeader->BMEdge) */ + BMO_elem_flag_enable(bm, (BMElemF *)h, EDGE_MARK); + break; } /* Only allow sliding if an edge is selected */ diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index 203acff8332..c7ab8f62f40 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -701,9 +701,8 @@ typedef struct ElemNode { void bmo_shortest_path_exec(BMesh *bm, BMOperator *op) { - BMOIter vs_iter /* , vs2_iter */; /* selected verts iterator */ BMIter v_iter; /* mesh verts iterator */ - BMVert *vs, *sv, *ev; /* starting vertex, ending vertex */ + BMVert *sv, *ev; /* starting vertex, ending vertex */ BMVert *v; /* mesh vertex */ Heap *h = NULL; @@ -712,13 +711,8 @@ void bmo_shortest_path_exec(BMesh *bm, BMOperator *op) int num_total = 0 /*, num_sels = 0 */, i = 0; const int type = BMO_slot_int_get(op->slots_in, "type"); - /* BMESH_TODO use BMO_slot_buffer_elem_first here? */ - BMO_ITER (vs, &vs_iter, op->slots_in, "startv", BM_VERT) { - sv = vs; - } - BMO_ITER (vs, &vs_iter, op->slots_in, "endv", BM_VERT) { - ev = vs; - } + sv = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "startv")); + ev = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "endv")); num_total = BM_mesh_elem_count(bm, BM_VERT); diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c index 3f865678a89..06ae91a6bcb 100644 --- a/source/blender/editors/mesh/editmesh_slide.c +++ b/source/blender/editors/mesh/editmesh_slide.c @@ -729,7 +729,7 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u /* Prepare operator */ if (!EDBM_op_init(em, &bmop, op, - "slide_vert vert=%e edge=%hev distance_t=%f", + "slide_vert vert=%e edges=%he distance_t=%f", start_vert, BM_ELEM_SELECT, distance_t)) { return OPERATOR_CANCELLED; @@ -738,10 +738,10 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u BMO_op_exec(bm, &bmop); /* Deselect the input edges */ - BMO_slot_buffer_hflag_disable(bm, bmop.slots_in, "edge", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE); + BMO_slot_buffer_hflag_disable(bm, bmop.slots_in, "edges", BM_EDGE, BM_ELEM_SELECT, TRUE); /* Select the output vert */ - BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "verts.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE); + BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "verts.out", BM_VERT, BM_ELEM_SELECT, TRUE); /* Flush the select buffers */ EDBM_selectmode_flush(em); diff --git a/source/blender/python/bmesh/bmesh_py_ops.c b/source/blender/python/bmesh/bmesh_py_ops.c index 09dda7261a8..f2d91f67a12 100644 --- a/source/blender/python/bmesh/bmesh_py_ops.c +++ b/source/blender/python/bmesh/bmesh_py_ops.c @@ -224,15 +224,36 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject * } case BMO_OP_SLOT_ELEMENT_BUF: { - /* there are many ways we could interpret arguments, for now... - * - verts/edges/faces from the mesh direct, - * this way the operator takes every item. - * - `TODO` a plain python sequence (list) of elements. - * - `TODO` an iterator. eg. - * face.verts - * - `TODO` (type, flag) pair, eg. - * ('VERT', {'TAG'}) - */ + if (slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) { + if (!BPy_BMElem_Check(value) || + !(((BPy_BMElem *)value)->ele->head.htype & slot->slot_subtype.elem)) + { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected a %.200s not *.200s", + self->opname, slot_name, + BPy_BMElem_StringFromHType(slot->slot_subtype.elem & BM_ALL_NOLOOP), + Py_TYPE(value)->tp_name); + return NULL; + } + else if (((BPy_BMElem *)value)->bm == NULL) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" invalidated element", + self->opname, slot_name); + return NULL; + } + + BMO_slot_buffer_from_single(&bmop, slot, &((BPy_BMElem *)value)->ele->head); + } + else { + /* there are many ways we could interpret arguments, for now... + * - verts/edges/faces from the mesh direct, + * this way the operator takes every item. + * - `TODO` a plain python sequence (list) of elements. + * - `TODO` an iterator. eg. + * face.verts + * - `TODO` (type, flag) pair, eg. + * ('VERT', {'TAG'}) + */ #define BPY_BM_GENERIC_MESH_TEST(type_string) \ if (((BPy_BMGeneric *)value)->bm != bm) { \ @@ -248,76 +269,76 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject * "%.200s: keyword \"%.200s\" expected " \ "a list of %.200s not " type_string, \ self->opname, slot_name, \ - BPy_BMElem_StringFromHType(slot->slot_subtype.elem & BM_ALL)); \ + BPy_BMElem_StringFromHType(slot->slot_subtype.elem & BM_ALL_NOLOOP)); \ return NULL; \ } (void)0 - if (BPy_BMVertSeq_Check(value)) { - BPY_BM_GENERIC_MESH_TEST("verts"); - BPY_BM_ELEM_TYPE_TEST("verts"); + if (BPy_BMVertSeq_Check(value)) { + BPY_BM_GENERIC_MESH_TEST("verts"); + BPY_BM_ELEM_TYPE_TEST("verts"); - BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_VERT); - } - else if (BPy_BMEdgeSeq_Check(value)) { - BPY_BM_GENERIC_MESH_TEST("edges"); - BPY_BM_ELEM_TYPE_TEST("edges"); - BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_EDGE); - } - else if (BPy_BMFaceSeq_Check(value)) { - BPY_BM_GENERIC_MESH_TEST("faces"); - BPY_BM_ELEM_TYPE_TEST("faces"); - BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_FACE); - } + BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_VERT); + } + else if (BPy_BMEdgeSeq_Check(value)) { + BPY_BM_GENERIC_MESH_TEST("edges"); + BPY_BM_ELEM_TYPE_TEST("edges"); + BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_EDGE); + } + else if (BPy_BMFaceSeq_Check(value)) { + BPY_BM_GENERIC_MESH_TEST("faces"); + BPY_BM_ELEM_TYPE_TEST("faces"); + BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_FACE); + } #undef BPY_BM_ELEM_TYPE_TEST - else if (BPy_BMElemSeq_Check(value)) { - BMIter iter; - BMHeader *ele; - int tot; - unsigned int i; + else if (BPy_BMElemSeq_Check(value)) { + BMIter iter; + BMHeader *ele; + int tot; + unsigned int i; - BPY_BM_GENERIC_MESH_TEST("elements"); + BPY_BM_GENERIC_MESH_TEST("elements"); - /* this will loop over all elements which is a shame but - * we need to know this before alloc */ - /* calls bpy_bmelemseq_length() */ - tot = Py_TYPE(value)->tp_as_sequence->sq_length((PyObject *)self); + /* this will loop over all elements which is a shame but + * we need to know this before alloc */ + /* calls bpy_bmelemseq_length() */ + tot = Py_TYPE(value)->tp_as_sequence->sq_length((PyObject *)self); - BMO_slot_buffer_alloc(&bmop, bmop.slots_in, slot_name, tot); + BMO_slot_buffer_alloc(&bmop, bmop.slots_in, slot_name, tot); - i = 0; - BM_ITER_BPY_BM_SEQ (ele, &iter, ((BPy_BMElemSeq *)value)) { - slot->data.buf[i] = ele; - i++; + i = 0; + BM_ITER_BPY_BM_SEQ (ele, &iter, ((BPy_BMElemSeq *)value)) { + slot->data.buf[i] = ele; + i++; + } } - } - /* keep this last */ - else if (PySequence_Check(value)) { - BMElem **elem_array = NULL; - Py_ssize_t elem_array_len; - - elem_array = BPy_BMElem_PySeq_As_Array(&bm, value, 0, PY_SSIZE_T_MAX, - &elem_array_len, (slot->slot_subtype.elem & BM_ALL_NOLOOP), - TRUE, TRUE, slot_name); + /* keep this last */ + else if (PySequence_Check(value)) { + BMElem **elem_array = NULL; + Py_ssize_t elem_array_len; + + elem_array = BPy_BMElem_PySeq_As_Array(&bm, value, 0, PY_SSIZE_T_MAX, + &elem_array_len, (slot->slot_subtype.elem & BM_ALL_NOLOOP), + TRUE, TRUE, slot_name); + + /* error is set above */ + if (elem_array == NULL) { + return NULL; + } - /* error is set above */ - if (elem_array == NULL) { + BMO_slot_buffer_alloc(&bmop, bmop.slots_in, slot_name, elem_array_len); + memcpy(slot->data.buf, elem_array, sizeof(void *) * elem_array_len); + PyMem_FREE(elem_array); + } + else { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a bmesh sequence, list, (htype, flag) pair, not %.200s", + self->opname, slot_name, Py_TYPE(value)->tp_name); return NULL; } - - BMO_slot_buffer_alloc(&bmop, bmop.slots_in, slot_name, elem_array_len); - memcpy(slot->data.buf, elem_array, sizeof(void *) * elem_array_len); - PyMem_FREE(elem_array); } - else { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected " - "a bmesh sequence, list, (htype, flag) pair, not %.200s", - self->opname, slot_name, Py_TYPE(value)->tp_name); - return NULL; - } - #undef BPY_BM_GENERIC_MESH_TEST break; @@ -548,14 +569,20 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject * break; case BMO_OP_SLOT_ELEMENT_BUF: { - const int size = slot->len; - void **buffer = BMO_SLOT_AS_BUFFER(slot); - int j; - - item = PyList_New(size); - for (j = 0; j < size; j++) { - BMHeader *ele = buffer[i]; - PyList_SET_ITEM(item, j, ele ? BPy_BMElem_CreatePyObject(bm, ele) : (Py_INCREF(Py_None), Py_None)); + if (slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) { + BMHeader *ele = BMO_slot_buffer_get_single(slot); + item = ele ? BPy_BMElem_CreatePyObject(bm, ele) : (Py_INCREF(Py_None), Py_None); + } + else { + const int size = slot->len; + void **buffer = BMO_SLOT_AS_BUFFER(slot); + int j; + + item = PyList_New(size); + for (j = 0; j < size; j++) { + BMHeader *ele = buffer[i]; + PyList_SET_ITEM(item, j, BPy_BMElem_CreatePyObject(bm, ele)); + } } break; } -- cgit v1.2.3 From c00a1b7493822abc62723e16082a908b221c6514 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 Nov 2012 09:41:08 +0000 Subject: use clearer names for 'single' bmesh operator args & add '%e' to BMO_op_vinitf comments. --- source/blender/bmesh/intern/bmesh_opdefines.c | 8 ++++---- source/blender/bmesh/intern/bmesh_operators.c | 4 ++-- source/blender/bmesh/operators/bmo_removedoubles.c | 18 +++++++++--------- source/blender/bmesh/operators/bmo_slide.c | 4 ++-- source/blender/bmesh/operators/bmo_utils.c | 4 ++-- source/blender/editors/mesh/editmesh_slide.c | 14 +++++++------- source/blender/editors/mesh/editmesh_tools.c | 6 ++++-- 7 files changed, 30 insertions(+), 28 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 2a7757dbfa1..8e2a2b22508 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -356,7 +356,7 @@ static BMOpDefine bmo_pointmerge_facedata_def = { "pointmerge_facedata", /* slots_in */ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ - {"snapv", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, /* snap vertex */ + {"vert_snap", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, /* snap vertex */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -1209,8 +1209,8 @@ static BMOpDefine bmo_reverse_colors_def = { static BMOpDefine bmo_shortest_path_def = { "shortest_path", /* slots_in */ - {{"startv", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, /* start vertex */ - {"endv", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, /* end vertex */ + {{"vert_start", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, /* start vertex */ + {"vert_end", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, /* end vertex */ {"type", BMO_OP_SLOT_INT}, /* type of selection */ {{'\0'}}, }, @@ -1547,7 +1547,7 @@ static BMOpDefine bmo_slide_vert_def = { /* slots_in */ {{"vert", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, - {"distance_t", BMO_OP_SLOT_FLT}, + {"factor", BMO_OP_SLOT_FLT}, {{'\0'}}, }, /* slots_out */ diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 54866c756cb..7c9b02b4952 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -1490,6 +1490,7 @@ static int bmo_opname_to_opcode(const char *opname) * f - float * s - slot_in * S - slot_out + * e - single vert/edge/face * hv - header flagged verts (hflag) * he - header flagged edges (hflag) * hf - header flagged faces (hflag) @@ -1601,9 +1602,8 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v state = 1; break; } - case 'e': + case 'e': /* single vert/edge/face */ { - /* XXX we have 'e' but no equivalent for verts/faces - why? we could use (V/E/P)*/ BMHeader *ele = va_arg(vlist, void *); BMOpSlot *slot = BMO_slot_get(op->slots_in, slot_name); diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c index 7fb78d2d160..d27a90f0366 100644 --- a/source/blender/bmesh/operators/bmo_removedoubles.c +++ b/source/blender/bmesh/operators/bmo_removedoubles.c @@ -258,19 +258,19 @@ void bmo_pointmerge_facedata_exec(BMesh *bm, BMOperator *op) { BMOIter siter; BMIter iter; - BMVert *v, *snapv; + BMVert *v, *vert_snap; BMLoop *l, *firstl = NULL; float fac; int i, tot; - snapv = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "snapv")); - tot = BM_vert_face_count(snapv); + vert_snap = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "vert_snap")); + tot = BM_vert_face_count(vert_snap); if (!tot) return; fac = 1.0f / tot; - BM_ITER_ELEM (l, &iter, snapv, BM_LOOPS_OF_VERT) { + BM_ITER_ELEM (l, &iter, vert_snap, BM_LOOPS_OF_VERT) { if (!firstl) { firstl = l; } @@ -343,7 +343,7 @@ void bmo_pointmerge_exec(BMesh *bm, BMOperator *op) { BMOperator weldop; BMOIter siter; - BMVert *v, *snapv = NULL; + BMVert *v, *vert_snap = NULL; float vec[3]; BMOpSlot *slot_targetmap; @@ -355,12 +355,12 @@ void bmo_pointmerge_exec(BMesh *bm, BMOperator *op) slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap"); BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) { - if (!snapv) { - snapv = v; - copy_v3_v3(snapv->co, vec); + if (!vert_snap) { + vert_snap = v; + copy_v3_v3(vert_snap->co, vec); } else { - BMO_slot_map_elem_insert(&weldop, slot_targetmap, v, snapv); + BMO_slot_map_elem_insert(&weldop, slot_targetmap, v, vert_snap); } } diff --git a/source/blender/bmesh/operators/bmo_slide.c b/source/blender/bmesh/operators/bmo_slide.c index 040c2d41e9c..ea9f9bf9eba 100644 --- a/source/blender/bmesh/operators/bmo_slide.c +++ b/source/blender/bmesh/operators/bmo_slide.c @@ -53,7 +53,7 @@ void bmo_slide_vert_exec(BMesh *bm, BMOperator *op) int selected_edges = 0; /* Get slide amount */ - const float distance_t = BMO_slot_float_get(op->slots_in, "distance_t"); + const float factor = BMO_slot_float_get(op->slots_in, "factor"); /* Get start vertex */ vertex = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "vert")); @@ -101,7 +101,7 @@ void bmo_slide_vert_exec(BMesh *bm, BMOperator *op) BMO_elem_flag_enable(bm, vertex, VERT_MARK); /* Interpolate */ - interp_v3_v3v3(vertex->co, vertex->co, other->co, distance_t); + interp_v3_v3v3(vertex->co, vertex->co, other->co, factor); } /* Return the new edge. The same previously marked with VERT_MARK */ diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index c7ab8f62f40..dde3c526c13 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -711,8 +711,8 @@ void bmo_shortest_path_exec(BMesh *bm, BMOperator *op) int num_total = 0 /*, num_sels = 0 */, i = 0; const int type = BMO_slot_int_get(op->slots_in, "type"); - sv = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "startv")); - ev = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "endv")); + sv = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "vert_start")); + ev = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "vert_end")); num_total = BM_mesh_elem_count(bm, BM_VERT); diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c index 06ae91a6bcb..4fbe9c2534f 100644 --- a/source/blender/editors/mesh/editmesh_slide.c +++ b/source/blender/editors/mesh/editmesh_slide.c @@ -695,7 +695,7 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u BMOperator bmop; BMEditSelection *ese = (BMEditSelection *)em->bm->selected.last; - float distance_t = 0.0f; + float factor = 0.0f; /* Invoked modally? */ if (op->type->modal == edbm_vertex_slide_modal && op->customdata) { @@ -711,12 +711,12 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u BM_select_history_store(em->bm, vso->start_vtx); ese = (BMEditSelection *)em->bm->selected.last; } - distance_t = vso->distance; - RNA_float_set(op->ptr, "distance_t", distance_t); + factor = vso->distance; + RNA_float_set(op->ptr, "factor", factor); } else { /* Get Properties */ - distance_t = RNA_float_get(op->ptr, "distance_t"); + factor = RNA_float_get(op->ptr, "factor"); } /* Is there a starting vertex ? */ @@ -729,8 +729,8 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u /* Prepare operator */ if (!EDBM_op_init(em, &bmop, op, - "slide_vert vert=%e edges=%he distance_t=%f", - start_vert, BM_ELEM_SELECT, distance_t)) + "slide_vert vert=%e edges=%he factor=%f", + start_vert, BM_ELEM_SELECT, factor)) { return OPERATOR_CANCELLED; } @@ -787,7 +787,7 @@ void MESH_OT_vert_slide(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* Properties for vertex slide */ - prop = RNA_def_float(ot->srna, "distance_t", 0.0f, -FLT_MAX, FLT_MAX, "Distance", "Distance", -5.0f, 5.0f); + prop = RNA_def_float(ot->srna, "factor", 0.0f, -FLT_MAX, FLT_MAX, "Distance", "Distance", -5.0f, 5.0f); RNA_def_property_ui_range(prop, -5.0f, 5.0f, 0.1, 4); RNA_def_property_flag(prop, PROP_SKIP_SAVE); } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index f28bb753122..566372155ba 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -2018,7 +2018,7 @@ static int merge_firstlast(BMEditMesh *em, int first, int uvmerge, wmOperator *w return OPERATOR_CANCELLED; if (uvmerge) { - if (!EDBM_op_callf(em, wmop, "pointmerge_facedata verts=%hv snapv=%e", BM_ELEM_SELECT, mergevert)) + if (!EDBM_op_callf(em, wmop, "pointmerge_facedata verts=%hv vert_snap=%e", BM_ELEM_SELECT, mergevert)) return OPERATOR_CANCELLED; } @@ -2308,7 +2308,9 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op) } /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */ - EDBM_op_init(em, &bmop, op, "shortest_path startv=%e endv=%e type=%i", svert, evert, type); + EDBM_op_init(em, &bmop, op, + "shortest_path vert_start=%e vert_end=%e type=%i", + svert, evert, type); /* execute the operator */ BMO_op_exec(em->bm, &bmop); -- cgit v1.2.3 From 7c36100930ad3461b1f41667b14ccee01d37d302 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 Nov 2012 09:47:22 +0000 Subject: new bevel was still referring to old property name (holding shift wasnt working while beveling). --- source/blender/editors/mesh/editmesh_tools.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 566372155ba..b3093e0be12 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -4949,8 +4949,13 @@ static float edbm_bevel_mval_factor(wmOperator *op, wmEvent *event) /* Fake shift-transform... */ if (event->shift) { - if (opdata->shift_factor < 0.0f) + if (opdata->shift_factor < 0.0f) { +#ifdef NEW_BEVEL + opdata->shift_factor = RNA_float_get(op->ptr, "factor"); +#else opdata->shift_factor = RNA_float_get(op->ptr, "percent"); +#endif + } factor = (factor - opdata->shift_factor) * 0.1f + opdata->shift_factor; } else if (opdata->shift_factor >= 0.0f) -- cgit v1.2.3 From a7555a81c7a120477fe1b771e336cf8e38bb415d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 Nov 2012 09:52:20 +0000 Subject: remove unmaintained eltopo, keeping scons/cmake entries, but commenting out user visible config to make branch merging less of a hassle. --- CMakeLists.txt | 4 ++-- build_files/scons/tools/Blender.py | 6 +++++- build_files/scons/tools/btools.py | 6 +++--- extern/CMakeLists.txt | 7 ++++--- extern/SConscript | 3 +++ source/blender/blenkernel/SConscript | 3 ++- 6 files changed, 19 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cb42f081b2a..01bcc131e19 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -190,8 +190,8 @@ option(WITH_MOD_FLUID "Enable Elbeem Modifier (Fluid Simulation)" ON) option(WITH_MOD_SMOKE "Enable Smoke Modifier (Smoke Simulation)" ON) option(WITH_MOD_BOOLEAN "Enable Boolean Modifier" ON) option(WITH_MOD_REMESH "Enable Remesh Modifier" ON) -option(WITH_MOD_CLOTH_ELTOPO "Enable Experimental cloth solver" OFF) -mark_as_advanced(WITH_MOD_CLOTH_ELTOPO) +# option(WITH_MOD_CLOTH_ELTOPO "Enable Experimental cloth solver" OFF) # this is now only available in a branch +# mark_as_advanced(WITH_MOD_CLOTH_ELTOPO) option(WITH_MOD_OCEANSIM "Enable Ocean Modifier" OFF) # Image format support diff --git a/build_files/scons/tools/Blender.py b/build_files/scons/tools/Blender.py index 7aa2a293ae6..6805b5b0a96 100644 --- a/build_files/scons/tools/Blender.py +++ b/build_files/scons/tools/Blender.py @@ -166,10 +166,12 @@ def setup_staticlibs(lenv): libincs += Split(lenv['BF_FFTW3_LIBPATH']) if lenv['WITH_BF_STATICFFTW3']: statlibs += Split(lenv['BF_FFTW3_LIB_STATIC']) + ''' if lenv['WITH_BF_ELTOPO']: libincs += Split(lenv['BF_LAPACK_LIBPATH']) if lenv['WITH_BF_STATICLAPACK']: - statlibs += Split(lenv['BF_LAPACK_LIB_STATIC']) + statlibs += Split(lenv['BF_LAPACK_LIB_STATIC']) + ''' if lenv['WITH_BF_FFMPEG'] and lenv['WITH_BF_STATICFFMPEG']: statlibs += Split(lenv['BF_FFMPEG_LIB_STATIC']) if lenv['WITH_BF_INTERNATIONAL']: @@ -293,8 +295,10 @@ def setup_syslibs(lenv): syslibs += Split(lenv['BF_SNDFILE_LIB']) if lenv['WITH_BF_FFTW3'] and not lenv['WITH_BF_STATICFFTW3']: syslibs += Split(lenv['BF_FFTW3_LIB']) + ''' if lenv['WITH_BF_ELTOPO']: syslibs += Split(lenv['BF_LAPACK_LIB']) + ''' if lenv['WITH_BF_SDL']: syslibs += Split(lenv['BF_SDL_LIB']) if not lenv['WITH_BF_STATICOPENGL']: diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py index ab963d4543c..19f4ac9a1de 100644 --- a/build_files/scons/tools/btools.py +++ b/build_files/scons/tools/btools.py @@ -119,7 +119,8 @@ def validate_arguments(args, bc): 'WITH_BF_ICONV', 'BF_ICONV', 'BF_ICONV_INC', 'BF_ICONV_LIB', 'BF_ICONV_LIBPATH', 'WITH_BF_GAMEENGINE', 'WITH_BF_BULLET', 'BF_BULLET', 'BF_BULLET_INC', 'BF_BULLET_LIB', - 'WITH_BF_ELTOPO', 'BF_LAPACK', 'BF_LAPACK_LIB', 'BF_LAPACK_LIBPATH', 'BF_LAPACK_LIB_STATIC', + # 'WITH_BF_ELTOPO', # now only available in a branch + 'BF_LAPACK', 'BF_LAPACK_LIB', 'BF_LAPACK_LIBPATH', 'BF_LAPACK_LIB_STATIC', 'BF_WINTAB', 'BF_WINTAB_INC', 'BF_FREETYPE', 'BF_FREETYPE_INC', 'BF_FREETYPE_LIB', 'BF_FREETYPE_LIBPATH', 'BF_FREETYPE_LIB_STATIC', 'WITH_BF_FREETYPE_STATIC', 'WITH_BF_QUICKTIME', 'BF_QUICKTIME', 'BF_QUICKTIME_INC', 'BF_QUICKTIME_LIB', 'BF_QUICKTIME_LIBPATH', @@ -393,8 +394,7 @@ def read_opts(env, cfg, args): (BoolVariable('WITH_BF_GAMEENGINE', 'Build with gameengine' , False)), (BoolVariable('WITH_BF_BULLET', 'Use Bullet if true', True)), - - (BoolVariable('WITH_BF_ELTOPO', 'Use Eltopo collision library if true', False)), + # (BoolVariable('WITH_BF_ELTOPO', 'Use Eltopo collision library if true', False)), # this is now only available in a branch ('BF_LAPACK', 'LAPACK base path', ''), ('BF_LAPACK_LIB', 'LAPACK library', ''), ('BF_LAPACK_LIB_STATIC', 'LAPACK library', ''), diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index 151df493062..2640c528c94 100644 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -32,9 +32,10 @@ if(WITH_BULLET) add_subdirectory(bullet2) endif() -if(WITH_MOD_CLOTH_ELTOPO) - add_subdirectory(eltopo) -endif() +# now only available in a branch +#if(WITH_MOD_CLOTH_ELTOPO) +# add_subdirectory(eltopo) +#endif() if(WITH_BINRELOC) add_subdirectory(binreloc) diff --git a/extern/SConscript b/extern/SConscript index ce366deb38a..71998ee072c 100644 --- a/extern/SConscript +++ b/extern/SConscript @@ -8,8 +8,11 @@ SConscript(['colamd/SConscript']) if env['WITH_BF_GAMEENGINE']: SConscript(['recastnavigation/SConscript']) +# now only available in a branch +''' if env['WITH_BF_ELTOPO']: SConscript(['eltopo/SConscript']) +''' if env['WITH_BF_BULLET']: SConscript(['bullet2/src/SConscript']) diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index db06f4104a4..22be2f78ea7 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -41,11 +41,12 @@ if env['WITH_BF_PYTHON']: if env['BF_DEBUG']: defs.append('DEBUG') +''' if env['WITH_BF_ELTOPO']: incs += ' #/extern/eltopo' incs += ' #/extern/eltopo/eltopo3d' defs.append('WITH_ELTOPO') - +''' if env['WITH_BF_QUICKTIME']: incs += ' ../quicktime' -- cgit v1.2.3 From 9b14d3608f7790a23505bd2b892963efe61b80fe Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 27 Nov 2012 10:24:18 +0000 Subject: Mark boost symbols as local This was needed to resolve conflict between blender's and pylux's boost symbols. Ideally visibility should be changed to local in lux as well, since if blender is dynamically linked against boost it'll still crash. Anyway, having this change wouldn't hurt and will solve issues with lux for official linux builds at least. --- source/creator/blender.map | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/creator/blender.map b/source/creator/blender.map index dc7bc3151e8..928d0c2d904 100644 --- a/source/creator/blender.map +++ b/source/creator/blender.map @@ -1,11 +1,16 @@ -/* on Linux we exclude LLVM symbols, they conflict with Mesa llvmpipe */ +/* on Linux we exclude LLVM symbols, they conflict with Mesa llvmpipe + * we also keep boost's symbols local, since some python modules could + * be using boost as well (mainly that's for lux render) + */ { global: *; + *_boost*; local: *llvm*; *LLVM*; + *boost*; }; -- cgit v1.2.3 From f79c61c1665b9eea828bb3ba6d8d07dfc0939a48 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 27 Nov 2012 11:28:39 +0000 Subject: Masking: fixed bug with vector handles not updating when CV is parented to a motion track. --- source/blender/blenkernel/intern/mask.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index b7f4c4bd61e..bda924060d5 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1416,7 +1416,7 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const int do for (spline = masklay->splines.first; spline; spline = spline->next) { int i; - int has_auto = FALSE; + int need_handle_recalc = FALSE; BKE_mask_spline_ensure_deform(spline); @@ -1436,16 +1436,16 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const int do add_v2_v2(point_deform->bezt.vec[2], delta); } - if (point->bezt.h1 == HD_AUTO) { - has_auto = TRUE; + if (ELEM(point->bezt.h1, HD_AUTO, HD_VECT)) { + need_handle_recalc = TRUE; } } - /* if the spline has auto handles, these need to be recalculated after deformation */ - if (has_auto) { + /* if the spline has auto or vector handles, these need to be recalculated after deformation */ + if (need_handle_recalc) { for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point_deform = &spline->points_deform[i]; - if (point_deform->bezt.h1 == HD_AUTO) { + if (ELEM(point_deform->bezt.h1, HD_AUTO, HD_VECT)) { BKE_mask_calc_handle_point(spline, point_deform); } } -- cgit v1.2.3 From 1fa12f09d5bce2a6ea64050674aefab08c45e63e Mon Sep 17 00:00:00 2001 From: Jens Verwiebe Date: Tue, 27 Nov 2012 11:38:59 +0000 Subject: OSX/scons: introducing and testing an unexported_symbols_list to prevent clashes, todo: cmake --- SConstruct | 3 +++ source/creator/osx_locals.map | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 source/creator/osx_locals.map diff --git a/SConstruct b/SConstruct index 5a1797ec1dc..d6972de8cab 100644 --- a/SConstruct +++ b/SConstruct @@ -312,6 +312,9 @@ if env['OURPLATFORM']=='darwin': env.Append(LINKFLAGS=['-L'+OSX_OSL_LIBPATH,'-loslcomp','-force_load '+ OSX_OSL_LIBPATH +'/liboslexec.a','-loslquery']) env.Append(BF_PROGRAM_LINKFLAGS=['-Xlinker','-force_load','-Xlinker',OSX_OSL_LIBPATH +'/liboslexec.a']) + # Trying to get rid of eventually clashes, we export some explicite as local symbols + env.Append(LINKFLAGS=['-Xlinker','-unexported_symbols_list','-Xlinker','./source/creator/osx_locals.map']) + if env['WITH_BF_OPENMP'] == 1: if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): env['CCFLAGS'].append('/openmp') diff --git a/source/creator/osx_locals.map b/source/creator/osx_locals.map new file mode 100644 index 00000000000..c3dd8b62792 --- /dev/null +++ b/source/creator/osx_locals.map @@ -0,0 +1,3 @@ +## The symbols will be treated as if they were marked as __private_extern__ +## (aka visibility=hidden) and will not be global in the output file +*boost* -- cgit v1.2.3 From 2d5b8172e941d0d21295dd1681309b19c70e927e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 Nov 2012 13:45:28 +0000 Subject: add empty files (will move bmesh operator calling here) --- source/blender/python/bmesh/CMakeLists.txt | 2 ++ source/blender/python/bmesh/bmesh_py_ops_call.c | 28 +++++++++++++++++++++ source/blender/python/bmesh/bmesh_py_ops_call.h | 33 +++++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 source/blender/python/bmesh/bmesh_py_ops_call.c create mode 100644 source/blender/python/bmesh/bmesh_py_ops_call.h diff --git a/source/blender/python/bmesh/CMakeLists.txt b/source/blender/python/bmesh/CMakeLists.txt index 032a914fb70..ccabe572ce5 100644 --- a/source/blender/python/bmesh/CMakeLists.txt +++ b/source/blender/python/bmesh/CMakeLists.txt @@ -34,6 +34,7 @@ set(INC_SYS set(SRC bmesh_py_api.c bmesh_py_ops.c + bmesh_py_ops_call.c bmesh_py_types.c bmesh_py_types_customdata.c bmesh_py_types_meshdata.c @@ -42,6 +43,7 @@ set(SRC bmesh_py_api.h bmesh_py_ops.h + bmesh_py_ops_call.h bmesh_py_types.h bmesh_py_types_customdata.h bmesh_py_types_meshdata.h diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c new file mode 100644 index 00000000000..9f5775d28bf --- /dev/null +++ b/source/blender/python/bmesh/bmesh_py_ops_call.c @@ -0,0 +1,28 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/python/bmesh/bmesh_py_ops_call.c + * \ingroup pybmesh + */ diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.h b/source/blender/python/bmesh/bmesh_py_ops_call.h new file mode 100644 index 00000000000..3bdf1e36b20 --- /dev/null +++ b/source/blender/python/bmesh/bmesh_py_ops_call.h @@ -0,0 +1,33 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/python/bmesh/bmesh_py_ops_call.h + * \ingroup pybmesh + */ + +#ifndef __BMESH_PY_OPS_CALL_H__ +#define __BMESH_PY_OPS_CALL_H__ + +#endif /* __BMESH_PY_OPS_CALL_H__ */ -- cgit v1.2.3 From 492af7cc6b1c0e986eaef42b2a2573a5ee4ee1da Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 Nov 2012 13:54:34 +0000 Subject: move bmesh operator calling into its own file. --- source/blender/python/bmesh/bmesh_py_ops.c | 655 +---------------------- source/blender/python/bmesh/bmesh_py_ops_call.c | 664 ++++++++++++++++++++++++ source/blender/python/bmesh/bmesh_py_ops_call.h | 8 + 3 files changed, 675 insertions(+), 652 deletions(-) diff --git a/source/blender/python/bmesh/bmesh_py_ops.c b/source/blender/python/bmesh/bmesh_py_ops.c index f2d91f67a12..0a2091af5df 100644 --- a/source/blender/python/bmesh/bmesh_py_ops.c +++ b/source/blender/python/bmesh/bmesh_py_ops.c @@ -38,39 +38,19 @@ #include "../generic/py_capi_utils.h" -#include "../mathutils/mathutils.h" - #include "bmesh.h" +#include "bmesh_py_ops_call.h" #include "bmesh_py_ops.h" /* own include */ #include "bmesh_py_types.h" -#include "bmesh_py_utils.h" /* own include */ - -static int bpy_bm_op_as_py_error(BMesh *bm) -{ - if (BMO_error_occurred(bm)) { - const char *errmsg; - if (BMO_error_get(bm, &errmsg, NULL)) { - PyErr_Format(PyExc_RuntimeError, - "bmesh operator: %.200s", - errmsg); - return -1; - } - } - return 0; -} +#include "bmesh_py_utils.h" /* bmesh operator 'bmesh.ops.*' callable types * ******************************************* */ PyTypeObject bmesh_op_Type; -typedef struct { - PyObject_HEAD /* required python macro */ - const char *opname; -} BPy_BMeshOpFunc; - static PyObject *bpy_bmesh_op_CreatePyObject(const char *opname) { BPy_BMeshOpFunc *self = PyObject_New(BPy_BMeshOpFunc, &bmesh_op_Type); @@ -88,635 +68,6 @@ static PyObject *bpy_bmesh_op_repr(BPy_BMeshOpFunc *self) } -static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw) -{ - PyObject *ret; - BPy_BMesh *py_bm; - BMesh *bm; - - BMOperator bmop; - - if ((PyTuple_GET_SIZE(args) == 1) && - (py_bm = (BPy_BMesh *)PyTuple_GET_ITEM(args, 0)) && - (BPy_BMesh_Check(py_bm)) - ) - { - BPY_BM_CHECK_OBJ(py_bm); - bm = py_bm->bm; - } - else { - PyErr_SetString(PyExc_TypeError, - "calling a bmesh operator expects a single BMesh (non keyword) " - "as the first argument"); - return NULL; - } - - /* TODO - error check this!, though we do the error check on attribute access */ - /* TODO - make flags optional */ - BMO_op_init(bm, &bmop, BMO_FLAG_DEFAULTS, self->opname); - - if (kw && PyDict_Size(kw) > 0) { - /* setup properties, see bpy_rna.c: pyrna_py_to_prop() - * which shares this logic for parsing properties */ - - PyObject *key, *value; - Py_ssize_t pos = 0; - while (PyDict_Next(kw, &pos, &key, &value)) { - const char *slot_name = _PyUnicode_AsString(key); - BMOpSlot *slot = BMO_slot_get(bmop.slots_in, slot_name); - - if (slot == NULL) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" is invalid for this operator", - self->opname, slot_name); - return NULL; - } - - /* now assign the value */ - switch (slot->slot_type) { - case BMO_OP_SLOT_BOOL: - { - int param; - - param = PyLong_AsLong(value); - - if (param < 0) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected True/False or 0/1, not %.200s", - self->opname, slot_name, Py_TYPE(value)->tp_name); - return NULL; - } - else { - BMO_SLOT_AS_BOOL(slot) = param; - } - - break; - } - case BMO_OP_SLOT_INT: - { - int overflow; - long param = PyLong_AsLongAndOverflow(value, &overflow); - if (overflow || (param > INT_MAX) || (param < INT_MIN)) { - PyErr_Format(PyExc_ValueError, - "%.200s: keyword \"%.200s\" value not in 'int' range " - "(" STRINGIFY(INT_MIN) ", " STRINGIFY(INT_MAX) ")", - self->opname, slot_name, Py_TYPE(value)->tp_name); - return NULL; - } - else if (param == -1 && PyErr_Occurred()) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected an int, not %.200s", - self->opname, slot_name, Py_TYPE(value)->tp_name); - return NULL; - } - else { - BMO_SLOT_AS_INT(slot) = (int)param; - } - break; - } - case BMO_OP_SLOT_FLT: - { - float param = PyFloat_AsDouble(value); - if (param == -1 && PyErr_Occurred()) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected a float, not %.200s", - self->opname, slot_name, Py_TYPE(value)->tp_name); - return NULL; - } - else { - BMO_SLOT_AS_FLOAT(slot) = param; - } - break; - } - case BMO_OP_SLOT_MAT: - { - /* XXX - BMesh operator design is crappy here, operator slot should define matrix size, - * not the caller! */ - unsigned short size; - if (!MatrixObject_Check(value)) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected a Matrix, not %.200s", - self->opname, slot_name, Py_TYPE(value)->tp_name); - return NULL; - } - else if (BaseMath_ReadCallback((MatrixObject *)value) == -1) { - return NULL; - } - else if (((size = ((MatrixObject *)value)->num_col) != ((MatrixObject *)value)->num_row) || - (ELEM(size, 3, 4) == FALSE)) - { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected a 3x3 or 4x4 matrix Matrix", - self->opname, slot_name); - return NULL; - } - - BMO_slot_mat_set(&bmop, bmop.slots_in, slot_name, ((MatrixObject *)value)->matrix, size); - break; - } - case BMO_OP_SLOT_VEC: - { - /* passing slot name here is a bit non-descriptive */ - if (mathutils_array_parse(BMO_SLOT_AS_VECTOR(slot), 3, 3, value, slot_name) == -1) { - return NULL; - } - break; - } - case BMO_OP_SLOT_ELEMENT_BUF: - { - if (slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) { - if (!BPy_BMElem_Check(value) || - !(((BPy_BMElem *)value)->ele->head.htype & slot->slot_subtype.elem)) - { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected a %.200s not *.200s", - self->opname, slot_name, - BPy_BMElem_StringFromHType(slot->slot_subtype.elem & BM_ALL_NOLOOP), - Py_TYPE(value)->tp_name); - return NULL; - } - else if (((BPy_BMElem *)value)->bm == NULL) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" invalidated element", - self->opname, slot_name); - return NULL; - } - - BMO_slot_buffer_from_single(&bmop, slot, &((BPy_BMElem *)value)->ele->head); - } - else { - /* there are many ways we could interpret arguments, for now... - * - verts/edges/faces from the mesh direct, - * this way the operator takes every item. - * - `TODO` a plain python sequence (list) of elements. - * - `TODO` an iterator. eg. - * face.verts - * - `TODO` (type, flag) pair, eg. - * ('VERT', {'TAG'}) - */ - -#define BPY_BM_GENERIC_MESH_TEST(type_string) \ - if (((BPy_BMGeneric *)value)->bm != bm) { \ - PyErr_Format(PyExc_NotImplementedError, \ - "%.200s: keyword \"%.200s\" " type_string " are from another bmesh", \ - self->opname, slot_name, slot->slot_type); \ - return NULL; \ - } (void)0 - -#define BPY_BM_ELEM_TYPE_TEST(type_string) \ - if ((slot->slot_subtype.elem & BM_VERT) == 0) { \ - PyErr_Format(PyExc_TypeError, \ - "%.200s: keyword \"%.200s\" expected " \ - "a list of %.200s not " type_string, \ - self->opname, slot_name, \ - BPy_BMElem_StringFromHType(slot->slot_subtype.elem & BM_ALL_NOLOOP)); \ - return NULL; \ - } (void)0 - - if (BPy_BMVertSeq_Check(value)) { - BPY_BM_GENERIC_MESH_TEST("verts"); - BPY_BM_ELEM_TYPE_TEST("verts"); - - BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_VERT); - } - else if (BPy_BMEdgeSeq_Check(value)) { - BPY_BM_GENERIC_MESH_TEST("edges"); - BPY_BM_ELEM_TYPE_TEST("edges"); - BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_EDGE); - } - else if (BPy_BMFaceSeq_Check(value)) { - BPY_BM_GENERIC_MESH_TEST("faces"); - BPY_BM_ELEM_TYPE_TEST("faces"); - BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_FACE); - } - -#undef BPY_BM_ELEM_TYPE_TEST - - else if (BPy_BMElemSeq_Check(value)) { - BMIter iter; - BMHeader *ele; - int tot; - unsigned int i; - - BPY_BM_GENERIC_MESH_TEST("elements"); - - /* this will loop over all elements which is a shame but - * we need to know this before alloc */ - /* calls bpy_bmelemseq_length() */ - tot = Py_TYPE(value)->tp_as_sequence->sq_length((PyObject *)self); - - BMO_slot_buffer_alloc(&bmop, bmop.slots_in, slot_name, tot); - - i = 0; - BM_ITER_BPY_BM_SEQ (ele, &iter, ((BPy_BMElemSeq *)value)) { - slot->data.buf[i] = ele; - i++; - } - } - /* keep this last */ - else if (PySequence_Check(value)) { - BMElem **elem_array = NULL; - Py_ssize_t elem_array_len; - - elem_array = BPy_BMElem_PySeq_As_Array(&bm, value, 0, PY_SSIZE_T_MAX, - &elem_array_len, (slot->slot_subtype.elem & BM_ALL_NOLOOP), - TRUE, TRUE, slot_name); - - /* error is set above */ - if (elem_array == NULL) { - return NULL; - } - - BMO_slot_buffer_alloc(&bmop, bmop.slots_in, slot_name, elem_array_len); - memcpy(slot->data.buf, elem_array, sizeof(void *) * elem_array_len); - PyMem_FREE(elem_array); - } - else { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected " - "a bmesh sequence, list, (htype, flag) pair, not %.200s", - self->opname, slot_name, Py_TYPE(value)->tp_name); - return NULL; - } - } -#undef BPY_BM_GENERIC_MESH_TEST - - break; - } - case BMO_OP_SLOT_MAPPING: - { - /* first check types */ - if (slot->slot_subtype.map != BMO_OP_SLOT_SUBTYPE_MAP_EMPTY) { - if (!PyDict_Check(value)) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected " - "a dict, not %.200s", - self->opname, slot_name, Py_TYPE(value)->tp_name); - return NULL; - } - } - else { - if (!PySet_Check(value)) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected " - "a set, not %.200s", - self->opname, slot_name, Py_TYPE(value)->tp_name); - return NULL; - } - } - - switch (slot->slot_subtype.map) { - - /* this could be a static function */ -#define BPY_BM_MAPPING_KEY_CHECK(arg_key) \ - if (!BPy_BMElem_Check(arg_key)) { \ - PyErr_Format(PyExc_TypeError, \ - "%.200s: keyword \"%.200s\" expected " \ - "a dict with bmesh element keys, not %.200s", \ - self->opname, slot_name, Py_TYPE(arg_key)->tp_name); \ - return NULL; \ - } \ - else if (((BPy_BMGeneric *)arg_key)->bm == NULL) { \ - PyErr_Format(PyExc_TypeError, \ - "%.200s: keyword \"%.200s\" invalidated element key in dict", \ - self->opname, slot_name); \ - return NULL; \ - } (void)0 - - - case BMO_OP_SLOT_SUBTYPE_MAP_ELEM: - { - if (PyDict_Size(value) > 0) { - PyObject *arg_key, *arg_value; - Py_ssize_t arg_pos = 0; - while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { - /* TODO, check the elements come from the right mesh? */ - BPY_BM_MAPPING_KEY_CHECK(arg_key); - - if (!BPy_BMElem_Check(arg_value)) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected " - "a dict with bmesh element values, not %.200s", - self->opname, slot_name, Py_TYPE(arg_value)->tp_name); - return NULL; - } - else if (((BPy_BMGeneric *)arg_value)->bm == NULL) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" invalidated element value in dict", - self->opname, slot_name); - return NULL; - } - - BMO_slot_map_elem_insert(&bmop, slot, - ((BPy_BMElem *)arg_key)->ele, ((BPy_BMElem *)arg_value)->ele); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_FLOAT: - { - if (PyDict_Size(value) > 0) { - PyObject *arg_key, *arg_value; - Py_ssize_t arg_pos = 0; - while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { - float value_f; - /* TODO, check the elements come from the right mesh? */ - BPY_BM_MAPPING_KEY_CHECK(arg_key); - value_f = PyFloat_AsDouble(arg_value); - - if (value_f == -1.0f && PyErr_Occurred()) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected " - "a dict with float values, not %.200s", - self->opname, slot_name, Py_TYPE(arg_value)->tp_name); - return NULL; - } - - BMO_slot_map_float_insert(&bmop, slot, - ((BPy_BMElem *)arg_key)->ele, value_f); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_INT: - { - if (PyDict_Size(value) > 0) { - PyObject *arg_key, *arg_value; - Py_ssize_t arg_pos = 0; - while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { - int value_i; - /* TODO, check the elements come from the right mesh? */ - BPY_BM_MAPPING_KEY_CHECK(arg_key); - value_i = PyLong_AsLong(arg_value); - - if (value_i == -1 && PyErr_Occurred()) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected " - "a dict with int values, not %.200s", - self->opname, slot_name, Py_TYPE(arg_value)->tp_name); - return NULL; - } - - BMO_slot_map_int_insert(&bmop, slot, - ((BPy_BMElem *)arg_key)->ele, value_i); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_BOOL: - { - if (PyDict_Size(value) > 0) { - PyObject *arg_key, *arg_value; - Py_ssize_t arg_pos = 0; - while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { - int value_i; - /* TODO, check the elements come from the right mesh? */ - BPY_BM_MAPPING_KEY_CHECK(arg_key); - value_i = PyLong_AsLong(arg_value); - - if (value_i == -1 && PyErr_Occurred()) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected " - "a dict with bool values, not %.200s", - self->opname, slot_name, Py_TYPE(arg_value)->tp_name); - return NULL; - } - - BMO_slot_map_bool_insert(&bmop, slot, - ((BPy_BMElem *)arg_key)->ele, value_i != 0); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_EMPTY: - { - if (PySet_Size(value) > 0) { - PyObject *arg_key; - Py_ssize_t arg_pos = 0; - Py_ssize_t arg_hash = 0; - while (_PySet_NextEntry(value, &arg_pos, &arg_key, &arg_hash)) { - /* TODO, check the elements come from the right mesh? */ - BPY_BM_MAPPING_KEY_CHECK(arg_key); - - BMO_slot_map_empty_insert(&bmop, slot, - ((BPy_BMElem *)arg_key)->ele); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL: - { - /* can't convert from these */ - PyErr_Format(PyExc_NotImplementedError, - "This arguments mapping subtype %d is not supported", slot->slot_subtype); - break; - } -#undef BPY_BM_MAPPING_KEY_CHECK - - } - } - default: - /* TODO --- many others */ - PyErr_Format(PyExc_NotImplementedError, - "%.200s: keyword \"%.200s\" type %d not working yet!", - self->opname, slot_name, slot->slot_type); - return NULL; - break; - } - } - } - - BMO_op_exec(bm, &bmop); - - /* from here until the end of the function, no returns, just set 'ret' */ - if (UNLIKELY(bpy_bm_op_as_py_error(bm) == -1)) { - ret = NULL; /* exception raised above */ - } - else if (bmop.slots_out[0].slot_name == NULL) { - ret = (Py_INCREF(Py_None), Py_None); - } - else { - /* build return value */ - int i; - ret = PyDict_New(); - - for (i = 0; bmop.slots_out[i].slot_name; i++) { - // BMOpDefine *op_def = opdefines[bmop.type]; - // BMOSlotType *slot_type = op_def->slot_types_out[i]; - BMOpSlot *slot = &bmop.slots_out[i]; - PyObject *item = NULL; - - /* keep switch in same order as above */ - switch (slot->slot_type) { - case BMO_OP_SLOT_BOOL: - item = PyBool_FromLong((BMO_SLOT_AS_BOOL(slot))); - break; - case BMO_OP_SLOT_INT: - item = PyLong_FromLong(BMO_SLOT_AS_INT(slot)); - break; - case BMO_OP_SLOT_FLT: - item = PyFloat_FromDouble((double)BMO_SLOT_AS_FLOAT(slot)); - break; - case BMO_OP_SLOT_MAT: - item = Matrix_CreatePyObject((float *)BMO_SLOT_AS_MATRIX(slot), 4, 4, Py_NEW, NULL); - break; - case BMO_OP_SLOT_VEC: - item = Vector_CreatePyObject(BMO_SLOT_AS_VECTOR(slot), slot->len, Py_NEW, NULL); - break; - case BMO_OP_SLOT_PTR: - BLI_assert(0); /* currently we don't have any pointer return values in use */ - item = (Py_INCREF(Py_None), Py_None); - break; - case BMO_OP_SLOT_ELEMENT_BUF: - { - if (slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) { - BMHeader *ele = BMO_slot_buffer_get_single(slot); - item = ele ? BPy_BMElem_CreatePyObject(bm, ele) : (Py_INCREF(Py_None), Py_None); - } - else { - const int size = slot->len; - void **buffer = BMO_SLOT_AS_BUFFER(slot); - int j; - - item = PyList_New(size); - for (j = 0; j < size; j++) { - BMHeader *ele = buffer[i]; - PyList_SET_ITEM(item, j, BPy_BMElem_CreatePyObject(bm, ele)); - } - } - break; - } - case BMO_OP_SLOT_MAPPING: - { - GHash *slot_hash = BMO_SLOT_AS_GHASH(slot); - GHashIterator hash_iter; - - switch (slot->slot_subtype.map) { - case BMO_OP_SLOT_SUBTYPE_MAP_ELEM: - { - item = PyDict_New(); - if (slot_hash) { - GHASH_ITER (hash_iter, slot_hash) { - BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); - BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); - - PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); - PyObject *py_val = BPy_BMElem_CreatePyObject(bm, *(void **)BMO_OP_SLOT_MAPPING_DATA(ele_val)); - - BLI_assert(slot->slot_subtype.elem & ((BPy_BMElem *)py_val)->ele->head.htype); - - PyDict_SetItem(ret, py_key, py_val); - Py_DECREF(py_key); - Py_DECREF(py_val); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_FLOAT: - { - item = PyDict_New(); - if (slot_hash) { - GHASH_ITER (hash_iter, slot_hash) { - BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); - BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); - - PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); - PyObject *py_val = PyFloat_FromDouble(*(float *)BMO_OP_SLOT_MAPPING_DATA(ele_val)); - - PyDict_SetItem(ret, py_key, py_val); - Py_DECREF(py_key); - Py_DECREF(py_val); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_INT: - { - item = PyDict_New(); - if (slot_hash) { - GHASH_ITER (hash_iter, slot_hash) { - BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); - BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); - - PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); - PyObject *py_val = PyLong_FromLong(*(int *)BMO_OP_SLOT_MAPPING_DATA(ele_val)); - - PyDict_SetItem(ret, py_key, py_val); - Py_DECREF(py_key); - Py_DECREF(py_val); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_BOOL: - { - item = PyDict_New(); - if (slot_hash) { - GHASH_ITER (hash_iter, slot_hash) { - BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); - BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); - - PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); - PyObject *py_val = PyBool_FromLong(*(int *)BMO_OP_SLOT_MAPPING_DATA(ele_val)); - - PyDict_SetItem(ret, py_key, py_val); - Py_DECREF(py_key); - Py_DECREF(py_val); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_EMPTY: - { - item = PySet_New(NULL); - if (slot_hash) { - GHASH_ITER (hash_iter, slot_hash) { - BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); - - PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); - - PySet_Add(item, py_key); - - Py_DECREF(py_key); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL: - /* can't convert from these */ - item = (Py_INCREF(Py_None), Py_None); - break; - } - break; - } - } - BLI_assert(item != NULL); - if (item == NULL) { - item = (Py_INCREF(Py_None), Py_None); - } - -#if 1 - /* temp code, strip off '.out' while we keep this convention */ - { - char slot_name_strip[MAX_SLOTNAME]; - char *ch = strchr(slot->slot_name, '.'); /* can't fail! */ - int tot = ch - slot->slot_name; - BLI_assert(ch != NULL); - memcpy(slot_name_strip, slot->slot_name, tot); - slot_name_strip[tot] = '\0'; - PyDict_SetItemString(ret, slot_name_strip, item); - } -#else - PyDict_SetItemString(ret, slot->slot_name, item); -#endif - Py_DECREF(item); - } - } - - BMO_op_finish(bm, &bmop); - return ret; -} - PyTypeObject bmesh_op_Type = { PyVarObject_HEAD_INIT(NULL, 0) @@ -740,7 +91,7 @@ PyTypeObject bmesh_op_Type = { /* More standard operations (here for binary compatibility) */ NULL, /* hashfunc tp_hash; */ - (ternaryfunc)pyrna_op_call, /* ternaryfunc tp_call; */ + (ternaryfunc)BPy_BMO_call, /* ternaryfunc tp_call; */ NULL, /* reprfunc tp_str; */ /* will only use these if this is a subtype of a py class */ diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c index 9f5775d28bf..9dadf6c2bac 100644 --- a/source/blender/python/bmesh/bmesh_py_ops_call.c +++ b/source/blender/python/bmesh/bmesh_py_ops_call.c @@ -25,4 +25,668 @@ /** \file blender/python/bmesh/bmesh_py_ops_call.c * \ingroup pybmesh + * + * This file provides __call__ aka BPy_BMO_call for + * the bmesh operatorand has been given its own file + * because argument conversion is involved. + */ + +#include + +#include "BLI_utildefines.h" + +#include "../mathutils/mathutils.h" + +#include "bmesh.h" + +#include "bmesh_py_ops.h" +#include "bmesh_py_ops_call.h" /* own include */ + +#include "bmesh_py_types.h" +#include "bmesh_py_utils.h" + +static int bpy_bm_op_as_py_error(BMesh *bm) +{ + if (BMO_error_occurred(bm)) { + const char *errmsg; + if (BMO_error_get(bm, &errmsg, NULL)) { + PyErr_Format(PyExc_RuntimeError, + "bmesh operator: %.200s", + errmsg); + return -1; + } + } + return 0; +} + +/** + * This is the __call__ for bmesh.ops.xxx() */ +PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw) +{ + PyObject *ret; + BPy_BMesh *py_bm; + BMesh *bm; + + BMOperator bmop; + + if ((PyTuple_GET_SIZE(args) == 1) && + (py_bm = (BPy_BMesh *)PyTuple_GET_ITEM(args, 0)) && + (BPy_BMesh_Check(py_bm)) + ) + { + BPY_BM_CHECK_OBJ(py_bm); + bm = py_bm->bm; + } + else { + PyErr_SetString(PyExc_TypeError, + "calling a bmesh operator expects a single BMesh (non keyword) " + "as the first argument"); + return NULL; + } + + /* TODO - error check this!, though we do the error check on attribute access */ + /* TODO - make flags optional */ + BMO_op_init(bm, &bmop, BMO_FLAG_DEFAULTS, self->opname); + + if (kw && PyDict_Size(kw) > 0) { + /* setup properties, see bpy_rna.c: pyrna_py_to_prop() + * which shares this logic for parsing properties */ + + PyObject *key, *value; + Py_ssize_t pos = 0; + while (PyDict_Next(kw, &pos, &key, &value)) { + const char *slot_name = _PyUnicode_AsString(key); + BMOpSlot *slot = BMO_slot_get(bmop.slots_in, slot_name); + + if (slot == NULL) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" is invalid for this operator", + self->opname, slot_name); + return NULL; + } + + /* now assign the value */ + switch (slot->slot_type) { + case BMO_OP_SLOT_BOOL: + { + int param; + + param = PyLong_AsLong(value); + + if (param < 0) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected True/False or 0/1, not %.200s", + self->opname, slot_name, Py_TYPE(value)->tp_name); + return NULL; + } + else { + BMO_SLOT_AS_BOOL(slot) = param; + } + + break; + } + case BMO_OP_SLOT_INT: + { + int overflow; + long param = PyLong_AsLongAndOverflow(value, &overflow); + if (overflow || (param > INT_MAX) || (param < INT_MIN)) { + PyErr_Format(PyExc_ValueError, + "%.200s: keyword \"%.200s\" value not in 'int' range " + "(" STRINGIFY(INT_MIN) ", " STRINGIFY(INT_MAX) ")", + self->opname, slot_name, Py_TYPE(value)->tp_name); + return NULL; + } + else if (param == -1 && PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected an int, not %.200s", + self->opname, slot_name, Py_TYPE(value)->tp_name); + return NULL; + } + else { + BMO_SLOT_AS_INT(slot) = (int)param; + } + break; + } + case BMO_OP_SLOT_FLT: + { + float param = PyFloat_AsDouble(value); + if (param == -1 && PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected a float, not %.200s", + self->opname, slot_name, Py_TYPE(value)->tp_name); + return NULL; + } + else { + BMO_SLOT_AS_FLOAT(slot) = param; + } + break; + } + case BMO_OP_SLOT_MAT: + { + /* XXX - BMesh operator design is crappy here, operator slot should define matrix size, + * not the caller! */ + unsigned short size; + if (!MatrixObject_Check(value)) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected a Matrix, not %.200s", + self->opname, slot_name, Py_TYPE(value)->tp_name); + return NULL; + } + else if (BaseMath_ReadCallback((MatrixObject *)value) == -1) { + return NULL; + } + else if (((size = ((MatrixObject *)value)->num_col) != ((MatrixObject *)value)->num_row) || + (ELEM(size, 3, 4) == FALSE)) + { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected a 3x3 or 4x4 matrix Matrix", + self->opname, slot_name); + return NULL; + } + + BMO_slot_mat_set(&bmop, bmop.slots_in, slot_name, ((MatrixObject *)value)->matrix, size); + break; + } + case BMO_OP_SLOT_VEC: + { + /* passing slot name here is a bit non-descriptive */ + if (mathutils_array_parse(BMO_SLOT_AS_VECTOR(slot), 3, 3, value, slot_name) == -1) { + return NULL; + } + break; + } + case BMO_OP_SLOT_ELEMENT_BUF: + { + if (slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) { + if (!BPy_BMElem_Check(value) || + !(((BPy_BMElem *)value)->ele->head.htype & slot->slot_subtype.elem)) + { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected a %.200s not *.200s", + self->opname, slot_name, + BPy_BMElem_StringFromHType(slot->slot_subtype.elem & BM_ALL_NOLOOP), + Py_TYPE(value)->tp_name); + return NULL; + } + else if (((BPy_BMElem *)value)->bm == NULL) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" invalidated element", + self->opname, slot_name); + return NULL; + } + + BMO_slot_buffer_from_single(&bmop, slot, &((BPy_BMElem *)value)->ele->head); + } + else { + /* there are many ways we could interpret arguments, for now... + * - verts/edges/faces from the mesh direct, + * this way the operator takes every item. + * - `TODO` a plain python sequence (list) of elements. + * - `TODO` an iterator. eg. + * face.verts + * - `TODO` (type, flag) pair, eg. + * ('VERT', {'TAG'}) + */ + +#define BPY_BM_GENERIC_MESH_TEST(type_string) \ + if (((BPy_BMGeneric *)value)->bm != bm) { \ + PyErr_Format(PyExc_NotImplementedError, \ + "%.200s: keyword \"%.200s\" " type_string " are from another bmesh", \ + self->opname, slot_name, slot->slot_type); \ + return NULL; \ + } (void)0 + +#define BPY_BM_ELEM_TYPE_TEST(type_string) \ + if ((slot->slot_subtype.elem & BM_VERT) == 0) { \ + PyErr_Format(PyExc_TypeError, \ + "%.200s: keyword \"%.200s\" expected " \ + "a list of %.200s not " type_string, \ + self->opname, slot_name, \ + BPy_BMElem_StringFromHType(slot->slot_subtype.elem & BM_ALL_NOLOOP)); \ + return NULL; \ + } (void)0 + + if (BPy_BMVertSeq_Check(value)) { + BPY_BM_GENERIC_MESH_TEST("verts"); + BPY_BM_ELEM_TYPE_TEST("verts"); + + BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_VERT); + } + else if (BPy_BMEdgeSeq_Check(value)) { + BPY_BM_GENERIC_MESH_TEST("edges"); + BPY_BM_ELEM_TYPE_TEST("edges"); + BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_EDGE); + } + else if (BPy_BMFaceSeq_Check(value)) { + BPY_BM_GENERIC_MESH_TEST("faces"); + BPY_BM_ELEM_TYPE_TEST("faces"); + BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_FACE); + } + +#undef BPY_BM_ELEM_TYPE_TEST + + else if (BPy_BMElemSeq_Check(value)) { + BMIter iter; + BMHeader *ele; + int tot; + unsigned int i; + + BPY_BM_GENERIC_MESH_TEST("elements"); + + /* this will loop over all elements which is a shame but + * we need to know this before alloc */ + /* calls bpy_bmelemseq_length() */ + tot = Py_TYPE(value)->tp_as_sequence->sq_length((PyObject *)self); + + BMO_slot_buffer_alloc(&bmop, bmop.slots_in, slot_name, tot); + + i = 0; + BM_ITER_BPY_BM_SEQ (ele, &iter, ((BPy_BMElemSeq *)value)) { + slot->data.buf[i] = ele; + i++; + } + } + /* keep this last */ + else if (PySequence_Check(value)) { + BMElem **elem_array = NULL; + Py_ssize_t elem_array_len; + + elem_array = BPy_BMElem_PySeq_As_Array(&bm, value, 0, PY_SSIZE_T_MAX, + &elem_array_len, (slot->slot_subtype.elem & BM_ALL_NOLOOP), + TRUE, TRUE, slot_name); + + /* error is set above */ + if (elem_array == NULL) { + return NULL; + } + + BMO_slot_buffer_alloc(&bmop, bmop.slots_in, slot_name, elem_array_len); + memcpy(slot->data.buf, elem_array, sizeof(void *) * elem_array_len); + PyMem_FREE(elem_array); + } + else { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a bmesh sequence, list, (htype, flag) pair, not %.200s", + self->opname, slot_name, Py_TYPE(value)->tp_name); + return NULL; + } + } +#undef BPY_BM_GENERIC_MESH_TEST + + break; + } + case BMO_OP_SLOT_MAPPING: + { + /* first check types */ + if (slot->slot_subtype.map != BMO_OP_SLOT_SUBTYPE_MAP_EMPTY) { + if (!PyDict_Check(value)) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a dict, not %.200s", + self->opname, slot_name, Py_TYPE(value)->tp_name); + return NULL; + } + } + else { + if (!PySet_Check(value)) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a set, not %.200s", + self->opname, slot_name, Py_TYPE(value)->tp_name); + return NULL; + } + } + + switch (slot->slot_subtype.map) { + + /* this could be a static function */ +#define BPY_BM_MAPPING_KEY_CHECK(arg_key) \ + if (!BPy_BMElem_Check(arg_key)) { \ + PyErr_Format(PyExc_TypeError, \ + "%.200s: keyword \"%.200s\" expected " \ + "a dict with bmesh element keys, not %.200s", \ + self->opname, slot_name, Py_TYPE(arg_key)->tp_name); \ + return NULL; \ + } \ + else if (((BPy_BMGeneric *)arg_key)->bm == NULL) { \ + PyErr_Format(PyExc_TypeError, \ + "%.200s: keyword \"%.200s\" invalidated element key in dict", \ + self->opname, slot_name); \ + return NULL; \ + } (void)0 + + + case BMO_OP_SLOT_SUBTYPE_MAP_ELEM: + { + if (PyDict_Size(value) > 0) { + PyObject *arg_key, *arg_value; + Py_ssize_t arg_pos = 0; + while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { + /* TODO, check the elements come from the right mesh? */ + BPY_BM_MAPPING_KEY_CHECK(arg_key); + + if (!BPy_BMElem_Check(arg_value)) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a dict with bmesh element values, not %.200s", + self->opname, slot_name, Py_TYPE(arg_value)->tp_name); + return NULL; + } + else if (((BPy_BMGeneric *)arg_value)->bm == NULL) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" invalidated element value in dict", + self->opname, slot_name); + return NULL; + } + + BMO_slot_map_elem_insert(&bmop, slot, + ((BPy_BMElem *)arg_key)->ele, ((BPy_BMElem *)arg_value)->ele); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_FLOAT: + { + if (PyDict_Size(value) > 0) { + PyObject *arg_key, *arg_value; + Py_ssize_t arg_pos = 0; + while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { + float value_f; + /* TODO, check the elements come from the right mesh? */ + BPY_BM_MAPPING_KEY_CHECK(arg_key); + value_f = PyFloat_AsDouble(arg_value); + + if (value_f == -1.0f && PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a dict with float values, not %.200s", + self->opname, slot_name, Py_TYPE(arg_value)->tp_name); + return NULL; + } + + BMO_slot_map_float_insert(&bmop, slot, + ((BPy_BMElem *)arg_key)->ele, value_f); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_INT: + { + if (PyDict_Size(value) > 0) { + PyObject *arg_key, *arg_value; + Py_ssize_t arg_pos = 0; + while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { + int value_i; + /* TODO, check the elements come from the right mesh? */ + BPY_BM_MAPPING_KEY_CHECK(arg_key); + value_i = PyLong_AsLong(arg_value); + + if (value_i == -1 && PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a dict with int values, not %.200s", + self->opname, slot_name, Py_TYPE(arg_value)->tp_name); + return NULL; + } + + BMO_slot_map_int_insert(&bmop, slot, + ((BPy_BMElem *)arg_key)->ele, value_i); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_BOOL: + { + if (PyDict_Size(value) > 0) { + PyObject *arg_key, *arg_value; + Py_ssize_t arg_pos = 0; + while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { + int value_i; + /* TODO, check the elements come from the right mesh? */ + BPY_BM_MAPPING_KEY_CHECK(arg_key); + value_i = PyLong_AsLong(arg_value); + + if (value_i == -1 && PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a dict with bool values, not %.200s", + self->opname, slot_name, Py_TYPE(arg_value)->tp_name); + return NULL; + } + + BMO_slot_map_bool_insert(&bmop, slot, + ((BPy_BMElem *)arg_key)->ele, value_i != 0); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_EMPTY: + { + if (PySet_Size(value) > 0) { + PyObject *arg_key; + Py_ssize_t arg_pos = 0; + Py_ssize_t arg_hash = 0; + while (_PySet_NextEntry(value, &arg_pos, &arg_key, &arg_hash)) { + /* TODO, check the elements come from the right mesh? */ + BPY_BM_MAPPING_KEY_CHECK(arg_key); + + BMO_slot_map_empty_insert(&bmop, slot, + ((BPy_BMElem *)arg_key)->ele); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL: + { + /* can't convert from these */ + PyErr_Format(PyExc_NotImplementedError, + "This arguments mapping subtype %d is not supported", slot->slot_subtype); + break; + } +#undef BPY_BM_MAPPING_KEY_CHECK + + } + } + default: + /* TODO --- many others */ + PyErr_Format(PyExc_NotImplementedError, + "%.200s: keyword \"%.200s\" type %d not working yet!", + self->opname, slot_name, slot->slot_type); + return NULL; + break; + } + } + } + + BMO_op_exec(bm, &bmop); + + /* from here until the end of the function, no returns, just set 'ret' */ + if (UNLIKELY(bpy_bm_op_as_py_error(bm) == -1)) { + ret = NULL; /* exception raised above */ + } + else if (bmop.slots_out[0].slot_name == NULL) { + ret = (Py_INCREF(Py_None), Py_None); + } + else { + /* build return value */ + int i; + ret = PyDict_New(); + + for (i = 0; bmop.slots_out[i].slot_name; i++) { + // BMOpDefine *op_def = opdefines[bmop.type]; + // BMOSlotType *slot_type = op_def->slot_types_out[i]; + BMOpSlot *slot = &bmop.slots_out[i]; + PyObject *item = NULL; + + /* keep switch in same order as above */ + switch (slot->slot_type) { + case BMO_OP_SLOT_BOOL: + item = PyBool_FromLong((BMO_SLOT_AS_BOOL(slot))); + break; + case BMO_OP_SLOT_INT: + item = PyLong_FromLong(BMO_SLOT_AS_INT(slot)); + break; + case BMO_OP_SLOT_FLT: + item = PyFloat_FromDouble((double)BMO_SLOT_AS_FLOAT(slot)); + break; + case BMO_OP_SLOT_MAT: + item = Matrix_CreatePyObject((float *)BMO_SLOT_AS_MATRIX(slot), 4, 4, Py_NEW, NULL); + break; + case BMO_OP_SLOT_VEC: + item = Vector_CreatePyObject(BMO_SLOT_AS_VECTOR(slot), slot->len, Py_NEW, NULL); + break; + case BMO_OP_SLOT_PTR: + BLI_assert(0); /* currently we don't have any pointer return values in use */ + item = (Py_INCREF(Py_None), Py_None); + break; + case BMO_OP_SLOT_ELEMENT_BUF: + { + if (slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) { + BMHeader *ele = BMO_slot_buffer_get_single(slot); + item = ele ? BPy_BMElem_CreatePyObject(bm, ele) : (Py_INCREF(Py_None), Py_None); + } + else { + const int size = slot->len; + void **buffer = BMO_SLOT_AS_BUFFER(slot); + int j; + + item = PyList_New(size); + for (j = 0; j < size; j++) { + BMHeader *ele = buffer[i]; + PyList_SET_ITEM(item, j, BPy_BMElem_CreatePyObject(bm, ele)); + } + } + break; + } + case BMO_OP_SLOT_MAPPING: + { + GHash *slot_hash = BMO_SLOT_AS_GHASH(slot); + GHashIterator hash_iter; + + switch (slot->slot_subtype.map) { + case BMO_OP_SLOT_SUBTYPE_MAP_ELEM: + { + item = PyDict_New(); + if (slot_hash) { + GHASH_ITER (hash_iter, slot_hash) { + BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); + BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); + + PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); + PyObject *py_val = BPy_BMElem_CreatePyObject(bm, *(void **)BMO_OP_SLOT_MAPPING_DATA(ele_val)); + + BLI_assert(slot->slot_subtype.elem & ((BPy_BMElem *)py_val)->ele->head.htype); + + PyDict_SetItem(ret, py_key, py_val); + Py_DECREF(py_key); + Py_DECREF(py_val); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_FLOAT: + { + item = PyDict_New(); + if (slot_hash) { + GHASH_ITER (hash_iter, slot_hash) { + BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); + BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); + + PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); + PyObject *py_val = PyFloat_FromDouble(*(float *)BMO_OP_SLOT_MAPPING_DATA(ele_val)); + + PyDict_SetItem(ret, py_key, py_val); + Py_DECREF(py_key); + Py_DECREF(py_val); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_INT: + { + item = PyDict_New(); + if (slot_hash) { + GHASH_ITER (hash_iter, slot_hash) { + BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); + BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); + + PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); + PyObject *py_val = PyLong_FromLong(*(int *)BMO_OP_SLOT_MAPPING_DATA(ele_val)); + + PyDict_SetItem(ret, py_key, py_val); + Py_DECREF(py_key); + Py_DECREF(py_val); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_BOOL: + { + item = PyDict_New(); + if (slot_hash) { + GHASH_ITER (hash_iter, slot_hash) { + BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); + BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); + + PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); + PyObject *py_val = PyBool_FromLong(*(int *)BMO_OP_SLOT_MAPPING_DATA(ele_val)); + + PyDict_SetItem(ret, py_key, py_val); + Py_DECREF(py_key); + Py_DECREF(py_val); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_EMPTY: + { + item = PySet_New(NULL); + if (slot_hash) { + GHASH_ITER (hash_iter, slot_hash) { + BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); + + PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); + + PySet_Add(item, py_key); + + Py_DECREF(py_key); + } + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL: + /* can't convert from these */ + item = (Py_INCREF(Py_None), Py_None); + break; + } + break; + } + } + BLI_assert(item != NULL); + if (item == NULL) { + item = (Py_INCREF(Py_None), Py_None); + } + +#if 1 + /* temp code, strip off '.out' while we keep this convention */ + { + char slot_name_strip[MAX_SLOTNAME]; + char *ch = strchr(slot->slot_name, '.'); /* can't fail! */ + int tot = ch - slot->slot_name; + BLI_assert(ch != NULL); + memcpy(slot_name_strip, slot->slot_name, tot); + slot_name_strip[tot] = '\0'; + PyDict_SetItemString(ret, slot_name_strip, item); + } +#else + PyDict_SetItemString(ret, slot->slot_name, item); +#endif + Py_DECREF(item); + } + } + + BMO_op_finish(bm, &bmop); + return ret; +} diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.h b/source/blender/python/bmesh/bmesh_py_ops_call.h index 3bdf1e36b20..d350aec8f7f 100644 --- a/source/blender/python/bmesh/bmesh_py_ops_call.h +++ b/source/blender/python/bmesh/bmesh_py_ops_call.h @@ -30,4 +30,12 @@ #ifndef __BMESH_PY_OPS_CALL_H__ #define __BMESH_PY_OPS_CALL_H__ +typedef struct { + PyObject_HEAD /* required python macro */ + const char *opname; +} BPy_BMeshOpFunc; + + +PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw); + #endif /* __BMESH_PY_OPS_CALL_H__ */ -- cgit v1.2.3 From c9d84ab5ed3ba8ff89f7205d614c93fc92f83262 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 Nov 2012 14:25:38 +0000 Subject: split py->slot & slot->py into their own functions & fixed some mistakes with conversion. --- source/blender/python/bmesh/bmesh_py_ops_call.c | 1081 ++++++++++++----------- 1 file changed, 556 insertions(+), 525 deletions(-) diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c index 9dadf6c2bac..222ceadbc3d 100644 --- a/source/blender/python/bmesh/bmesh_py_ops_call.c +++ b/source/blender/python/bmesh/bmesh_py_ops_call.c @@ -60,443 +60,617 @@ static int bpy_bm_op_as_py_error(BMesh *bm) } /** - * This is the __call__ for bmesh.ops.xxx() + * Use for giving py args to an operator. */ -PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw) +static int bpy_slot_from_py(BMesh *bm, BMOperator *bmop, BMOpSlot *slot, PyObject *value, + /* the are just for exception messages */ + const char *opname, const char *slot_name) { - PyObject *ret; - BPy_BMesh *py_bm; - BMesh *bm; - - BMOperator bmop; - - if ((PyTuple_GET_SIZE(args) == 1) && - (py_bm = (BPy_BMesh *)PyTuple_GET_ITEM(args, 0)) && - (BPy_BMesh_Check(py_bm)) - ) - { - BPY_BM_CHECK_OBJ(py_bm); - bm = py_bm->bm; - } - else { - PyErr_SetString(PyExc_TypeError, - "calling a bmesh operator expects a single BMesh (non keyword) " - "as the first argument"); - return NULL; - } + switch (slot->slot_type) { + case BMO_OP_SLOT_BOOL: + { + int param; - /* TODO - error check this!, though we do the error check on attribute access */ - /* TODO - make flags optional */ - BMO_op_init(bm, &bmop, BMO_FLAG_DEFAULTS, self->opname); + param = PyLong_AsLong(value); - if (kw && PyDict_Size(kw) > 0) { - /* setup properties, see bpy_rna.c: pyrna_py_to_prop() - * which shares this logic for parsing properties */ - - PyObject *key, *value; - Py_ssize_t pos = 0; - while (PyDict_Next(kw, &pos, &key, &value)) { - const char *slot_name = _PyUnicode_AsString(key); - BMOpSlot *slot = BMO_slot_get(bmop.slots_in, slot_name); + if (param < 0) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected True/False or 0/1, not %.200s", + opname, slot_name, Py_TYPE(value)->tp_name); + return -1; + } + else { + BMO_SLOT_AS_BOOL(slot) = param; + } - if (slot == NULL) { + break; + } + case BMO_OP_SLOT_INT: + { + int overflow; + long param = PyLong_AsLongAndOverflow(value, &overflow); + if (overflow || (param > INT_MAX) || (param < INT_MIN)) { + PyErr_Format(PyExc_ValueError, + "%.200s: keyword \"%.200s\" value not in 'int' range " + "(" STRINGIFY(INT_MIN) ", " STRINGIFY(INT_MAX) ")", + opname, slot_name, Py_TYPE(value)->tp_name); + return -1; + } + else if (param == -1 && PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" is invalid for this operator", - self->opname, slot_name); - return NULL; + "%.200s: keyword \"%.200s\" expected an int, not %.200s", + opname, slot_name, Py_TYPE(value)->tp_name); + return -1; + } + else { + BMO_SLOT_AS_INT(slot) = (int)param; + } + break; + } + case BMO_OP_SLOT_FLT: + { + float param = PyFloat_AsDouble(value); + if (param == -1 && PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected a float, not %.200s", + opname, slot_name, Py_TYPE(value)->tp_name); + return -1; + } + else { + BMO_SLOT_AS_FLOAT(slot) = param; + } + break; + } + case BMO_OP_SLOT_MAT: + { + /* XXX - BMesh operator design is crappy here, operator slot should define matrix size, + * not the caller! */ + unsigned short size; + if (!MatrixObject_Check(value)) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected a Matrix, not %.200s", + opname, slot_name, Py_TYPE(value)->tp_name); + return -1; + } + else if (BaseMath_ReadCallback((MatrixObject *)value) == -1) { + return -1; + } + else if (((size = ((MatrixObject *)value)->num_col) != ((MatrixObject *)value)->num_row) || + (ELEM(size, 3, 4) == FALSE)) + { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected a 3x3 or 4x4 matrix Matrix", + opname, slot_name); + return -1; } - /* now assign the value */ - switch (slot->slot_type) { - case BMO_OP_SLOT_BOOL: + BMO_slot_mat_set(bmop, bmop->slots_in, slot_name, ((MatrixObject *)value)->matrix, size); + break; + } + case BMO_OP_SLOT_VEC: + { + /* passing slot name here is a bit non-descriptive */ + if (mathutils_array_parse(BMO_SLOT_AS_VECTOR(slot), 3, 3, value, slot_name) == -1) { + return -1; + } + break; + } + case BMO_OP_SLOT_ELEMENT_BUF: + { + if (slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) { + if (!BPy_BMElem_Check(value) || + !(((BPy_BMElem *)value)->ele->head.htype & slot->slot_subtype.elem)) { - int param; + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected a %.200s not *.200s", + opname, slot_name, + BPy_BMElem_StringFromHType(slot->slot_subtype.elem & BM_ALL_NOLOOP), + Py_TYPE(value)->tp_name); + return -1; + } + else if (((BPy_BMElem *)value)->bm == NULL) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" invalidated element", + opname, slot_name); + return -1; + } + + BMO_slot_buffer_from_single(bmop, slot, &((BPy_BMElem *)value)->ele->head); + } + else { + /* there are many ways we could interpret arguments, for now... + * - verts/edges/faces from the mesh direct, + * this way the operator takes every item. + * - `TODO` a plain python sequence (list) of elements. + * - `TODO` an iterator. eg. + * face.verts + * - `TODO` (type, flag) pair, eg. + * ('VERT', {'TAG'}) + */ + +#define BPY_BM_GENERIC_MESH_TEST(type_string) \ +if (((BPy_BMGeneric *)value)->bm != bm) { \ + PyErr_Format(PyExc_NotImplementedError, \ + "%.200s: keyword \"%.200s\" " type_string " are from another bmesh", \ + opname, slot_name, slot->slot_type); \ + return -1; \ + } (void)0 + +#define BPY_BM_ELEM_TYPE_TEST(type_string) \ + if ((slot->slot_subtype.elem & BM_VERT) == 0) { \ + PyErr_Format(PyExc_TypeError, \ + "%.200s: keyword \"%.200s\" expected " \ + "a list of %.200s not " type_string, \ + opname, slot_name, \ + BPy_BMElem_StringFromHType(slot->slot_subtype.elem & BM_ALL_NOLOOP)); \ + return -1; \ + } (void)0 - param = PyLong_AsLong(value); + if (BPy_BMVertSeq_Check(value)) { + BPY_BM_GENERIC_MESH_TEST("verts"); + BPY_BM_ELEM_TYPE_TEST("verts"); + + BMO_slot_buffer_from_all(bm, bmop, bmop->slots_in, slot_name, BM_VERT); + } + else if (BPy_BMEdgeSeq_Check(value)) { + BPY_BM_GENERIC_MESH_TEST("edges"); + BPY_BM_ELEM_TYPE_TEST("edges"); + BMO_slot_buffer_from_all(bm, bmop, bmop->slots_in, slot_name, BM_EDGE); + } + else if (BPy_BMFaceSeq_Check(value)) { + BPY_BM_GENERIC_MESH_TEST("faces"); + BPY_BM_ELEM_TYPE_TEST("faces"); + BMO_slot_buffer_from_all(bm, bmop, bmop->slots_in, slot_name, BM_FACE); + } + +#undef BPY_BM_ELEM_TYPE_TEST - if (param < 0) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected True/False or 0/1, not %.200s", - self->opname, slot_name, Py_TYPE(value)->tp_name); - return NULL; + else if (BPy_BMElemSeq_Check(value)) { + BMIter iter; + BMHeader *ele; + int tot; + unsigned int i; + + BPY_BM_GENERIC_MESH_TEST("elements"); + + /* this will loop over all elements which is a shame but + * we need to know this before alloc */ + /* calls bpy_bmelemseq_length() */ + tot = Py_TYPE(value)->tp_as_sequence->sq_length((PyObject *)value); + + BMO_slot_buffer_alloc(bmop, bmop->slots_in, slot_name, tot); + + i = 0; + BM_ITER_BPY_BM_SEQ (ele, &iter, ((BPy_BMElemSeq *)value)) { + slot->data.buf[i] = ele; + i++; } - else { - BMO_SLOT_AS_BOOL(slot) = param; + } + /* keep this last */ + else if (PySequence_Check(value)) { + BMElem **elem_array = NULL; + Py_ssize_t elem_array_len; + + elem_array = BPy_BMElem_PySeq_As_Array(&bm, value, 0, PY_SSIZE_T_MAX, + &elem_array_len, (slot->slot_subtype.elem & BM_ALL_NOLOOP), + TRUE, TRUE, slot_name); + + /* error is set above */ + if (elem_array == NULL) { + return -1; } - break; + BMO_slot_buffer_alloc(bmop, bmop->slots_in, slot_name, elem_array_len); + memcpy(slot->data.buf, elem_array, sizeof(void *) * elem_array_len); + PyMem_FREE(elem_array); + } + else { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a bmesh sequence, list, (htype, flag) pair, not %.200s", + opname, slot_name, Py_TYPE(value)->tp_name); + return -1; + } + } +#undef BPY_BM_GENERIC_MESH_TEST + + break; + } + case BMO_OP_SLOT_MAPPING: + { + /* first check types */ + if (slot->slot_subtype.map != BMO_OP_SLOT_SUBTYPE_MAP_EMPTY) { + if (!PyDict_Check(value)) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a dict, not %.200s", + opname, slot_name, Py_TYPE(value)->tp_name); + return -1; } - case BMO_OP_SLOT_INT: + } + else { + if (!PySet_Check(value)) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a set, not %.200s", + opname, slot_name, Py_TYPE(value)->tp_name); + return -1; + } + } + + switch (slot->slot_subtype.map) { + + /* this could be a static function */ +#define BPY_BM_MAPPING_KEY_CHECK(arg_key) \ + if (!BPy_BMElem_Check(arg_key)) { \ + PyErr_Format(PyExc_TypeError, \ + "%.200s: keyword \"%.200s\" expected " \ + "a dict with bmesh element keys, not %.200s", \ + opname, slot_name, Py_TYPE(arg_key)->tp_name); \ + return -1; \ + } \ + else if (((BPy_BMGeneric *)arg_key)->bm == NULL) { \ + PyErr_Format(PyExc_TypeError, \ + "%.200s: keyword \"%.200s\" invalidated element key in dict", \ + opname, slot_name); \ + return -1; \ + } (void)0 + + + case BMO_OP_SLOT_SUBTYPE_MAP_ELEM: { - int overflow; - long param = PyLong_AsLongAndOverflow(value, &overflow); - if (overflow || (param > INT_MAX) || (param < INT_MIN)) { - PyErr_Format(PyExc_ValueError, - "%.200s: keyword \"%.200s\" value not in 'int' range " - "(" STRINGIFY(INT_MIN) ", " STRINGIFY(INT_MAX) ")", - self->opname, slot_name, Py_TYPE(value)->tp_name); - return NULL; - } - else if (param == -1 && PyErr_Occurred()) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected an int, not %.200s", - self->opname, slot_name, Py_TYPE(value)->tp_name); - return NULL; - } - else { - BMO_SLOT_AS_INT(slot) = (int)param; + if (PyDict_Size(value) > 0) { + PyObject *arg_key, *arg_value; + Py_ssize_t arg_pos = 0; + while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { + /* TODO, check the elements come from the right mesh? */ + BPY_BM_MAPPING_KEY_CHECK(arg_key); + + if (!BPy_BMElem_Check(arg_value)) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a dict with bmesh element values, not %.200s", + opname, slot_name, Py_TYPE(arg_value)->tp_name); + return -1; + } + else if (((BPy_BMGeneric *)arg_value)->bm == NULL) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" invalidated element value in dict", + opname, slot_name); + return -1; + } + + BMO_slot_map_elem_insert(bmop, slot, + ((BPy_BMElem *)arg_key)->ele, ((BPy_BMElem *)arg_value)->ele); + } } break; } - case BMO_OP_SLOT_FLT: + case BMO_OP_SLOT_SUBTYPE_MAP_FLOAT: { - float param = PyFloat_AsDouble(value); - if (param == -1 && PyErr_Occurred()) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected a float, not %.200s", - self->opname, slot_name, Py_TYPE(value)->tp_name); - return NULL; - } - else { - BMO_SLOT_AS_FLOAT(slot) = param; + if (PyDict_Size(value) > 0) { + PyObject *arg_key, *arg_value; + Py_ssize_t arg_pos = 0; + while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { + float value_f; + /* TODO, check the elements come from the right mesh? */ + BPY_BM_MAPPING_KEY_CHECK(arg_key); + value_f = PyFloat_AsDouble(arg_value); + + if (value_f == -1.0f && PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a dict with float values, not %.200s", + opname, slot_name, Py_TYPE(arg_value)->tp_name); + return -1; + } + + BMO_slot_map_float_insert(bmop, slot, + ((BPy_BMElem *)arg_key)->ele, value_f); + } } break; } - case BMO_OP_SLOT_MAT: + case BMO_OP_SLOT_SUBTYPE_MAP_INT: { - /* XXX - BMesh operator design is crappy here, operator slot should define matrix size, - * not the caller! */ - unsigned short size; - if (!MatrixObject_Check(value)) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected a Matrix, not %.200s", - self->opname, slot_name, Py_TYPE(value)->tp_name); - return NULL; - } - else if (BaseMath_ReadCallback((MatrixObject *)value) == -1) { - return NULL; - } - else if (((size = ((MatrixObject *)value)->num_col) != ((MatrixObject *)value)->num_row) || - (ELEM(size, 3, 4) == FALSE)) - { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected a 3x3 or 4x4 matrix Matrix", - self->opname, slot_name); - return NULL; - } + if (PyDict_Size(value) > 0) { + PyObject *arg_key, *arg_value; + Py_ssize_t arg_pos = 0; + while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { + int value_i; + /* TODO, check the elements come from the right mesh? */ + BPY_BM_MAPPING_KEY_CHECK(arg_key); + value_i = PyLong_AsLong(arg_value); + + if (value_i == -1 && PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a dict with int values, not %.200s", + opname, slot_name, Py_TYPE(arg_value)->tp_name); + return -1; + } - BMO_slot_mat_set(&bmop, bmop.slots_in, slot_name, ((MatrixObject *)value)->matrix, size); + BMO_slot_map_int_insert(bmop, slot, + ((BPy_BMElem *)arg_key)->ele, value_i); + } + } break; } - case BMO_OP_SLOT_VEC: + case BMO_OP_SLOT_SUBTYPE_MAP_BOOL: { - /* passing slot name here is a bit non-descriptive */ - if (mathutils_array_parse(BMO_SLOT_AS_VECTOR(slot), 3, 3, value, slot_name) == -1) { - return NULL; + if (PyDict_Size(value) > 0) { + PyObject *arg_key, *arg_value; + Py_ssize_t arg_pos = 0; + while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { + int value_i; + /* TODO, check the elements come from the right mesh? */ + BPY_BM_MAPPING_KEY_CHECK(arg_key); + value_i = PyLong_AsLong(arg_value); + + if (value_i == -1 && PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" expected " + "a dict with bool values, not %.200s", + opname, slot_name, Py_TYPE(arg_value)->tp_name); + return -1; + } + + BMO_slot_map_bool_insert(bmop, slot, + ((BPy_BMElem *)arg_key)->ele, value_i != 0); + } } break; } - case BMO_OP_SLOT_ELEMENT_BUF: + case BMO_OP_SLOT_SUBTYPE_MAP_EMPTY: { - if (slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) { - if (!BPy_BMElem_Check(value) || - !(((BPy_BMElem *)value)->ele->head.htype & slot->slot_subtype.elem)) - { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected a %.200s not *.200s", - self->opname, slot_name, - BPy_BMElem_StringFromHType(slot->slot_subtype.elem & BM_ALL_NOLOOP), - Py_TYPE(value)->tp_name); - return NULL; - } - else if (((BPy_BMElem *)value)->bm == NULL) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" invalidated element", - self->opname, slot_name); - return NULL; + if (PySet_Size(value) > 0) { + PyObject *arg_key; + Py_ssize_t arg_pos = 0; + Py_ssize_t arg_hash = 0; + while (_PySet_NextEntry(value, &arg_pos, &arg_key, &arg_hash)) { + /* TODO, check the elements come from the right mesh? */ + BPY_BM_MAPPING_KEY_CHECK(arg_key); + + BMO_slot_map_empty_insert(bmop, slot, + ((BPy_BMElem *)arg_key)->ele); } - - BMO_slot_buffer_from_single(&bmop, slot, &((BPy_BMElem *)value)->ele->head); } - else { - /* there are many ways we could interpret arguments, for now... - * - verts/edges/faces from the mesh direct, - * this way the operator takes every item. - * - `TODO` a plain python sequence (list) of elements. - * - `TODO` an iterator. eg. - * face.verts - * - `TODO` (type, flag) pair, eg. - * ('VERT', {'TAG'}) - */ - -#define BPY_BM_GENERIC_MESH_TEST(type_string) \ - if (((BPy_BMGeneric *)value)->bm != bm) { \ - PyErr_Format(PyExc_NotImplementedError, \ - "%.200s: keyword \"%.200s\" " type_string " are from another bmesh", \ - self->opname, slot_name, slot->slot_type); \ - return NULL; \ - } (void)0 - -#define BPY_BM_ELEM_TYPE_TEST(type_string) \ - if ((slot->slot_subtype.elem & BM_VERT) == 0) { \ - PyErr_Format(PyExc_TypeError, \ - "%.200s: keyword \"%.200s\" expected " \ - "a list of %.200s not " type_string, \ - self->opname, slot_name, \ - BPy_BMElem_StringFromHType(slot->slot_subtype.elem & BM_ALL_NOLOOP)); \ - return NULL; \ - } (void)0 - - if (BPy_BMVertSeq_Check(value)) { - BPY_BM_GENERIC_MESH_TEST("verts"); - BPY_BM_ELEM_TYPE_TEST("verts"); - - BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_VERT); - } - else if (BPy_BMEdgeSeq_Check(value)) { - BPY_BM_GENERIC_MESH_TEST("edges"); - BPY_BM_ELEM_TYPE_TEST("edges"); - BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_EDGE); - } - else if (BPy_BMFaceSeq_Check(value)) { - BPY_BM_GENERIC_MESH_TEST("faces"); - BPY_BM_ELEM_TYPE_TEST("faces"); - BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_FACE); - } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL: + { + /* can't convert from these */ + PyErr_Format(PyExc_NotImplementedError, + "This arguments mapping subtype %d is not supported", slot->slot_subtype); + return -1; + } +#undef BPY_BM_MAPPING_KEY_CHECK -#undef BPY_BM_ELEM_TYPE_TEST + } + } + default: + /* TODO --- many others */ + PyErr_Format(PyExc_NotImplementedError, + "%.200s: keyword \"%.200s\" type %d not working yet!", + opname, slot_name, slot->slot_type); + return -1; + } - else if (BPy_BMElemSeq_Check(value)) { - BMIter iter; - BMHeader *ele; - int tot; - unsigned int i; + /* all is well */ + return 0; +} - BPY_BM_GENERIC_MESH_TEST("elements"); +/** + * Use for getting return values from an operator thats already executed. + * + * \note Don't throw any exceptions and should always return a valid (PyObject *). + */ +static PyObject* bpy_slot_to_py(BMesh *bm, BMOpSlot *slot) +{ + PyObject *item = NULL; + + /* keep switch in same order as above */ + switch (slot->slot_type) { + case BMO_OP_SLOT_BOOL: + item = PyBool_FromLong((BMO_SLOT_AS_BOOL(slot))); + break; + case BMO_OP_SLOT_INT: + item = PyLong_FromLong(BMO_SLOT_AS_INT(slot)); + break; + case BMO_OP_SLOT_FLT: + item = PyFloat_FromDouble((double)BMO_SLOT_AS_FLOAT(slot)); + break; + case BMO_OP_SLOT_MAT: + item = Matrix_CreatePyObject((float *)BMO_SLOT_AS_MATRIX(slot), 4, 4, Py_NEW, NULL); + break; + case BMO_OP_SLOT_VEC: + item = Vector_CreatePyObject(BMO_SLOT_AS_VECTOR(slot), slot->len, Py_NEW, NULL); + break; + case BMO_OP_SLOT_PTR: + BLI_assert(0); /* currently we don't have any pointer return values in use */ + item = (Py_INCREF(Py_None), Py_None); + break; + case BMO_OP_SLOT_ELEMENT_BUF: + { + if (slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) { + BMHeader *ele = BMO_slot_buffer_get_single(slot); + item = ele ? BPy_BMElem_CreatePyObject(bm, ele) : (Py_INCREF(Py_None), Py_None); + } + else { + const int size = slot->len; + void **buffer = BMO_SLOT_AS_BUFFER(slot); + int j; + + item = PyList_New(size); + for (j = 0; j < size; j++) { + BMHeader *ele = buffer[j]; + PyList_SET_ITEM(item, j, BPy_BMElem_CreatePyObject(bm, ele)); + } + } + break; + } + case BMO_OP_SLOT_MAPPING: + { + GHash *slot_hash = BMO_SLOT_AS_GHASH(slot); + GHashIterator hash_iter; - /* this will loop over all elements which is a shame but - * we need to know this before alloc */ - /* calls bpy_bmelemseq_length() */ - tot = Py_TYPE(value)->tp_as_sequence->sq_length((PyObject *)self); + switch (slot->slot_subtype.map) { + case BMO_OP_SLOT_SUBTYPE_MAP_ELEM: + { + item = PyDict_New(); + if (slot_hash) { + GHASH_ITER (hash_iter, slot_hash) { + BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); + BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); - BMO_slot_buffer_alloc(&bmop, bmop.slots_in, slot_name, tot); + PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); + PyObject *py_val = BPy_BMElem_CreatePyObject(bm, *(void **)BMO_OP_SLOT_MAPPING_DATA(ele_val)); - i = 0; - BM_ITER_BPY_BM_SEQ (ele, &iter, ((BPy_BMElemSeq *)value)) { - slot->data.buf[i] = ele; - i++; - } - } - /* keep this last */ - else if (PySequence_Check(value)) { - BMElem **elem_array = NULL; - Py_ssize_t elem_array_len; - - elem_array = BPy_BMElem_PySeq_As_Array(&bm, value, 0, PY_SSIZE_T_MAX, - &elem_array_len, (slot->slot_subtype.elem & BM_ALL_NOLOOP), - TRUE, TRUE, slot_name); - - /* error is set above */ - if (elem_array == NULL) { - return NULL; - } + BLI_assert(slot->slot_subtype.elem & ((BPy_BMElem *)py_val)->ele->head.htype); - BMO_slot_buffer_alloc(&bmop, bmop.slots_in, slot_name, elem_array_len); - memcpy(slot->data.buf, elem_array, sizeof(void *) * elem_array_len); - PyMem_FREE(elem_array); + PyDict_SetItem(item, py_key, py_val); + Py_DECREF(py_key); + Py_DECREF(py_val); } - else { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected " - "a bmesh sequence, list, (htype, flag) pair, not %.200s", - self->opname, slot_name, Py_TYPE(value)->tp_name); - return NULL; + } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_FLOAT: + { + item = PyDict_New(); + if (slot_hash) { + GHASH_ITER (hash_iter, slot_hash) { + BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); + BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); + + PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); + PyObject *py_val = PyFloat_FromDouble(*(float *)BMO_OP_SLOT_MAPPING_DATA(ele_val)); + + PyDict_SetItem(item, py_key, py_val); + Py_DECREF(py_key); + Py_DECREF(py_val); } } -#undef BPY_BM_GENERIC_MESH_TEST - break; } - case BMO_OP_SLOT_MAPPING: + case BMO_OP_SLOT_SUBTYPE_MAP_INT: { - /* first check types */ - if (slot->slot_subtype.map != BMO_OP_SLOT_SUBTYPE_MAP_EMPTY) { - if (!PyDict_Check(value)) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected " - "a dict, not %.200s", - self->opname, slot_name, Py_TYPE(value)->tp_name); - return NULL; + item = PyDict_New(); + if (slot_hash) { + GHASH_ITER (hash_iter, slot_hash) { + BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); + BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); + + PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); + PyObject *py_val = PyLong_FromLong(*(int *)BMO_OP_SLOT_MAPPING_DATA(ele_val)); + + PyDict_SetItem(item, py_key, py_val); + Py_DECREF(py_key); + Py_DECREF(py_val); } } - else { - if (!PySet_Check(value)) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected " - "a set, not %.200s", - self->opname, slot_name, Py_TYPE(value)->tp_name); - return NULL; + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_BOOL: + { + item = PyDict_New(); + if (slot_hash) { + GHASH_ITER (hash_iter, slot_hash) { + BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); + BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); + + PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); + PyObject *py_val = PyBool_FromLong(*(int *)BMO_OP_SLOT_MAPPING_DATA(ele_val)); + + PyDict_SetItem(item, py_key, py_val); + Py_DECREF(py_key); + Py_DECREF(py_val); } } + break; + } + case BMO_OP_SLOT_SUBTYPE_MAP_EMPTY: + { + item = PySet_New(NULL); + if (slot_hash) { + GHASH_ITER (hash_iter, slot_hash) { + BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); - switch (slot->slot_subtype.map) { + PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); - /* this could be a static function */ -#define BPY_BM_MAPPING_KEY_CHECK(arg_key) \ - if (!BPy_BMElem_Check(arg_key)) { \ - PyErr_Format(PyExc_TypeError, \ - "%.200s: keyword \"%.200s\" expected " \ - "a dict with bmesh element keys, not %.200s", \ - self->opname, slot_name, Py_TYPE(arg_key)->tp_name); \ - return NULL; \ - } \ - else if (((BPy_BMGeneric *)arg_key)->bm == NULL) { \ - PyErr_Format(PyExc_TypeError, \ - "%.200s: keyword \"%.200s\" invalidated element key in dict", \ - self->opname, slot_name); \ - return NULL; \ - } (void)0 - - - case BMO_OP_SLOT_SUBTYPE_MAP_ELEM: - { - if (PyDict_Size(value) > 0) { - PyObject *arg_key, *arg_value; - Py_ssize_t arg_pos = 0; - while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { - /* TODO, check the elements come from the right mesh? */ - BPY_BM_MAPPING_KEY_CHECK(arg_key); - - if (!BPy_BMElem_Check(arg_value)) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected " - "a dict with bmesh element values, not %.200s", - self->opname, slot_name, Py_TYPE(arg_value)->tp_name); - return NULL; - } - else if (((BPy_BMGeneric *)arg_value)->bm == NULL) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" invalidated element value in dict", - self->opname, slot_name); - return NULL; - } - - BMO_slot_map_elem_insert(&bmop, slot, - ((BPy_BMElem *)arg_key)->ele, ((BPy_BMElem *)arg_value)->ele); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_FLOAT: - { - if (PyDict_Size(value) > 0) { - PyObject *arg_key, *arg_value; - Py_ssize_t arg_pos = 0; - while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { - float value_f; - /* TODO, check the elements come from the right mesh? */ - BPY_BM_MAPPING_KEY_CHECK(arg_key); - value_f = PyFloat_AsDouble(arg_value); - - if (value_f == -1.0f && PyErr_Occurred()) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected " - "a dict with float values, not %.200s", - self->opname, slot_name, Py_TYPE(arg_value)->tp_name); - return NULL; - } - - BMO_slot_map_float_insert(&bmop, slot, - ((BPy_BMElem *)arg_key)->ele, value_f); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_INT: - { - if (PyDict_Size(value) > 0) { - PyObject *arg_key, *arg_value; - Py_ssize_t arg_pos = 0; - while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { - int value_i; - /* TODO, check the elements come from the right mesh? */ - BPY_BM_MAPPING_KEY_CHECK(arg_key); - value_i = PyLong_AsLong(arg_value); - - if (value_i == -1 && PyErr_Occurred()) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected " - "a dict with int values, not %.200s", - self->opname, slot_name, Py_TYPE(arg_value)->tp_name); - return NULL; - } - - BMO_slot_map_int_insert(&bmop, slot, - ((BPy_BMElem *)arg_key)->ele, value_i); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_BOOL: - { - if (PyDict_Size(value) > 0) { - PyObject *arg_key, *arg_value; - Py_ssize_t arg_pos = 0; - while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { - int value_i; - /* TODO, check the elements come from the right mesh? */ - BPY_BM_MAPPING_KEY_CHECK(arg_key); - value_i = PyLong_AsLong(arg_value); - - if (value_i == -1 && PyErr_Occurred()) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected " - "a dict with bool values, not %.200s", - self->opname, slot_name, Py_TYPE(arg_value)->tp_name); - return NULL; - } - - BMO_slot_map_bool_insert(&bmop, slot, - ((BPy_BMElem *)arg_key)->ele, value_i != 0); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_EMPTY: - { - if (PySet_Size(value) > 0) { - PyObject *arg_key; - Py_ssize_t arg_pos = 0; - Py_ssize_t arg_hash = 0; - while (_PySet_NextEntry(value, &arg_pos, &arg_key, &arg_hash)) { - /* TODO, check the elements come from the right mesh? */ - BPY_BM_MAPPING_KEY_CHECK(arg_key); - - BMO_slot_map_empty_insert(&bmop, slot, - ((BPy_BMElem *)arg_key)->ele); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL: - { - /* can't convert from these */ - PyErr_Format(PyExc_NotImplementedError, - "This arguments mapping subtype %d is not supported", slot->slot_subtype); - break; - } -#undef BPY_BM_MAPPING_KEY_CHECK + PySet_Add(item, py_key); + Py_DECREF(py_key); + } } + break; } - default: - /* TODO --- many others */ - PyErr_Format(PyExc_NotImplementedError, - "%.200s: keyword \"%.200s\" type %d not working yet!", - self->opname, slot_name, slot->slot_type); - return NULL; + case BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL: + /* can't convert from these */ + item = (Py_INCREF(Py_None), Py_None); break; } + break; + } + } + BLI_assert(item != NULL); + + return item; +} + +/** + * This is the __call__ for bmesh.ops.xxx() + */ +PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw) +{ + PyObject *ret; + BPy_BMesh *py_bm; + BMesh *bm; + + BMOperator bmop; + + if ((PyTuple_GET_SIZE(args) == 1) && + (py_bm = (BPy_BMesh *)PyTuple_GET_ITEM(args, 0)) && + (BPy_BMesh_Check(py_bm)) + ) + { + BPY_BM_CHECK_OBJ(py_bm); + bm = py_bm->bm; + } + else { + PyErr_SetString(PyExc_TypeError, + "calling a bmesh operator expects a single BMesh (non keyword) " + "as the first argument"); + return NULL; + } + + /* TODO - error check this!, though we do the error check on attribute access */ + /* TODO - make flags optional */ + BMO_op_init(bm, &bmop, BMO_FLAG_DEFAULTS, self->opname); + + if (kw && PyDict_Size(kw) > 0) { + /* setup properties, see bpy_rna.c: pyrna_py_to_prop() + * which shares this logic for parsing properties */ + + PyObject *key, *value; + Py_ssize_t pos = 0; + while (PyDict_Next(kw, &pos, &key, &value)) { + const char *slot_name = _PyUnicode_AsString(key); + BMOpSlot *slot = BMO_slot_get(bmop.slots_in, slot_name); + + if (slot == NULL) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" is invalid for this operator", + self->opname, slot_name); + return NULL; + } + + /* now assign the value */ + if (bpy_slot_from_py(bm, &bmop, slot, value, + self->opname, slot_name) == -1) + { + return NULL; + } } } @@ -518,153 +692,10 @@ PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw) // BMOpDefine *op_def = opdefines[bmop.type]; // BMOSlotType *slot_type = op_def->slot_types_out[i]; BMOpSlot *slot = &bmop.slots_out[i]; - PyObject *item = NULL; + PyObject *item; - /* keep switch in same order as above */ - switch (slot->slot_type) { - case BMO_OP_SLOT_BOOL: - item = PyBool_FromLong((BMO_SLOT_AS_BOOL(slot))); - break; - case BMO_OP_SLOT_INT: - item = PyLong_FromLong(BMO_SLOT_AS_INT(slot)); - break; - case BMO_OP_SLOT_FLT: - item = PyFloat_FromDouble((double)BMO_SLOT_AS_FLOAT(slot)); - break; - case BMO_OP_SLOT_MAT: - item = Matrix_CreatePyObject((float *)BMO_SLOT_AS_MATRIX(slot), 4, 4, Py_NEW, NULL); - break; - case BMO_OP_SLOT_VEC: - item = Vector_CreatePyObject(BMO_SLOT_AS_VECTOR(slot), slot->len, Py_NEW, NULL); - break; - case BMO_OP_SLOT_PTR: - BLI_assert(0); /* currently we don't have any pointer return values in use */ - item = (Py_INCREF(Py_None), Py_None); - break; - case BMO_OP_SLOT_ELEMENT_BUF: - { - if (slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) { - BMHeader *ele = BMO_slot_buffer_get_single(slot); - item = ele ? BPy_BMElem_CreatePyObject(bm, ele) : (Py_INCREF(Py_None), Py_None); - } - else { - const int size = slot->len; - void **buffer = BMO_SLOT_AS_BUFFER(slot); - int j; - - item = PyList_New(size); - for (j = 0; j < size; j++) { - BMHeader *ele = buffer[i]; - PyList_SET_ITEM(item, j, BPy_BMElem_CreatePyObject(bm, ele)); - } - } - break; - } - case BMO_OP_SLOT_MAPPING: - { - GHash *slot_hash = BMO_SLOT_AS_GHASH(slot); - GHashIterator hash_iter; - - switch (slot->slot_subtype.map) { - case BMO_OP_SLOT_SUBTYPE_MAP_ELEM: - { - item = PyDict_New(); - if (slot_hash) { - GHASH_ITER (hash_iter, slot_hash) { - BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); - BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); - - PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); - PyObject *py_val = BPy_BMElem_CreatePyObject(bm, *(void **)BMO_OP_SLOT_MAPPING_DATA(ele_val)); - - BLI_assert(slot->slot_subtype.elem & ((BPy_BMElem *)py_val)->ele->head.htype); - - PyDict_SetItem(ret, py_key, py_val); - Py_DECREF(py_key); - Py_DECREF(py_val); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_FLOAT: - { - item = PyDict_New(); - if (slot_hash) { - GHASH_ITER (hash_iter, slot_hash) { - BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); - BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); - - PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); - PyObject *py_val = PyFloat_FromDouble(*(float *)BMO_OP_SLOT_MAPPING_DATA(ele_val)); - - PyDict_SetItem(ret, py_key, py_val); - Py_DECREF(py_key); - Py_DECREF(py_val); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_INT: - { - item = PyDict_New(); - if (slot_hash) { - GHASH_ITER (hash_iter, slot_hash) { - BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); - BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); - - PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); - PyObject *py_val = PyLong_FromLong(*(int *)BMO_OP_SLOT_MAPPING_DATA(ele_val)); - - PyDict_SetItem(ret, py_key, py_val); - Py_DECREF(py_key); - Py_DECREF(py_val); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_BOOL: - { - item = PyDict_New(); - if (slot_hash) { - GHASH_ITER (hash_iter, slot_hash) { - BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); - BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter); - - PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); - PyObject *py_val = PyBool_FromLong(*(int *)BMO_OP_SLOT_MAPPING_DATA(ele_val)); - - PyDict_SetItem(ret, py_key, py_val); - Py_DECREF(py_key); - Py_DECREF(py_val); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_EMPTY: - { - item = PySet_New(NULL); - if (slot_hash) { - GHASH_ITER (hash_iter, slot_hash) { - BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter); - - PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); - - PySet_Add(item, py_key); - - Py_DECREF(py_key); - } - } - break; - } - case BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL: - /* can't convert from these */ - item = (Py_INCREF(Py_None), Py_None); - break; - } - break; - } - } - BLI_assert(item != NULL); + /* this function doesn't throw exceptions */ + item = bpy_slot_to_py(bm, slot); if (item == NULL) { item = (Py_INCREF(Py_None), Py_None); } -- cgit v1.2.3 From eda56398afd140b02038991888c458c57923e6b9 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 27 Nov 2012 15:10:22 +0000 Subject: Camera Tracking: fixed camera solve operator not updating scene camera Was own regression caused by fix of crash when non-camera object is used as scene camera. --- source/blender/editors/space_clip/tracking_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index d97b112e95d..a29524de36d 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -1409,7 +1409,7 @@ static void solve_camera_freejob(void *scv) id_us_plus(&clip->id); /* set blender camera focal length so result would look fine there */ - if (scene->camera && GS(scene->camera->id.name) == ID_CA) { + if (scene->camera && scene->camera->data && GS(((ID *) scene->camera->data)->name) == ID_CA) { Camera *camera = (Camera *)scene->camera->data; int width, height; -- cgit v1.2.3 From 21db9ac0f49dc23ed300db8133f2467e6f88767d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 Nov 2012 15:26:10 +0000 Subject: replace and exception macro's for static functions and fix some bad assumptions. --- source/blender/python/bmesh/bmesh_py_ops_call.c | 230 +++++++++++++++--------- 1 file changed, 144 insertions(+), 86 deletions(-) diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c index 222ceadbc3d..13dc2eef3ce 100644 --- a/source/blender/python/bmesh/bmesh_py_ops_call.c +++ b/source/blender/python/bmesh/bmesh_py_ops_call.c @@ -59,6 +59,84 @@ static int bpy_bm_op_as_py_error(BMesh *bm) return 0; } +/** + * \brief Utility function to check BMVert/BMEdge/BMFace's + * + * \param value + * \param bm Check the \a value against this. + * \param htype Test \a value matches this type. + * \param descr Description text. + */ +static int bpy_slot_from_py_elem_check(BPy_BMElem *value, BMesh *bm, const char htype, + /* for error messages */ + const char *opname, const char *slot_name, const char *descr) +{ + if (!BPy_BMElem_Check(value) || + !(value->ele->head.htype & htype)) + { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" %.200s, expected a %.200s not *.200s", + opname, slot_name, descr, + BPy_BMElem_StringFromHType(htype), + Py_TYPE(value)->tp_name); + return -1; + } + else if (value->bm == NULL) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" %.200s invalidated element", + opname, slot_name, descr); + return -1; + } + else if (value->bm != bm) { /* we may want to make this check optional by setting 'bm' to NULL */ + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" %.200s invalidated element", + opname, slot_name, descr); + return -1; + } + return 0; +} + +/** + * \brief Utility function to check BMVertSeq/BMEdgeSeq/BMFaceSeq's + * + * \param value Caller must check its a BMeshSeq + * \param bm Check the \a value against this. + * \param htype_py The type(s) of \a value. + * \param htype_bmo The type(s) supported by the target slot. + * \param descr Description text. + */ +static int bpy_slot_from_py_elemseq_check(BPy_BMGeneric *value, BMesh *bm, + const char htype_py, const char htype_bmo, + /* for error messages */ + const char *opname, const char *slot_name, const char *descr) +{ + if (value->bm == NULL) { + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" %.200s, invalidated sequence", + opname, slot_name, descr); + return -1; + } + else if (value->bm != bm) { /* we may want to make this check optional by setting 'bm' to NULL */ + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" %.200s, invalidated sequence", + opname, slot_name, descr); + return -1; + } + else if ((htype_py & htype_bmo) == 0) { + char str_bmo[32]; + char str_py[32]; + PyErr_Format(PyExc_TypeError, + "%.200s: keyword \"%.200s\" %.200s, expected " + "a sequence of %.200s not %.200s", + opname, slot_name, descr, + BPy_BMElem_StringFromHType_ex(htype_bmo, str_bmo), + BPy_BMElem_StringFromHType_ex(htype_py, str_py)); + return -1; + } + + return 0; +} + /** * Use for giving py args to an operator. */ @@ -158,21 +236,10 @@ static int bpy_slot_from_py(BMesh *bm, BMOperator *bmop, BMOpSlot *slot, PyObjec case BMO_OP_SLOT_ELEMENT_BUF: { if (slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) { - if (!BPy_BMElem_Check(value) || - !(((BPy_BMElem *)value)->ele->head.htype & slot->slot_subtype.elem)) + if (bpy_slot_from_py_elem_check((BPy_BMElem *)value, bm, (slot->slot_subtype.elem & BM_ALL_NOLOOP), + opname, slot_name, "single element") == -1) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected a %.200s not *.200s", - opname, slot_name, - BPy_BMElem_StringFromHType(slot->slot_subtype.elem & BM_ALL_NOLOOP), - Py_TYPE(value)->tp_name); - return -1; - } - else if (((BPy_BMElem *)value)->bm == NULL) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" invalidated element", - opname, slot_name); - return -1; + return -1; /* error is set in bpy_slot_from_py_elem_check() */ } BMO_slot_buffer_from_single(bmop, slot, &((BPy_BMElem *)value)->ele->head); @@ -188,55 +255,54 @@ static int bpy_slot_from_py(BMesh *bm, BMOperator *bmop, BMOpSlot *slot, PyObjec * ('VERT', {'TAG'}) */ -#define BPY_BM_GENERIC_MESH_TEST(type_string) \ -if (((BPy_BMGeneric *)value)->bm != bm) { \ - PyErr_Format(PyExc_NotImplementedError, \ - "%.200s: keyword \"%.200s\" " type_string " are from another bmesh", \ - opname, slot_name, slot->slot_type); \ - return -1; \ - } (void)0 - -#define BPY_BM_ELEM_TYPE_TEST(type_string) \ - if ((slot->slot_subtype.elem & BM_VERT) == 0) { \ - PyErr_Format(PyExc_TypeError, \ - "%.200s: keyword \"%.200s\" expected " \ - "a list of %.200s not " type_string, \ - opname, slot_name, \ - BPy_BMElem_StringFromHType(slot->slot_subtype.elem & BM_ALL_NOLOOP)); \ - return -1; \ - } (void)0 - if (BPy_BMVertSeq_Check(value)) { - BPY_BM_GENERIC_MESH_TEST("verts"); - BPY_BM_ELEM_TYPE_TEST("verts"); + if (bpy_slot_from_py_elemseq_check((BPy_BMGeneric *)value, bm, + BM_VERT, (slot->slot_subtype.elem & BM_ALL_NOLOOP), + opname, slot_name, "element buffer") == -1) + { + return -1; /* error is set in bpy_slot_from_py_elem_check() */ + } BMO_slot_buffer_from_all(bm, bmop, bmop->slots_in, slot_name, BM_VERT); } else if (BPy_BMEdgeSeq_Check(value)) { - BPY_BM_GENERIC_MESH_TEST("edges"); - BPY_BM_ELEM_TYPE_TEST("edges"); + if (bpy_slot_from_py_elemseq_check((BPy_BMGeneric *)value, bm, + BM_EDGE, (slot->slot_subtype.elem & BM_ALL_NOLOOP), + opname, slot_name, "element buffer") == -1) + { + return -1; /* error is set in bpy_slot_from_py_elem_check() */ + } + BMO_slot_buffer_from_all(bm, bmop, bmop->slots_in, slot_name, BM_EDGE); } else if (BPy_BMFaceSeq_Check(value)) { - BPY_BM_GENERIC_MESH_TEST("faces"); - BPY_BM_ELEM_TYPE_TEST("faces"); + if (bpy_slot_from_py_elemseq_check((BPy_BMGeneric *)value, bm, + BM_FACE, (slot->slot_subtype.elem & BM_ALL_NOLOOP), + opname, slot_name, "element buffer") == -1) + { + return -1; /* error is set in bpy_slot_from_py_elem_check() */ + } BMO_slot_buffer_from_all(bm, bmop, bmop->slots_in, slot_name, BM_FACE); } -#undef BPY_BM_ELEM_TYPE_TEST - else if (BPy_BMElemSeq_Check(value)) { BMIter iter; BMHeader *ele; int tot; unsigned int i; - BPY_BM_GENERIC_MESH_TEST("elements"); + if (bpy_slot_from_py_elemseq_check((BPy_BMGeneric *)value, bm, + bm_iter_itype_htype_map[((BPy_BMElemSeq *)value)->itype], + (slot->slot_subtype.elem & BM_ALL_NOLOOP), + opname, slot_name, "element buffer") == -1) + { + return -1; /* error is set in bpy_slot_from_py_elem_check() */ + } /* this will loop over all elements which is a shame but * we need to know this before alloc */ /* calls bpy_bmelemseq_length() */ - tot = Py_TYPE(value)->tp_as_sequence->sq_length((PyObject *)value); + tot = Py_TYPE(value)->tp_as_sequence->sq_length(value); BMO_slot_buffer_alloc(bmop, bmop->slots_in, slot_name, tot); @@ -272,8 +338,6 @@ if (((BPy_BMGeneric *)value)->bm != bm) { return -1; } } -#undef BPY_BM_GENERIC_MESH_TEST - break; } case BMO_OP_SLOT_MAPPING: @@ -299,45 +363,22 @@ if (((BPy_BMGeneric *)value)->bm != bm) { } switch (slot->slot_subtype.map) { - - /* this could be a static function */ -#define BPY_BM_MAPPING_KEY_CHECK(arg_key) \ - if (!BPy_BMElem_Check(arg_key)) { \ - PyErr_Format(PyExc_TypeError, \ - "%.200s: keyword \"%.200s\" expected " \ - "a dict with bmesh element keys, not %.200s", \ - opname, slot_name, Py_TYPE(arg_key)->tp_name); \ - return -1; \ - } \ - else if (((BPy_BMGeneric *)arg_key)->bm == NULL) { \ - PyErr_Format(PyExc_TypeError, \ - "%.200s: keyword \"%.200s\" invalidated element key in dict", \ - opname, slot_name); \ - return -1; \ - } (void)0 - - case BMO_OP_SLOT_SUBTYPE_MAP_ELEM: { if (PyDict_Size(value) > 0) { PyObject *arg_key, *arg_value; Py_ssize_t arg_pos = 0; while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { - /* TODO, check the elements come from the right mesh? */ - BPY_BM_MAPPING_KEY_CHECK(arg_key); - - if (!BPy_BMElem_Check(arg_value)) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected " - "a dict with bmesh element values, not %.200s", - opname, slot_name, Py_TYPE(arg_value)->tp_name); - return -1; + if (bpy_slot_from_py_elem_check((BPy_BMElem *)arg_key, bm, BM_ALL_NOLOOP, + opname, slot_name, "invalid key in dict") == -1) + { + return -1; /* error is set in bpy_slot_from_py_elem_check() */ } - else if (((BPy_BMGeneric *)arg_value)->bm == NULL) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" invalidated element value in dict", - opname, slot_name); - return -1; + + if (bpy_slot_from_py_elem_check((BPy_BMElem *)arg_value, bm, BM_ALL_NOLOOP, + opname, slot_name, "invalid value in dict") == -1) + { + return -1; /* error is set in bpy_slot_from_py_elem_check() */ } BMO_slot_map_elem_insert(bmop, slot, @@ -353,8 +394,13 @@ if (((BPy_BMGeneric *)value)->bm != bm) { Py_ssize_t arg_pos = 0; while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { float value_f; - /* TODO, check the elements come from the right mesh? */ - BPY_BM_MAPPING_KEY_CHECK(arg_key); + + if (bpy_slot_from_py_elem_check((BPy_BMElem *)arg_key, bm, BM_ALL_NOLOOP, + opname, slot_name, "invalid key in dict") == -1) + { + return -1; /* error is set in bpy_slot_from_py_elem_check() */ + } + value_f = PyFloat_AsDouble(arg_value); if (value_f == -1.0f && PyErr_Occurred()) { @@ -378,8 +424,13 @@ if (((BPy_BMGeneric *)value)->bm != bm) { Py_ssize_t arg_pos = 0; while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { int value_i; - /* TODO, check the elements come from the right mesh? */ - BPY_BM_MAPPING_KEY_CHECK(arg_key); + + if (bpy_slot_from_py_elem_check((BPy_BMElem *)arg_key, bm, BM_ALL_NOLOOP, + opname, slot_name, "invalid key in dict") == -1) + { + return -1; /* error is set in bpy_slot_from_py_elem_check() */ + } + value_i = PyLong_AsLong(arg_value); if (value_i == -1 && PyErr_Occurred()) { @@ -403,8 +454,13 @@ if (((BPy_BMGeneric *)value)->bm != bm) { Py_ssize_t arg_pos = 0; while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) { int value_i; - /* TODO, check the elements come from the right mesh? */ - BPY_BM_MAPPING_KEY_CHECK(arg_key); + + if (bpy_slot_from_py_elem_check((BPy_BMElem *)arg_key, bm, BM_ALL_NOLOOP, + opname, slot_name, "invalid key in dict") == -1) + { + return -1; /* error is set in bpy_slot_from_py_elem_check() */ + } + value_i = PyLong_AsLong(arg_value); if (value_i == -1 && PyErr_Occurred()) { @@ -428,8 +484,12 @@ if (((BPy_BMGeneric *)value)->bm != bm) { Py_ssize_t arg_pos = 0; Py_ssize_t arg_hash = 0; while (_PySet_NextEntry(value, &arg_pos, &arg_key, &arg_hash)) { - /* TODO, check the elements come from the right mesh? */ - BPY_BM_MAPPING_KEY_CHECK(arg_key); + + if (bpy_slot_from_py_elem_check((BPy_BMElem *)arg_key, bm, BM_ALL_NOLOOP, + opname, slot_name, "invalid key in set") == -1) + { + return -1; /* error is set in bpy_slot_from_py_elem_check() */ + } BMO_slot_map_empty_insert(bmop, slot, ((BPy_BMElem *)arg_key)->ele); @@ -444,8 +504,6 @@ if (((BPy_BMGeneric *)value)->bm != bm) { "This arguments mapping subtype %d is not supported", slot->slot_subtype); return -1; } -#undef BPY_BM_MAPPING_KEY_CHECK - } } default: -- cgit v1.2.3 From 2b080dbc4ee17d3562e74637d23d12e429e8c309 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 27 Nov 2012 16:02:03 +0000 Subject: Fix part of #32248: transform with a size limit constraint did not preserve negative scale. --- source/blender/editors/transform/transform.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 7fbfe8fc719..6145fec7e51 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2427,6 +2427,8 @@ static void constraintSizeLim(TransInfo *t, TransData *td) bConstraintTypeInfo *cti = get_constraint_typeinfo(CONSTRAINT_TYPE_SIZELIMIT); bConstraintOb cob = {NULL}; bConstraint *con; + float size_sign[3], size_abs[3]; + int i; /* Make a temporary bConstraintOb for using these limit constraints * - they only care that cob->matrix is correctly set ;-) @@ -2440,8 +2442,14 @@ static void constraintSizeLim(TransInfo *t, TransData *td) /* Reset val if SINGLESIZE but using a constraint */ if (td->flag & TD_SINGLESIZE) return; + + /* separate out sign to apply back later */ + for (i = 0; i < 3; i++) { + size_sign[i] = signf(td->ext->size[i]); + size_abs[i] = fabsf(td->ext->size[i]); + } - size_to_mat4(cob.matrix, td->ext->size); + size_to_mat4(cob.matrix, size_abs); } /* Evaluate valid constraints */ @@ -2489,7 +2497,9 @@ static void constraintSizeLim(TransInfo *t, TransData *td) if (td->flag & TD_SINGLESIZE) return; + /* extrace scale from matrix and apply back sign */ mat4_to_size(td->ext->size, cob.matrix); + mul_v3_v3(td->ext->size, size_sign); } } } -- cgit v1.2.3 From 5f8fded63943fd593f81203956968b97ec27c52c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 27 Nov 2012 16:02:12 +0000 Subject: Fix cycles OSL shader loading warnings after recent bugfix. --- intern/cycles/render/osl.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index c5ecddcfc15..c1d2eade5e5 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -351,6 +351,9 @@ bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input) { /* exception for output node, only one input is actually used * depending on the current shader type */ + + if(!(input->usage & ShaderInput::USE_OSL)) + return true; if(node->name == ustring("output")) { if(strcmp(input->name, "Surface") == 0 && current_type != SHADER_TYPE_SURFACE) -- cgit v1.2.3 From b43c022373a58b5d7214c526e2b474f01b40d692 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 27 Nov 2012 16:02:15 +0000 Subject: Move to layer: remove the OK button and make it apply immediately like it did before, is much nicer workflow. Now only if global undo is disabled will the OK button show. This is also a more generic fix for #26891 that solves other operators that were also broken with global undo disabled. --- source/blender/editors/object/object_relations.c | 4 ++-- source/blender/windowmanager/intern/wm_operators.c | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 6c3155deb17..f886b52e2ce 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1225,7 +1225,7 @@ static unsigned int move_to_layer_init(bContext *C, wmOperator *op) return lay; } -static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *event) { View3D *v3d = CTX_wm_view3d(C); if (v3d && v3d->localvd) { @@ -1233,7 +1233,7 @@ static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(eve } else { move_to_layer_init(C, op); - return WM_operator_props_dialog_popup(C, op, 260, 30); + return WM_operator_props_popup(C, op, event); } } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 027c883c01f..c64cb339445 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1207,13 +1207,17 @@ int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height) * \note operator menu needs undo flag enabled , for redo callback */ static int wm_operator_props_popup_ex(bContext *C, wmOperator *op, const int do_call) { - if ((op->type->flag & OPTYPE_REGISTER) == 0) { BKE_reportf(op->reports, RPT_ERROR, "Operator '%s' does not have register enabled, incorrect invoke function", op->type->idname); return OPERATOR_CANCELLED; } + /* if we don't have global undo, we can't do undo push for automatic redo, + * so we require manual OK clicking in this popup */ + if(!(U.uiflag & USER_GLOBALUNDO)) + return WM_operator_props_dialog_popup(C, op, 300, UI_UNIT_Y); + ED_undo_push_op(C, op); wm_operator_register(C, op); -- cgit v1.2.3 From 2dbbcb4c731fd38d8991ee150021253f28936b2e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 Nov 2012 16:19:52 +0000 Subject: add osl shader scripts to bpath walker (so making paths absolute or relative applies to shader paths too). also remove "RNA_types.h" include from BKE_nodes.h. --- source/blender/blenkernel/BKE_node.h | 4 +- source/blender/blenlib/intern/bpath.c | 122 +++++++++++++++++++++------------- 2 files changed, 78 insertions(+), 48 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 65610b5c989..515bb37b249 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -34,8 +34,6 @@ #include "DNA_listBase.h" -#include "RNA_types.h" - /* not very important, but the stack solver likes to know a maximum */ #define MAX_SOCKET 64 @@ -82,7 +80,7 @@ typedef struct bNodeSocketTemplate { char name[64]; /* MAX_NAME */ float val1, val2, val3, val4; /* default alloc value for inputs */ float min, max; - PropertySubType subtype; + int subtype; /* would use PropertySubType but this is a bad level include to use RNA */ int flag; /* after this line is used internal only */ diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c index be9f5f97a6e..b1da53ace30 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenlib/intern/bpath.c @@ -64,6 +64,8 @@ #include "DNA_sequence_types.h" #include "DNA_sound_types.h" #include "DNA_text_types.h" +#include "DNA_material_types.h" +#include "DNA_node_types.h" #include "DNA_texture_types.h" #include "DNA_vfont_types.h" #include "DNA_scene_types.h" @@ -76,6 +78,7 @@ #include "BKE_font.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_node.h" #include "BKE_report.h" #include "BKE_sequencer.h" #include "BKE_image.h" /* so we can check the image's type */ @@ -382,7 +385,6 @@ static int rewrite_path_alloc(char **path, BPathVisitor visit_cb, const char *ab /* Run visitor function 'visit' on all paths contained in 'id'. */ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int flag, void *bpath_user_data) { - Image *ima; const char *absbase = (flag & BLI_BPATH_TRAVERSE_ABS) ? ID_BLEND_PATH(bmain, id) : NULL; if ((flag & BLI_BPATH_TRAVERSE_SKIP_LIBRARY) && id->lib) { @@ -391,6 +393,8 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int switch (GS(id->name)) { case ID_IM: + { + Image *ima; ima = (Image *)id; if (ima->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) { if (ELEM3(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { @@ -398,15 +402,20 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int } } break; + } case ID_BR: { Brush *brush = (Brush *)id; if (brush->icon_filepath[0]) { rewrite_path_fixed(brush->icon_filepath, visit_cb, absbase, bpath_user_data); } + break; } - break; case ID_OB: + { + Object *ob = (Object *)id; + ModifierData *md; + ParticleSystem *psys; #define BPATH_TRAVERSE_POINTCACHE(ptcaches) \ { \ @@ -421,62 +430,56 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int } \ } (void)0 - - { - Object *ob = (Object *)id; - ModifierData *md; - ParticleSystem *psys; - - /* do via modifiers instead */ + /* do via modifiers instead */ #if 0 - if (ob->fluidsimSettings) { - rewrite_path_fixed(ob->fluidsimSettings->surfdataPath, visit_cb, absbase, bpath_user_data); - } + if (ob->fluidsimSettings) { + rewrite_path_fixed(ob->fluidsimSettings->surfdataPath, visit_cb, absbase, bpath_user_data); + } #endif - for (md = ob->modifiers.first; md; md = md->next) { - if (md->type == eModifierType_Fluidsim) { - FluidsimModifierData *fluidmd = (FluidsimModifierData *)md; - if (fluidmd->fss) { - rewrite_path_fixed(fluidmd->fss->surfdataPath, visit_cb, absbase, bpath_user_data); - } - } - else if (md->type == eModifierType_Smoke) { - SmokeModifierData *smd = (SmokeModifierData *)md; - if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { - BPATH_TRAVERSE_POINTCACHE(smd->domain->ptcaches[0]); - } - } - else if (md->type == eModifierType_Cloth) { - ClothModifierData *clmd = (ClothModifierData *) md; - BPATH_TRAVERSE_POINTCACHE(clmd->ptcaches); + for (md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Fluidsim) { + FluidsimModifierData *fluidmd = (FluidsimModifierData *)md; + if (fluidmd->fss) { + rewrite_path_fixed(fluidmd->fss->surfdataPath, visit_cb, absbase, bpath_user_data); } - else if (md->type == eModifierType_Ocean) { - OceanModifierData *omd = (OceanModifierData *) md; - rewrite_path_fixed(omd->cachepath, visit_cb, absbase, bpath_user_data); + } + else if (md->type == eModifierType_Smoke) { + SmokeModifierData *smd = (SmokeModifierData *)md; + if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { + BPATH_TRAVERSE_POINTCACHE(smd->domain->ptcaches[0]); } } - - if (ob->soft) { - BPATH_TRAVERSE_POINTCACHE(ob->soft->ptcaches); + else if (md->type == eModifierType_Cloth) { + ClothModifierData *clmd = (ClothModifierData *) md; + BPATH_TRAVERSE_POINTCACHE(clmd->ptcaches); } - - for (psys = ob->particlesystem.first; psys; psys = psys->next) { - BPATH_TRAVERSE_POINTCACHE(psys->ptcaches); + else if (md->type == eModifierType_Ocean) { + OceanModifierData *omd = (OceanModifierData *) md; + rewrite_path_fixed(omd->cachepath, visit_cb, absbase, bpath_user_data); } } + if (ob->soft) { + BPATH_TRAVERSE_POINTCACHE(ob->soft->ptcaches); + } + + for (psys = ob->particlesystem.first; psys; psys = psys->next) { + BPATH_TRAVERSE_POINTCACHE(psys->ptcaches); + } + #undef BPATH_TRAVERSE_POINTCACHE break; + } case ID_SO: { bSound *sound = (bSound *)id; if (sound->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) { rewrite_path_fixed(sound->name, visit_cb, absbase, bpath_user_data); } + break; } - break; case ID_TXT: if (((Text *)id)->name) { rewrite_path_alloc(&((Text *)id)->name, visit_cb, absbase, bpath_user_data); @@ -490,17 +493,46 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int rewrite_path_fixed(((VFont *)id)->name, visit_cb, absbase, bpath_user_data); } } + break; + } + case ID_MA: + { + Material *ma = (Material *)id; + bNodeTree *ntree = ma->nodetree; + bNode *node; + + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == SH_NODE_SCRIPT) { + NodeShaderScript *nss = (NodeShaderScript *)node->storage; + rewrite_path_fixed(nss->filepath, visit_cb, absbase, bpath_user_data); + } + } + break; + } + case ID_NT: + { + bNodeTree *ntree = (bNodeTree *)id; + bNode *node; + + if (ntree->type == NTREE_SHADER) { + /* same as lines above */ + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == SH_NODE_SCRIPT) { + NodeShaderScript *nss = (NodeShaderScript *)node->storage; + rewrite_path_fixed(nss->filepath, visit_cb, absbase, bpath_user_data); + } + } + } + break; } - break; case ID_TE: { Tex *tex = (Tex *)id; if (tex->type == TEX_VOXELDATA && TEX_VD_IS_SOURCE_PATH(tex->vd->file_format)) { rewrite_path_fixed(tex->vd->source_path, visit_cb, absbase, bpath_user_data); } + break; } - break; - case ID_SCE: { Scene *scene = (Scene *)id; @@ -539,30 +571,30 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int } SEQ_END } + break; } - break; case ID_ME: { Mesh *me = (Mesh *)id; if (me->ldata.external) { rewrite_path_fixed(me->ldata.external->filename, visit_cb, absbase, bpath_user_data); } + break; } - break; case ID_LI: { Library *lib = (Library *)id; if (rewrite_path_fixed(lib->name, visit_cb, absbase, bpath_user_data)) { BKE_library_filepath_set(lib, lib->name); } + break; } - break; case ID_MC: { MovieClip *clip = (MovieClip *)id; rewrite_path_fixed(clip->name, visit_cb, absbase, bpath_user_data); + break; } - break; default: /* Nothing to do for other IDs that don't contain file paths. */ break; -- cgit v1.2.3 From c0a78307335bf29f8b799402285947ab2d04173f Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Tue, 27 Nov 2012 17:21:58 +0000 Subject: fix crash with path conversion, not all materials have nodes --- source/blender/blenlib/intern/bpath.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c index b1da53ace30..8209ce7e541 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenlib/intern/bpath.c @@ -499,12 +499,15 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int { Material *ma = (Material *)id; bNodeTree *ntree = ma->nodetree; - bNode *node; - for (node = ntree->nodes.first; node; node = node->next) { - if (node->type == SH_NODE_SCRIPT) { - NodeShaderScript *nss = (NodeShaderScript *)node->storage; - rewrite_path_fixed(nss->filepath, visit_cb, absbase, bpath_user_data); + if(ntree) { + bNode *node; + + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == SH_NODE_SCRIPT) { + NodeShaderScript *nss = (NodeShaderScript *)node->storage; + rewrite_path_fixed(nss->filepath, visit_cb, absbase, bpath_user_data); + } } } break; -- cgit v1.2.3 From 5a6d6952185134d4ae66edd01f79bedb5d731a2c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 27 Nov 2012 17:30:46 +0000 Subject: CMake: hide some unnecessary LLVM/OSL/EXR prints. --- CMakeLists.txt | 15 --------------- source/blender/imbuf/intern/openexr/CMakeLists.txt | 2 -- 2 files changed, 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 01bcc131e19..69ddaa189d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -755,7 +755,6 @@ if(UNIX AND NOT APPLE) OUTPUT_STRIP_TRAILING_WHITESPACE) string(REPLACE " " ";" LLVM_LIBRARY ${LLVM_LIBRARY}) endif() - message(STATUS "LLVM library = ${LLVM_LIBRARY}") else() message(FATAL_ERROR "LLVM not found.") endif() @@ -928,8 +927,6 @@ elseif(WIN32) if(WITH_CYCLES_OSL) set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation") - message(STATUS "CYCLES_OSL = ${CYCLES_OSL}") - find_library(OSL_LIB_EXEC NAMES oslexec PATHS ${CYCLES_OSL}/lib) find_library(OSL_LIB_COMP NAMES oslcomp PATHS ${CYCLES_OSL}/lib) find_library(OSL_LIB_QUERY NAMES oslquery PATHS ${CYCLES_OSL}/lib) @@ -939,9 +936,6 @@ elseif(WIN32) if(OSL_INCLUDES AND OSL_LIBRARIES AND OSL_COMPILER) set(OSL_FOUND TRUE) - message(STATUS "OSL includes = ${OSL_INCLUDES}") - message(STATUS "OSL library = ${OSL_LIBRARIES}") - message(STATUS "OSL compiler = ${OSL_COMPILER}") else() message(STATUS "OSL not found") endif() @@ -1613,9 +1607,6 @@ elseif(APPLE) find_library(LLVM_LIBRARY NAMES LLVMAnalysis # first of a whole bunch of libs to get PATHS ${LLVM_LIB_DIR}) - message(STATUS "LLVM version = ${LLVM_VERSION}") - message(STATUS "LLVM dir = ${LLVM_DIRECTORY}") - message(STATUS "LLVM lib dir = ${LLVM_LIB_DIR}") if(LLVM_LIBRARY AND LLVM_DIRECTORY AND LLVM_LIB_DIR) if(LLVM_STATIC) @@ -1627,7 +1618,6 @@ elseif(APPLE) OUTPUT_STRIP_TRAILING_WHITESPACE) string(REPLACE " " ";" LLVM_LIBRARY ${LLVM_LIBRARY}) endif() - message(STATUS "LLVM library = ${LLVM_LIBRARY}") else() message(FATAL_ERROR "LLVM not found.") endif() @@ -1636,8 +1626,6 @@ elseif(APPLE) if(WITH_CYCLES_OSL) set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation") - message(STATUS "CYCLES_OSL = ${CYCLES_OSL}") - find_library(OSL_LIB_EXEC NAMES oslexec PATHS ${CYCLES_OSL}/lib) find_library(OSL_LIB_COMP NAMES oslcomp PATHS ${CYCLES_OSL}/lib) find_library(OSL_LIB_QUERY NAMES oslquery PATHS ${CYCLES_OSL}/lib) @@ -1648,9 +1636,6 @@ elseif(APPLE) if(OSL_INCLUDES AND OSL_LIBRARIES AND OSL_COMPILER) set(OSL_FOUND TRUE) - message(STATUS "OSL includes = ${OSL_INCLUDES}") - message(STATUS "OSL library = ${OSL_LIBRARIES}") - message(STATUS "OSL compiler = ${OSL_COMPILER}") else() message(STATUS "OSL not found") endif() diff --git a/source/blender/imbuf/intern/openexr/CMakeLists.txt b/source/blender/imbuf/intern/openexr/CMakeLists.txt index 6c428afe535..d5cb8e8a3b6 100644 --- a/source/blender/imbuf/intern/openexr/CMakeLists.txt +++ b/source/blender/imbuf/intern/openexr/CMakeLists.txt @@ -52,6 +52,4 @@ if(WITH_IMAGE_OPENEXR) add_definitions(-DWITH_OPENEXR) endif() -message(STATUS "EXR ${INC_SYS}") - blender_add_lib(bf_imbuf_openexr "${SRC}" "${INC}" "${INC_SYS}") -- cgit v1.2.3 From 936fca57c394093bca4e8d8609635c51ebeee49d Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Tue, 27 Nov 2012 17:41:39 +0000 Subject: BGE: Fix for [#33027] "logic.keyboard polling rate extremely low" reported by Josiah Lane (solarlune). The embedded player now treats KM_DBL_CLICK the same as KM_PRESS. --- source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp index f4e325eabb8..19ba46ed6d7 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp @@ -105,7 +105,7 @@ bool KX_BlenderKeyboardDevice::ConvertBlenderEvent(unsigned short incode,short v { int previousTable = 1-m_currentTable; - if (val == KM_PRESS) + if (val == KM_PRESS || val == KM_DBL_CLICK) { if (kxevent == KX_KetsjiEngine::GetExitKey() && val != 0 && !m_hookesc) result = true; -- cgit v1.2.3 From e066601fdd2f10dbb9efb60a12504772e1495b31 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 27 Nov 2012 20:07:12 +0000 Subject: Fix #33324: Auto IK not working after recent changes. iTaSC it seems never worked with Auto IK, now that's fixed too. --- source/blender/editors/transform/CMakeLists.txt | 1 + source/blender/editors/transform/SConscript | 2 +- source/blender/editors/transform/transform_conversions.c | 10 +++++++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt index 05a4f6f4ce5..ec114bc3019 100644 --- a/source/blender/editors/transform/CMakeLists.txt +++ b/source/blender/editors/transform/CMakeLists.txt @@ -25,6 +25,7 @@ set(INC ../../blenlib ../../blenloader ../../bmesh + ../../ikplugin ../../makesdna ../../makesrna ../../windowmanager diff --git a/source/blender/editors/transform/SConscript b/source/blender/editors/transform/SConscript index dbf6179035c..9cf36a2d970 100644 --- a/source/blender/editors/transform/SConscript +++ b/source/blender/editors/transform/SConscript @@ -6,7 +6,7 @@ sources = env.Glob('*.c') incs = '../include ../../blenfont ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' ../../render/extern/include' -incs += ' ../../gpu ../../makesrna ../../blenloader ../../bmesh' +incs += ' ../../gpu ../../makesrna ../../blenloader ../../bmesh ../../ikplugin' defs = [] diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 5b79b69f7ec..1cf01bc1bbc 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -91,6 +91,7 @@ #include "BKE_tracking.h" #include "BKE_mask.h" +#include "BIK_api.h" #include "ED_anim_api.h" #include "ED_armature.h" @@ -773,6 +774,9 @@ static void pose_grab_with_ik_clear(Object *ob) if (con->type == CONSTRAINT_TYPE_KINEMATIC) { data = con->data; if (data->flag & CONSTRAINT_IK_TEMP) { + /* iTaSC needs clear for removed constraints */ + BIK_clear_data(ob->pose); + BLI_remlink(&pchan->constraints, con); MEM_freeN(con->data); MEM_freeN(con); @@ -839,7 +843,7 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan) } else data->flag = CONSTRAINT_IK_TIP; - data->flag |= CONSTRAINT_IK_TEMP | CONSTRAINT_IK_AUTO; + data->flag |= CONSTRAINT_IK_TEMP | CONSTRAINT_IK_AUTO | CONSTRAINT_IK_POS; copy_v3_v3(data->grabtarget, pchan->pose_tail); data->rootbone = 0; /* watch-it! has to be 0 here, since we're still on the same bone for the first time through the loop [#25885] */ @@ -933,6 +937,10 @@ static short pose_grab_with_ik(Object *ob) } } + /* iTaSC needs clear for new IK constraints */ + if(tot_ik) + BIK_clear_data(ob->pose); + return (tot_ik) ? 1 : 0; } -- cgit v1.2.3 From a31cc2aeb7748bbbb51f02490a047633f9b10087 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 27 Nov 2012 20:12:00 +0000 Subject: Fix #33326: outliner numpad minus collapse followed by numpad plus expand did not work. --- source/blender/editors/space_outliner/outliner_edit.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index f7ce48fe7cb..d11a8ed6369 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -836,6 +836,8 @@ static int outliner_one_level_exec(bContext *C, wmOperator *op) void OUTLINER_OT_show_one_level(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Show/Hide One Level"; ot->idname = "OUTLINER_OT_show_one_level"; @@ -848,7 +850,8 @@ void OUTLINER_OT_show_one_level(wmOperatorType *ot) /* no undo or registry, UI option */ /* properties */ - RNA_def_boolean(ot->srna, "open", 1, "Open", "Expand all entries one level deep"); + prop = RNA_def_boolean(ot->srna, "open", 1, "Open", "Expand all entries one level deep"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } /* Show Hierarchy ----------------------------------------------- */ -- cgit v1.2.3 From 390ddd910309ad8274b43439aaaacf7ebbf6b52a Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 27 Nov 2012 21:26:06 +0000 Subject: Fix #33168: collada export added incorrect -material postfix to material names. In the bug report it was also mentioned that special characters should be preserved for names, however the collada 1.4 specification does not allow this. Version 1.5 does, but we are still writing 1.4 files and files with such special characters will then fail to open in some applications. --- source/blender/collada/MaterialExporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/collada/MaterialExporter.cpp b/source/blender/collada/MaterialExporter.cpp index 5a1d8b7602a..4aece997f72 100644 --- a/source/blender/collada/MaterialExporter.cpp +++ b/source/blender/collada/MaterialExporter.cpp @@ -70,7 +70,7 @@ void MaterialsExporter::operator()(Material *ma, Object *ob) { std::string name(id_name(ma)); - openMaterial(get_material_id(ma), get_material_id(ma)); + openMaterial(get_material_id(ma), translate_id(name)); std::string efid = translate_id(name) + "-effect"; addInstanceEffect(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, efid)); -- cgit v1.2.3 From f4c93ae9355be8f5e1b2dbdc5fda0f3bce71d67d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 27 Nov 2012 21:47:55 +0000 Subject: Fix #33328: cycles not rendering dupliframes, needs an exception. --- intern/cycles/blender/blender_object.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index e8fa5c0ff3d..95263ebe463 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -360,8 +360,9 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) bool emitter_hide = false; if(b_dup_ob.is_duplicator()) { - /* duplicators hidden by default */ - emitter_hide = true; + /* duplicators hidden by default, except dupliframes which duplicate self */ + if(b_dup_ob.dupli_type() != BL::Object::dupli_type_FRAMES) + emitter_hide = true; /* check if we should render or hide particle emitter */ BL::Object::particle_systems_iterator b_psys; -- cgit v1.2.3 From 134bbf37913360c3c87649e871145a0984eaf166 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 27 Nov 2012 22:51:28 +0000 Subject: GPU: remove GPU Mipmap Generation option and just always enable it, it's an old OpenGL 1.4 feature that is stable, there's no reason not to use it. Also fixed GPU mipmap generation not working in the game player. --- release/scripts/startup/bl_ui/space_userpref.py | 1 - source/blender/gpu/GPU_draw.h | 2 +- source/blender/gpu/intern/gpu_draw.c | 12 +++--------- source/blender/makesrna/intern/rna_userdef.c | 11 ----------- source/blender/windowmanager/intern/wm_init_exit.c | 2 +- source/gameengine/GamePlayer/ghost/GPG_ghost.cpp | 1 + 6 files changed, 6 insertions(+), 23 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 0bb25e98456..f6eaf421a7a 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -437,7 +437,6 @@ class USERPREF_PT_system(Panel): col.label(text="OpenGL:") col.prop(system, "gl_clip_alpha", slider=True) col.prop(system, "use_mipmaps") - col.prop(system, "use_gpu_mipmap") col.prop(system, "use_16bit_textures") col.label(text="Anisotropic Filtering") col.prop(system, "anisotropic_filter", text="") diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index b26c25558c3..5f6eb45ad70 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -116,7 +116,7 @@ void GPU_set_anisotropic(float value); float GPU_get_anisotropic(void); /* enable gpu mipmapping */ -void GPU_set_gpu_mipmapping(int gpu_mipmap); +void GPU_set_gpu_mipmapping(void); /* Image updates and free * - these deal with images bound as opengl textures */ diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index e3ba4cb1f95..f2ddedcd76c 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -240,16 +240,10 @@ static struct GPUTextureState { /* Mipmap settings */ -void GPU_set_gpu_mipmapping(int gpu_mipmap) +void GPU_set_gpu_mipmapping() { - int old_value = GTS.gpu_mipmap; - - /* only actually enable if it's supported */ - GTS.gpu_mipmap = gpu_mipmap && GLEW_EXT_framebuffer_object; - - if (old_value != GTS.gpu_mipmap) { - GPU_free_images(); - } + /* always enable if it's supported */ + GTS.gpu_mipmap = GLEW_EXT_framebuffer_object; } void GPU_set_mipmap(int mipmap) diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 7be34c398ae..bd454bab25d 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -144,12 +144,6 @@ static void rna_userdef_anisotropic_update(Main *bmain, Scene *scene, PointerRNA rna_userdef_update(bmain, scene, ptr); } -static void rna_userdef_gl_gpu_mipmaps(Main *bmain, Scene *scene, PointerRNA *ptr) -{ - GPU_set_gpu_mipmapping(U.use_gpu_mipmap); - rna_userdef_update(bmain, scene, ptr); -} - static void rna_userdef_gl_texture_limit_update(Main *bmain, Scene *scene, PointerRNA *ptr) { GPU_free_images(); @@ -3224,11 +3218,6 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_ui_text(prop, "16 Bit Float Textures", "Use 16 bit per component texture for float images"); RNA_def_property_update(prop, 0, "rna_userdef_gl_use_16bit_textures"); - prop = RNA_def_property(srna, "use_gpu_mipmap", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "use_gpu_mipmap", 1); - RNA_def_property_ui_text(prop, "GPU Mipmap Generation", "Generate Image Mipmaps on the GPU"); - RNA_def_property_update(prop, 0, "rna_userdef_gl_gpu_mipmaps"); - prop = RNA_def_property(srna, "use_vertex_buffer_objects", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_VBO); RNA_def_property_ui_text(prop, "VBOs", diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index c9f0bbffc63..1b8bcd51564 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -183,7 +183,7 @@ void WM_init(bContext *C, int argc, const char **argv) GPU_extensions_init(); GPU_set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP)); GPU_set_anisotropic(U.anisotropic_filter); - GPU_set_gpu_mipmapping(U.use_gpu_mipmap); + GPU_set_gpu_mipmapping(); UI_init(); } diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index 4451c78b99c..475e139bfcc 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -756,6 +756,7 @@ int main(int argc, char** argv) } GPU_set_anisotropic(U.anisotropic_filter); + GPU_set_gpu_mipmapping(); // Create the system if (GHOST_ISystem::createSystem() == GHOST_kSuccess) -- cgit v1.2.3 From 69948150ad417e20ed29d818ba5a271d653ef2ff Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 Nov 2012 23:37:02 +0000 Subject: improve docstring for BMO_op_vinitf(). --- source/blender/bmesh/intern/bmesh_operators.c | 65 ++++++++++++++++++++------- 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 7c9b02b4952..18caefc13c3 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -1482,24 +1482,57 @@ static int bmo_opname_to_opcode(const char *opname) return -1; } -/* Example: - * BMO_op_callf(bm, BMO_FLAG_DEFAULTS, "delete %i %hv", DEL_ONLYFACES, BM_ELEM_SELECT); +/** + * \brief Format Strings for #BMOperator Initialization. + * + * Example: + * + * \code{.c} + * BMO_op_callf(bm, BMO_FLAG_DEFAULTS, + * "delete context=%i geom=%hv", + * DEL_ONLYFACES, BM_ELEM_SELECT); + * \endcode + * + * + * **Primitive Types** + * - `b` - boolean (same as int but 1/0 only). #BMO_OP_SLOT_BOOL + * - `i` - int. #BMO_OP_SLOT_INT + * - `f` - float. #BMO_OP_SLOT_FLT + * - `p` - pointer (normally to a Scene/Mesh/Object/BMesh). #BMO_OP_SLOT_PTR + * - `m3` - 3x3 matrix of floats. #BMO_OP_SLOT_MAT + * - `m4` - 4x4 matrix of floats. #BMO_OP_SLOT_MAT + * - `v` - 3D vector of floats. #BMO_OP_SLOT_VEC + * + * + * **Utility** + * + * Pass an existing slot which is copied to either an input or output slot. + * Taking the operator and slot-name pair of args. + * - `s` - slot_in (lower case) + * - `S` - slot_out (upper case) + * * - * i - int - * b - boolean (same as int but 1/0 only) - * f - float - * s - slot_in - * S - slot_out - * e - single vert/edge/face - * hv - header flagged verts (hflag) - * he - header flagged edges (hflag) - * hf - header flagged faces (hflag) - * fv - flagged verts (oflag) - * fe - flagged edges (oflag) - * ff - flagged faces (oflag) + * **Element Buffer** (#BMO_OP_SLOT_ELEMENT_BUF) + * - `e` - single element vert/edge/face (use with #BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE). + * - `av` - all verts + * - `ae` - all edges + * - `af` - all faces + * - `hv` - header flagged verts (hflag) + * - `he` - header flagged edges (hflag) + * - `hf` - header flagged faces (hflag) + * - `Hv` - header flagged verts (hflag off) + * - `He` - header flagged edges (hflag off) + * - `Hf` - header flagged faces (hflag off) + * - `fv` - flagged verts (oflag) + * - `fe` - flagged edges (oflag) + * - `ff` - flagged faces (oflag) + * - `Fv` - flagged verts (oflag off) + * - `Fe` - flagged edges (oflag off) + * - `Ff` - flagged faces (oflag off) * - * capitals - H, F to use the flag flipped (when the flag is off) - * Hv, He, Hf, Fv, Fe, Ff, + * \note The common v/e/f suffix can be mixed, + * so `avef` is can be used for all verts, edges and faces. + * Order is not important so `Hfev` is also valid (all unflagged verts, edges and faces). */ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, va_list vlist) -- cgit v1.2.3 From 8ecce451ab928fd2ab9d2844e8f337c18c6f1269 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 28 Nov 2012 00:16:06 +0000 Subject: bmesh operator naming - use clearer names for args eg: (mat -> matrix, use_singleedge -> use_single_edge) also remove duplicate docs for operator arg formatting. --- source/blender/bmesh/intern/bmesh_opdefines.c | 96 ++++++++++++------------ source/blender/bmesh/intern/bmesh_operator_api.h | 45 ++--------- source/blender/bmesh/intern/bmesh_operators.c | 6 ++ source/blender/bmesh/intern/bmesh_operators.h | 4 +- source/blender/bmesh/operators/bmo_dupe.c | 26 +++---- source/blender/bmesh/operators/bmo_extrude.c | 8 +- source/blender/bmesh/operators/bmo_hull.c | 8 +- source/blender/bmesh/operators/bmo_mirror.c | 6 +- source/blender/bmesh/operators/bmo_primitive.c | 18 ++--- source/blender/bmesh/operators/bmo_subdivide.c | 42 +++++------ source/blender/bmesh/operators/bmo_subdivide.h | 4 +- source/blender/bmesh/operators/bmo_symmetrize.c | 2 +- source/blender/bmesh/operators/bmo_triangulate.c | 2 +- source/blender/bmesh/operators/bmo_utils.c | 8 +- source/blender/editors/mesh/editmesh_add.c | 18 ++--- source/blender/editors/mesh/editmesh_loopcut.c | 6 +- source/blender/editors/mesh/editmesh_tools.c | 14 ++-- 17 files changed, 143 insertions(+), 170 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 8e2a2b22508..502dafeb5c3 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -254,11 +254,11 @@ static BMOpDefine bmo_mirror_def = { "mirror", /* slots_in */ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */ - {"mat", BMO_OP_SLOT_MAT}, /* matrix defining the mirror transformation */ - {"merge_dist", BMO_OP_SLOT_FLT}, /* maximum distance for merging. does no merging if 0. */ - {"axis", BMO_OP_SLOT_INT}, /* the axis to use, 0, 1, or 2 for x, y, z */ - {"mirror_u", BMO_OP_SLOT_BOOL}, /* mirror UVs across the u axis */ - {"mirror_v", BMO_OP_SLOT_BOOL}, /* mirror UVs across the v axis */ + {"matrix", BMO_OP_SLOT_MAT}, /* matrix defining the mirror transformation */ + {"merge_dist", BMO_OP_SLOT_FLT}, /* maximum distance for merging. does no merging if 0. */ + {"axis", BMO_OP_SLOT_INT}, /* the axis to use, 0, 1, or 2 for x, y, z */ + {"mirror_u", BMO_OP_SLOT_BOOL}, /* mirror UVs across the u axis */ + {"mirror_v", BMO_OP_SLOT_BOOL}, /* mirror UVs across the v axis */ {{'\0'}}, }, /* slots_out */ @@ -587,9 +587,9 @@ static BMOpDefine bmo_edgenet_prepare_def = { static BMOpDefine bmo_rotate_def = { "rotate", /* slots_in */ - {{"cent", BMO_OP_SLOT_VEC}, /* center of rotation */ - {"mat", BMO_OP_SLOT_MAT}, /* matrix defining rotation */ - {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ + {{"cent", BMO_OP_SLOT_VEC}, /* center of rotation */ + {"matrix", BMO_OP_SLOT_MAT}, /* matrix defining rotation */ + {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -642,8 +642,8 @@ static BMOpDefine bmo_scale_def = { static BMOpDefine bmo_transform_def = { "transform", /* slots_in */ - {{"mat", BMO_OP_SLOT_MAT}, /* transform matrix */ - {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ + {{"matrix", BMO_OP_SLOT_MAT}, /* transform matrix */ + {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -911,7 +911,7 @@ static BMOpDefine bmo_triangulate_def = { /* slots_out */ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, - {"facemap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, + {"face_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, {{'\0'}}, }, bmo_triangulate_exec, @@ -950,13 +950,13 @@ static BMOpDefine bmo_subdivide_edges_def = { {"along_normal", BMO_OP_SLOT_FLT}, {"cuts", BMO_OP_SLOT_INT}, {"seed", BMO_OP_SLOT_INT}, - {"custompatterns", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL}}, /* uses custom pointers */ - {"edgepercents", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_FLOAT}}, + {"custom_patterns", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL}}, /* uses custom pointers */ + {"edge_percents", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_FLOAT}}, {"quad_corner_type", BMO_OP_SLOT_INT}, /* quad corner type, see bmesh_operators.h */ - {"use_gridfill", BMO_OP_SLOT_BOOL}, /* fill in fully-selected faces with a grid */ - {"use_singleedge", BMO_OP_SLOT_BOOL}, /* tessellate the case of one edge selected in a quad or triangle */ - {"use_onlyquads", BMO_OP_SLOT_BOOL}, /* only subdivide quads (for loopcut) */ + {"use_grid_fill", BMO_OP_SLOT_BOOL}, /* fill in fully-selected faces with a grid */ + {"use_single_edge", BMO_OP_SLOT_BOOL}, /* tessellate the case of one edge selected in a quad or triangle */ + {"use_only_quads", BMO_OP_SLOT_BOOL}, /* only subdivide quads (for loopcut) */ {"use_sphere", BMO_OP_SLOT_BOOL}, /* for making new primitives only */ {{'\0'}}, }, @@ -980,7 +980,7 @@ static BMOpDefine bmo_delete_def = { "delete", /* slots_in */ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, - {"context", BMO_OP_SLOT_INT}, + {"context", BMO_OP_SLOT_INT}, /* enum DEL_VERTS ... */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -1007,9 +1007,9 @@ static BMOpDefine bmo_duplicate_def = { {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* facemap maps from source faces to dupe * faces, and from dupe faces to source faces */ - {"facemap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, - {"boundarymap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, - {"isovertmap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, + {"face_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, + {"boundary_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, + {"isovert_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, {{'\0'}}, }, bmo_duplicate_exec, @@ -1033,8 +1033,8 @@ static BMOpDefine bmo_split_def = { }, /* slots_out */ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, - {"boundarymap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, - {"isovertmap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, + {"boundary_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, + {"isovert_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, {{'\0'}}, }, bmo_split_exec, @@ -1252,10 +1252,10 @@ static BMOpDefine bmo_split_edges_def = { static BMOpDefine bmo_create_grid_def = { "create_grid", /* slots_in */ - {{"x_segments", BMO_OP_SLOT_INT}, /* number of x segments */ - {"y_segments", BMO_OP_SLOT_INT}, /* number of y segments */ - {"size", BMO_OP_SLOT_FLT}, /* size of the grid */ - {"mat", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ + {{"x_segments", BMO_OP_SLOT_INT}, /* number of x segments */ + {"y_segments", BMO_OP_SLOT_INT}, /* number of y segments */ + {"size", BMO_OP_SLOT_FLT}, /* size of the grid */ + {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ {{'\0'}}, }, /* slots_out */ @@ -1274,10 +1274,10 @@ static BMOpDefine bmo_create_grid_def = { static BMOpDefine bmo_create_uvsphere_def = { "create_uvsphere", /* slots_in */ - {{"u_segments", BMO_OP_SLOT_INT}, /* number of u segments */ - {"v_segments", BMO_OP_SLOT_INT}, /* number of v segment */ - {"diameter", BMO_OP_SLOT_FLT}, /* diameter */ - {"mat", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ + {{"u_segments", BMO_OP_SLOT_INT}, /* number of u segments */ + {"v_segments", BMO_OP_SLOT_INT}, /* number of v segment */ + {"diameter", BMO_OP_SLOT_FLT}, /* diameter */ + {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ {{'\0'}}, }, /* slots_out */ @@ -1296,9 +1296,9 @@ static BMOpDefine bmo_create_uvsphere_def = { static BMOpDefine bmo_create_icosphere_def = { "create_icosphere", /* slots_in */ - {{"subdivisions", BMO_OP_SLOT_INT}, /* how many times to recursively subdivide the sphere */ - {"diameter", BMO_OP_SLOT_FLT}, /* diameter */ - {"mat", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ + {{"subdivisions", BMO_OP_SLOT_INT}, /* how many times to recursively subdivide the sphere */ + {"diameter", BMO_OP_SLOT_FLT}, /* diameter */ + {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ {{'\0'}}, }, /* slots_out */ @@ -1317,7 +1317,7 @@ static BMOpDefine bmo_create_icosphere_def = { static BMOpDefine bmo_create_monkey_def = { "create_monkey", /* slots_in */ - {{"mat", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ + {{"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ {{'\0'}}, }, /* slots_out */ @@ -1336,13 +1336,13 @@ static BMOpDefine bmo_create_monkey_def = { static BMOpDefine bmo_create_cone_def = { "create_cone", /* slots_in */ - {{"cap_ends", BMO_OP_SLOT_BOOL}, /* whether or not to fill in the ends with faces */ - {"cap_tris", BMO_OP_SLOT_BOOL}, /* fill ends with triangles instead of ngons */ - {"segments", BMO_OP_SLOT_INT}, - {"diameter1", BMO_OP_SLOT_FLT}, /* diameter of one end */ - {"diameter2", BMO_OP_SLOT_FLT}, /* diameter of the opposite */ - {"depth", BMO_OP_SLOT_FLT}, /* distance between ends */ - {"mat", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ + {{"cap_ends", BMO_OP_SLOT_BOOL}, /* whether or not to fill in the ends with faces */ + {"cap_tris", BMO_OP_SLOT_BOOL}, /* fill ends with triangles instead of ngons */ + {"segments", BMO_OP_SLOT_INT}, + {"diameter1", BMO_OP_SLOT_FLT}, /* diameter of one end */ + {"diameter2", BMO_OP_SLOT_FLT}, /* diameter of the opposite */ + {"depth", BMO_OP_SLOT_FLT}, /* distance between ends */ + {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ {{'\0'}}, }, /* slots_out */ @@ -1359,11 +1359,11 @@ static BMOpDefine bmo_create_cone_def = { static BMOpDefine bmo_create_circle_def = { "create_circle", /* slots_in */ - {{"cap_ends", BMO_OP_SLOT_BOOL}, /* whether or not to fill in the ends with faces */ - {"cap_tris", BMO_OP_SLOT_BOOL}, /* fill ends with triangles instead of ngons */ - {"segments", BMO_OP_SLOT_INT}, - {"diameter", BMO_OP_SLOT_FLT}, /* diameter of one end */ - {"mat", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ + {{"cap_ends", BMO_OP_SLOT_BOOL}, /* whether or not to fill in the ends with faces */ + {"cap_tris", BMO_OP_SLOT_BOOL}, /* fill ends with triangles instead of ngons */ + {"segments", BMO_OP_SLOT_INT}, + {"diameter", BMO_OP_SLOT_FLT}, /* diameter of one end */ + {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ {{'\0'}}, }, /* slots_out */ @@ -1382,8 +1382,8 @@ static BMOpDefine bmo_create_circle_def = { static BMOpDefine bmo_create_cube_def = { "create_cube", /* slots_in */ - {{"size", BMO_OP_SLOT_FLT}, /* size of the cube */ - {"mat", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ + {{"size", BMO_OP_SLOT_FLT}, /* size of the cube */ + {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ {{'\0'}}, }, /* slots_out */ diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h index bebd3215d93..df67f459a34 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api.h +++ b/source/blender/bmesh/intern/bmesh_operator_api.h @@ -240,43 +240,6 @@ int BMO_mesh_enabled_flag_count(BMesh *bm, const char htype, const short oflag); int BMO_mesh_disabled_flag_count(BMesh *bm, const char htype, const short oflag); /*---------formatted operator initialization/execution-----------*/ -/* - * this system is used to execute or initialize an operator, - * using a formatted-string system. - * - * for example, BMO_op_callf(bm, BMO_FLAG_DEFAULTS, "delete geom=%hf context=%i", BM_ELEM_SELECT, DEL_FACES); - * . . .will execute the delete operator, feeding in selected faces, deleting them. - * - * the basic format for the format string is: - * [operatorname] [slot_name]=%[code] [slot_name]=%[code] - * - * as in printf, you pass in one additional argument to the function - * for every code. - * - * the formatting codes are: - * %d - put int in slot - * %f - put float in slot - * %p - put pointer in slot - * %h[f/e/v] - put elements with a header flag in slot. - * the letters after %h define which element types to use, - * so e.g. %hf will do faces, %hfe will do faces and edges, - * %hv will do verts, etc. must pass in at least one - * element type letter. - * %H[f/e/v] - same as %h, but tests if the flag is disabled - * %f[f/e/v] - same as %h, except it deals with tool flags instead of - * header flags. - * %F[f/e/v] - same as %f, but tests if the flag is disabled - * %a[f/e/v] - pass all elements (of types specified by f/e/v) to the - * slot. - * %e - pass in a single element. - * %v - pointer to a float vector of length 3. - * %m[3/4] - matrix, 3/4 refers to the matrix size, 3 or 4. the - * corresponding argument must be a pointer to - * a float matrix. - * %s - copy a slot from another op, instead of mapping to one - * argument, it maps to two, a pointer to an operator and - * a slot name. - */ void BMO_push(BMesh *bm, BMOperator *op); void BMO_pop(BMesh *bm); @@ -443,15 +406,18 @@ void *BMO_slot_buffer_alloc(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS] void BMO_slot_buffer_from_all(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char htype); -/* this part of the API is used to iterate over element buffer or +/** + * This part of the API is used to iterate over element buffer or * mapping slots. * * for example, iterating over the faces in a slot is: * + * \code{.c} + * * BMOIter oiter; * BMFace *f; * - * f = BMO_iter_new(&oiter, bm, some_operator, "slot_name", BM_FACE); + * f = BMO_iter_new(&oiter, some_operator, "slot_name", BM_FACE); * for (; f; f = BMO_iter_step(&oiter)) { * /do something with the face * } @@ -472,6 +438,7 @@ void BMO_slot_buffer_from_all(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_ * // *((void**)BMO_iter_map_value(&oiter)); * //or something like that. * } + * \endcode */ /* contents of this structure are private, diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 18caefc13c3..ba38f230f0b 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -1485,6 +1485,12 @@ static int bmo_opname_to_opcode(const char *opname) /** * \brief Format Strings for #BMOperator Initialization. * + * This system is used to execute or initialize an operator, + * using a formatted-string system. + * + * The basic format for the format string is: + * `[operatorname] [slot_name]=%[code] [slot_name]=%[code]` + * * Example: * * \code{.c} diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h index 9a89e2bc996..d02b0dce728 100644 --- a/source/blender/bmesh/intern/bmesh_operators.h +++ b/source/blender/bmesh/intern/bmesh_operators.h @@ -97,8 +97,8 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag, float smooth, float fractal, float along_normal, int numcuts, int seltype, int cornertype, - const short use_singleedge, const short use_gridfill, - const short use_onlyquads, + const short use_single_edge, const short use_grid_fill, + const short use_only_quads, int seed); #include "intern/bmesh_operator_api_inline.h" diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c index f278d3f8896..76a9d571b20 100644 --- a/source/blender/bmesh/operators/bmo_dupe.c +++ b/source/blender/bmesh/operators/bmo_dupe.c @@ -199,9 +199,9 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst) BMIter viter, eiter, fiter; GHash *vhash, *ehash; - BMOpSlot *slot_boundarymap_out = BMO_slot_get(op->slots_out, "boundarymap.out"); - BMOpSlot *slot_facemap_out = BMO_slot_get(op->slots_out, "facemap.out"); - BMOpSlot *slot_isovertmap_out = BMO_slot_get(op->slots_out, "isovertmap.out"); + BMOpSlot *slot_boundary_map_out = BMO_slot_get(op->slots_out, "boundary_map.out"); + BMOpSlot *slot_face_map_out = BMO_slot_get(op->slots_out, "face_map.out"); + BMOpSlot *slot_isovert_map_out = BMO_slot_get(op->slots_out, "isovert_map.out"); /* initialize pointer hashes */ vhash = BLI_ghash_ptr_new("bmesh dupeops v"); @@ -234,7 +234,7 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst) } if (isolated) { - BMO_slot_map_elem_insert(op, slot_isovertmap_out, v, v2); + BMO_slot_map_elem_insert(op, slot_isovert_map_out, v, v2); } BMO_elem_flag_enable(bm_src, v, DUPE_DONE); @@ -256,7 +256,7 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst) BMO_elem_flag_enable(bm_src, e->v2, DUPE_DONE); } /* now copy the actual edge */ - copy_edge(op, slot_boundarymap_out, bm_src, e, bm_dst, vhash, ehash); + copy_edge(op, slot_boundary_map_out, bm_src, e, bm_dst, vhash, ehash); BMO_elem_flag_enable(bm_src, e, DUPE_DONE); } } @@ -275,7 +275,7 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst) /* edge pass */ BM_ITER_ELEM (e, &eiter, f, BM_EDGES_OF_FACE) { if (!BMO_elem_flag_test(bm_src, e, DUPE_DONE)) { - copy_edge(op, slot_boundarymap_out, bm_src, e, bm_dst, vhash, ehash); + copy_edge(op, slot_boundary_map_out, bm_src, e, bm_dst, vhash, ehash); BMO_elem_flag_enable(bm_src, e, DUPE_DONE); } } @@ -287,7 +287,7 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst) BLI_array_grow_items(vtar, f->len); BLI_array_grow_items(edar, f->len); - copy_face(op, slot_facemap_out, bm_src, f, bm_dst, vtar, edar, vhash, ehash); + copy_face(op, slot_face_map_out, bm_src, f, bm_dst, vtar, edar, vhash, ehash); BMO_elem_flag_enable(bm_src, f, DUPE_DONE); } } @@ -445,11 +445,11 @@ void bmo_split_exec(BMesh *bm, BMOperator *op) BMO_slot_copy(&dupeop, slots_out, "geom.out", splitop, slots_out, "geom.out"); - BMO_slot_copy(&dupeop, slots_out, "boundarymap.out", - splitop, slots_out, "boundarymap.out"); + BMO_slot_copy(&dupeop, slots_out, "boundary_map.out", + splitop, slots_out, "boundary_map.out"); - BMO_slot_copy(&dupeop, slots_out, "isovertmap.out", - splitop, slots_out, "isovertmap.out"); + BMO_slot_copy(&dupeop, slots_out, "isovert_map.out", + splitop, slots_out, "isovert_map.out"); /* cleanup */ @@ -506,7 +506,7 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op) BMO_op_initf(bm, &dupop, op->flag, "duplicate geom=%S", op, "geom_last.out"); BMO_op_exec(bm, &dupop); BMO_op_callf(bm, op->flag, - "rotate cent=%v mat=%m3 verts=%S", + "rotate cent=%v matrix=%m3 verts=%S", cent, rmat, &dupop, "geom.out"); BMO_slot_copy(&dupop, slots_out, "geom.out", op, slots_out, "geom_last.out"); @@ -517,7 +517,7 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op) op, "geom_last.out"); BMO_op_exec(bm, &extop); BMO_op_callf(bm, op->flag, - "rotate cent=%v mat=%m3 verts=%S", + "rotate cent=%v matrix=%m3 verts=%S", cent, rmat, &extop, "geom.out"); BMO_slot_copy(&extop, slots_out, "geom.out", op, slots_out, "geom_last.out"); diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c index aece270b09c..1ab640ba6a5 100644 --- a/source/blender/bmesh/operators/bmo_extrude.c +++ b/source/blender/bmesh/operators/bmo_extrude.c @@ -198,7 +198,7 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op) } } - for (e = BMO_iter_new(&siter, dupeop.slots_out, "boundarymap.out", 0); e; e = BMO_iter_step(&siter)) { + for (e = BMO_iter_new(&siter, dupeop.slots_out, "boundary_map.out", 0); e; e = BMO_iter_step(&siter)) { BMVert *f_verts[4]; e_new = *(BMEdge **)BMO_iter_map_value(&siter); @@ -352,7 +352,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) } } - slot_facemap_out = BMO_slot_get(dupeop.slots_out, "facemap.out"); + slot_facemap_out = BMO_slot_get(dupeop.slots_out, "face_map.out"); if (bm->act_face && BMO_elem_flag_test(bm, bm->act_face, EXT_INPUT)) { bm->act_face = BMO_slot_map_elem_get(slot_facemap_out, bm->act_face); } @@ -374,7 +374,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) op, slots_out, "geom.out"); slot_edges_exclude = BMO_slot_get(op->slots_in, "edges_exclude"); - for (e = BMO_iter_new(&siter, dupeop.slots_out, "boundarymap.out", 0); e; e = BMO_iter_step(&siter)) { + for (e = BMO_iter_new(&siter, dupeop.slots_out, "boundary_map.out", 0); e; e = BMO_iter_step(&siter)) { BMVert *f_verts[4]; /* this should always be wire, so this is mainly a speedup to avoid map lookup */ @@ -428,7 +428,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) } /* link isolated vert */ - for (v = BMO_iter_new(&siter, dupeop.slots_out, "isovertmap.out", 0); v; v = BMO_iter_step(&siter)) { + for (v = BMO_iter_new(&siter, dupeop.slots_out, "isovert_map.out", 0); v; v = BMO_iter_step(&siter)) { v2 = *((void **)BMO_iter_map_value(&siter)); BM_edge_create(bm, v, v2, v->e, TRUE); } diff --git a/source/blender/bmesh/operators/bmo_hull.c b/source/blender/bmesh/operators/bmo_hull.c index 117f65ae4ea..08fc97ea262 100644 --- a/source/blender/bmesh/operators/bmo_hull.c +++ b/source/blender/bmesh/operators/bmo_hull.c @@ -604,22 +604,22 @@ void bmo_convex_hull_exec(BMesh *bm, BMOperator *op) /* Output slot of input elements that ended up inside the hull * rather than part of it */ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_interior.out", - BM_ALL, HULL_FLAG_INTERIOR_ELE); + BM_ALL_NOLOOP, HULL_FLAG_INTERIOR_ELE); /* Output slot of input elements that ended up inside the hull and * are are unused by other geometry. */ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_unused.out", - BM_ALL, HULL_FLAG_DEL); + BM_ALL_NOLOOP, HULL_FLAG_DEL); /* Output slot of faces and edges that were in the input and on * the hull (useful for cases like bridging where you want to * delete some input geometry) */ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_holes.out", - BM_ALL, HULL_FLAG_HOLE); + BM_ALL_NOLOOP, HULL_FLAG_HOLE); /* Output slot of all hull vertices, faces, and edges */ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", - BM_ALL, HULL_FLAG_OUTPUT_GEOM); + BM_ALL_NOLOOP, HULL_FLAG_OUTPUT_GEOM); } #endif /* WITH_BULLET */ diff --git a/source/blender/bmesh/operators/bmo_mirror.c b/source/blender/bmesh/operators/bmo_mirror.c index 41cfae579ff..61b061dd21f 100644 --- a/source/blender/bmesh/operators/bmo_mirror.c +++ b/source/blender/bmesh/operators/bmo_mirror.c @@ -60,7 +60,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op) ototvert = bm->totvert; /* ototedge = bm->totedge; */ /* UNUSED */ - BMO_slot_mat4_get(op->slots_in, "mat", mtx); + BMO_slot_mat4_get(op->slots_in, "matrix", mtx); invert_m4_m4(imtx, mtx); BMO_op_initf(bm, &dupeop, op->flag, "duplicate geom=%s", op, "geom"); @@ -81,9 +81,9 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op) /* feed old data to transform bmo */ scale[axis] = -1.0f; - BMO_op_callf(bm, op->flag, "transform verts=%fv mat=%m4", ELE_NEW, mtx); + BMO_op_callf(bm, op->flag, "transform verts=%fv matrix=%m4", ELE_NEW, mtx); BMO_op_callf(bm, op->flag, "scale verts=%fv vec=%v", ELE_NEW, scale); - BMO_op_callf(bm, op->flag, "transform verts=%fv mat=%m4", ELE_NEW, imtx); + BMO_op_callf(bm, op->flag, "transform verts=%fv matrix=%m4", ELE_NEW, imtx); BMO_op_init(bm, &weldop, op->flag, "weld_verts"); diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c index 71f63bbaf28..38096b4ca6f 100644 --- a/source/blender/bmesh/operators/bmo_primitive.c +++ b/source/blender/bmesh/operators/bmo_primitive.c @@ -237,7 +237,7 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op) float vec[3], mat[4][4], phi, phid; int a; - BMO_slot_mat4_get(op->slots_in, "mat", mat); + BMO_slot_mat4_get(op->slots_in, "matrix", mat); /* one segment first: the X axis */ phi = 1.0f; @@ -304,7 +304,7 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op) float phid; int a; - BMO_slot_mat4_get(op->slots_in, "mat", mat); + BMO_slot_mat4_get(op->slots_in, "matrix", mat); phid = 2.0f * (float)M_PI / tot; /* phi = 0.25f * (float)M_PI; */ /* UNUSED */ @@ -348,7 +348,7 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op) } BMO_slot_buffer_flag_enable(bm, bmop.slots_out, "geom.out", BM_VERT, VERT_MARK); - BMO_op_callf(bm, op->flag, "rotate cent=%v mat=%m3 verts=%S", vec, cmat, &bmop, "geom.out"); + BMO_op_callf(bm, op->flag, "rotate cent=%v matrix=%m3 verts=%S", vec, cmat, &bmop, "geom.out"); prevop = bmop; } @@ -397,7 +397,7 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op) float vec[3], mat[4][4] /* , phi, phid */; int a; - BMO_slot_mat4_get(op->slots_in, "mat", mat); + BMO_slot_mat4_get(op->slots_in, "matrix", mat); /* phid = 2.0f * (float)M_PI / subdiv; */ /* UNUSED */ /* phi = 0.25f * (float)M_PI; */ /* UNUSED */ @@ -436,7 +436,7 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op) "subdivide_edges edges=%fe " "smooth=%f " "cuts=%i " - "use_gridfill=%b use_sphere=%b", + "use_grid_fill=%b use_sphere=%b", EDGE_MARK, dia, (1 << (subdiv - 1)) - 1, TRUE, TRUE); @@ -463,7 +463,7 @@ void bmo_create_monkey_exec(BMesh *bm, BMOperator *op) float mat[4][4]; int i; - BMO_slot_mat4_get(op->slots_in, "mat", mat); + BMO_slot_mat4_get(op->slots_in, "matrix", mat); for (i = 0; i < monkeynv; i++) { float v[3]; @@ -518,7 +518,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op) if (!segs) return; - BMO_slot_mat4_get(op->slots_in, "mat", mat); + BMO_slot_mat4_get(op->slots_in, "matrix", mat); phid = 2.0f * (float)M_PI / segs; phi = 0; @@ -591,7 +591,7 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op) if (!segs) return; - BMO_slot_mat4_get(op->slots_in, "mat", mat); + BMO_slot_mat4_get(op->slots_in, "matrix", mat); phid = 2.0f * (float)M_PI / segs; phi = 0; @@ -677,7 +677,7 @@ void bmo_create_cube_exec(BMesh *bm, BMOperator *op) BMVert *v1, *v2, *v3, *v4, *v5, *v6, *v7, *v8; float vec[3], mat[4][4], off = BMO_slot_float_get(op->slots_in, "size") / 2.0f; - BMO_slot_mat4_get(op->slots_in, "mat", mat); + BMO_slot_mat4_get(op->slots_in, "matrix", mat); if (!off) off = 0.5f; diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index 8da1f5ebfe5..7407eb4423a 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -226,7 +226,7 @@ static BMVert *subdivideedgenum(BMesh *bm, BMEdge *edge, BMEdge *oedge, float percent, percent2 = 0.0f; if (BMO_elem_flag_test(bm, edge, EDGE_PERCENT) && totpoint == 1) { - percent = BMO_slot_map_float_get(params->slot_edgepercents, edge); + percent = BMO_slot_map_float_get(params->slot_edge_percents, edge); } else { percent = 1.0f / (float)(totpoint + 1 - curpoint); @@ -715,7 +715,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) BMFace *face; BLI_array_declare(verts); float smooth, fractal, along_normal; - int use_sphere, cornertype, use_singleedge, use_gridfill, use_onlyquads; + int use_sphere, cornertype, use_single_edge, use_grid_fill, use_only_quads; int skey, seed, i, j, matched, a, b, numcuts, totesel; BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, SUBD_SPLIT); @@ -727,10 +727,10 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) along_normal = BMO_slot_float_get(op->slots_in, "along_normal"); cornertype = BMO_slot_int_get(op->slots_in, "quad_corner_type"); - use_singleedge = BMO_slot_bool_get(op->slots_in, "use_singleedge"); - use_gridfill = BMO_slot_bool_get(op->slots_in, "use_gridfill"); - use_onlyquads = BMO_slot_bool_get(op->slots_in, "use_onlyquads"); - use_sphere = BMO_slot_bool_get(op->slots_in, "use_sphere"); + use_single_edge = BMO_slot_bool_get(op->slots_in, "use_single_edge"); + use_grid_fill = BMO_slot_bool_get(op->slots_in, "use_grid_fill"); + use_only_quads = BMO_slot_bool_get(op->slots_in, "use_only_quads"); + use_sphere = BMO_slot_bool_get(op->slots_in, "use_sphere"); BLI_srandom(seed); @@ -748,7 +748,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) break; } - if (use_singleedge) { + if (use_single_edge) { patterns[0] = &quad_1edge; patterns[2] = &tri_1edge; } @@ -757,7 +757,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) patterns[2] = NULL; } - if (use_gridfill) { + if (use_grid_fill) { patterns[3] = &quad_4edge; patterns[5] = &tri_3edge; } @@ -780,8 +780,8 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) params.numcuts = numcuts; params.op = op; - params.slot_edgepercents = BMO_slot_get(op->slots_in, "edgepercents"); - params.slot_custompatterns = BMO_slot_get(op->slots_in, "custompatterns"); + params.slot_edge_percents = BMO_slot_get(op->slots_in, "edge_percents"); + params.slot_custom_patterns = BMO_slot_get(op->slots_in, "custom_patterns"); params.smooth = smooth; params.seed = seed; params.fractal = fractal; @@ -794,10 +794,10 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) params.off[1] = (float)BLI_drand() * 200.0f; params.off[2] = (float)BLI_drand() * 200.0f; - BMO_slot_map_to_flag(bm, op->slots_in, "custompatterns", + BMO_slot_map_to_flag(bm, op->slots_in, "custom_patterns", BM_FACE, FACE_CUSTOMFILL); - BMO_slot_map_to_flag(bm, op->slots_in, "edgepercents", + BMO_slot_map_to_flag(bm, op->slots_in, "edge_percents", BM_EDGE, EDGE_PERCENT); @@ -806,7 +806,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) float vec1[3], vec2[3]; /* skip non-quads if requested */ - if (use_onlyquads && face->len != 4) + if (use_only_quads && face->len != 4) continue; /* figure out which pattern to use */ @@ -845,7 +845,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) } if (BMO_elem_flag_test(bm, face, FACE_CUSTOMFILL)) { - pat = BMO_slot_map_data_get(params.slot_custompatterns, face); + pat = BMO_slot_map_data_get(params.slot_custom_patterns, face); for (i = 0; i < pat->len; i++) { matched = 1; for (j = 0; j < pat->len; j++) { @@ -1093,8 +1093,8 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag, float smooth, float fractal, float along_normal, int numcuts, int seltype, int cornertype, - const short use_singleedge, const short use_gridfill, - const short use_onlyquads, + const short use_single_edge, const short use_grid_fill, + const short use_only_quads, int seed) { BMOperator op; @@ -1105,15 +1105,15 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag, "smooth=%f fractal=%f along_normal=%f " "cuts=%i " "quad_corner_type=%i " - "use_singleedge=%b use_gridfill=%b " - "use_onlyquads=%b " + "use_single_edge=%b use_grid_fill=%b " + "use_only_quads=%b " "seed=%i", edge_hflag, smooth, fractal, along_normal, numcuts, cornertype, - use_singleedge, use_gridfill, - use_onlyquads, + use_single_edge, use_grid_fill, + use_only_quads, seed); BMO_op_exec(bm, &op); @@ -1170,7 +1170,7 @@ void bmo_bisect_edges_exec(BMesh *bm, BMOperator *op) params.numcuts = BMO_slot_int_get(op->slots_in, "cuts"); params.op = op; - params.slot_edgepercents = BMO_slot_get(op->slots_in, "edgepercents"); + params.slot_edge_percents = BMO_slot_get(op->slots_in, "edge_percents"); BM_data_layer_add(bm, &bm->vdata, CD_SHAPEKEY); skey = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY) - 1; diff --git a/source/blender/bmesh/operators/bmo_subdivide.h b/source/blender/bmesh/operators/bmo_subdivide.h index d0676508917..529075aab02 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.h +++ b/source/blender/bmesh/operators/bmo_subdivide.h @@ -39,8 +39,8 @@ typedef struct SubDParams { int seed; int origkey; /* shapekey holding displaced vertex coordinates for current geometry */ BMOperator *op; - BMOpSlot *slot_edgepercents; /* BMO_slot_get(params->op->slots_in, "edgepercents"); */ - BMOpSlot *slot_custompatterns; /* BMO_slot_get(params->op->slots_in, "custompatterns"); */ + BMOpSlot *slot_edge_percents; /* BMO_slot_get(params->op->slots_in, "edge_percents"); */ + BMOpSlot *slot_custom_patterns; /* BMO_slot_get(params->op->slots_in, "custom_patterns"); */ float off[3]; } SubDParams; diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c b/source/blender/bmesh/operators/bmo_symmetrize.c index 8c440cae83e..71d9e3295c6 100644 --- a/source/blender/bmesh/operators/bmo_symmetrize.c +++ b/source/blender/bmesh/operators/bmo_symmetrize.c @@ -659,5 +659,5 @@ void bmo_symmetrize_exec(BMesh *bm, BMOperator *op) BLI_ghash_free(symm.edge_split_map, NULL, NULL); BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", - BM_ALL, SYMM_OUTPUT_GEOM); + BM_ALL_NOLOOP, SYMM_OUTPUT_GEOM); } diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c index 2f375710959..d20d01af114 100644 --- a/source/blender/bmesh/operators/bmo_triangulate.c +++ b/source/blender/bmesh/operators/bmo_triangulate.c @@ -53,7 +53,7 @@ void bmo_triangulate_exec(BMesh *bm, BMOperator *op) BLI_array_declare(projectverts); int i; const int use_beauty = BMO_slot_bool_get(op->slots_in, "use_beauty"); - BMOpSlot *slot_facemap_out = BMO_slot_get(op->slots_out, "facemap.out"); + BMOpSlot *slot_facemap_out = BMO_slot_get(op->slots_out, "face_map.out"); for (face = BMO_iter_new(&siter, op->slots_in, "faces", BM_FACE); face; face = BMO_iter_step(&siter)) { diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index dde3c526c13..b88bc51f586 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -57,7 +57,7 @@ void bmo_transform_exec(BMesh *UNUSED(bm), BMOperator *op) BMVert *v; float mat[4][4]; - BMO_slot_mat4_get(op->slots_in, "mat", mat); + BMO_slot_mat4_get(op->slots_in, "matrix", mat); BMO_ITER (v, &iter, op->slots_in, "verts", BM_VERT) { mul_m4_v3(mat, v->co); @@ -73,7 +73,7 @@ void bmo_translate_exec(BMesh *bm, BMOperator *op) unit_m4(mat); copy_v3_v3(mat[3], vec); - BMO_op_callf(bm, op->flag, "transform mat=%m4 verts=%s", mat, op, "verts"); + BMO_op_callf(bm, op->flag, "transform matrix=%m4 verts=%s", mat, op, "verts"); } void bmo_scale_exec(BMesh *bm, BMOperator *op) @@ -87,7 +87,7 @@ void bmo_scale_exec(BMesh *bm, BMOperator *op) mat[1][1] = vec[1]; mat[2][2] = vec[2]; - BMO_op_callf(bm, op->flag, "transform mat=%m3 verts=%s", mat, op, "verts"); + BMO_op_callf(bm, op->flag, "transform matrix=%m3 verts=%s", mat, op, "verts"); } void bmo_rotate_exec(BMesh *bm, BMOperator *op) @@ -102,7 +102,7 @@ void bmo_rotate_exec(BMesh *bm, BMOperator *op) mul_v3_fl(vec, -1.0f); BMO_op_callf(bm, op->flag, "translate verts=%s vec=%v", op, "verts", vec); - BMO_op_callf(bm, op->flag, "transform mat=%s verts=%s", op, "mat", op, "verts"); + BMO_op_callf(bm, op->flag, "transform matrix=%s verts=%s", op, "matrix", op, "verts"); mul_v3_fl(vec, -1.0f); BMO_op_callf(bm, op->flag, "translate verts=%s vec=%v", op, "verts", vec); diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 65d70e231a4..23f7c307356 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -109,7 +109,7 @@ static int add_primitive_plane_exec(bContext *C, wmOperator *op) em = BMEdit_FromObject(obedit); if (!EDBM_op_call_and_selectf(em, op, "verts.out", - "create_grid x_segments=%i y_segments=%i size=%f mat=%m4", 1, 1, dia, mat)) + "create_grid x_segments=%i y_segments=%i size=%f matrix=%m4", 1, 1, dia, mat)) { return OPERATOR_CANCELLED; } @@ -149,7 +149,7 @@ static int add_primitive_cube_exec(bContext *C, wmOperator *op) obedit = make_prim_init(C, "Cube", &dia, mat, &state, loc, rot, layer); em = BMEdit_FromObject(obedit); - if (!EDBM_op_call_and_selectf(em, op, "verts.out", "create_cube mat=%m4 size=%f", mat, dia * 2.0f)) { + if (!EDBM_op_call_and_selectf(em, op, "verts.out", "create_cube matrix=%m4 size=%f", mat, dia * 2.0f)) { return OPERATOR_CANCELLED; } @@ -199,7 +199,7 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op) em = BMEdit_FromObject(obedit); if (!EDBM_op_call_and_selectf(em, op, "verts.out", - "create_circle segments=%i diameter=%f cap_ends=%b cap_tris=%b mat=%m4", + "create_circle segments=%i diameter=%f cap_ends=%b cap_tris=%b matrix=%m4", RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius") * dia, cap_end, cap_tri, mat)) { @@ -254,7 +254,7 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op) if (!EDBM_op_call_and_selectf( em, op, "verts.out", - "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%m4", + "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f matrix=%m4", RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius") * dia, RNA_float_get(op->ptr, "radius") * dia, @@ -314,7 +314,7 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op) if (!EDBM_op_call_and_selectf( em, op, "verts.out", - "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%m4", + "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f matrix=%m4", RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius1") * dia, RNA_float_get(op->ptr, "radius2") * dia, cap_end, cap_tri, RNA_float_get(op->ptr, "depth") * dia, mat)) { @@ -369,7 +369,7 @@ static int add_primitive_grid_exec(bContext *C, wmOperator *op) em = BMEdit_FromObject(obedit); if (!EDBM_op_call_and_selectf(em, op, "verts.out", - "create_grid x_segments=%i y_segments=%i size=%f mat=%m4", + "create_grid x_segments=%i y_segments=%i size=%f matrix=%m4", RNA_int_get(op->ptr, "x_subdivisions"), RNA_int_get(op->ptr, "y_subdivisions"), RNA_float_get(op->ptr, "size") * dia, mat)) @@ -427,7 +427,7 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op) em = BMEdit_FromObject(obedit); - if (!EDBM_op_call_and_selectf(em, op, "verts.out", "create_monkey mat=%m4", mat)) { + if (!EDBM_op_call_and_selectf(em, op, "verts.out", "create_monkey matrix=%m4", mat)) { return OPERATOR_CANCELLED; } @@ -467,7 +467,7 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op) em = BMEdit_FromObject(obedit); if (!EDBM_op_call_and_selectf(em, op, "verts.out", - "create_uvsphere u_segments=%i v_segments=%i diameter=%f mat=%m4", + "create_uvsphere u_segments=%i v_segments=%i diameter=%f matrix=%m4", RNA_int_get(op->ptr, "segments"), RNA_int_get(op->ptr, "ring_count"), RNA_float_get(op->ptr, "size") * dia, mat)) { @@ -519,7 +519,7 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op) if (!EDBM_op_call_and_selectf( em, op, "verts.out", - "create_icosphere subdivisions=%i diameter=%f mat=%m4", + "create_icosphere subdivisions=%i diameter=%f matrix=%m4", RNA_int_get(op->ptr, "subdivisions"), RNA_float_get(op->ptr, "size") * dia, mat)) { diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index 3920d684243..62eabd98aee 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -314,9 +314,9 @@ static void ringsel_finish(bContext *C, wmOperator *op) const int cuts = RNA_int_get(op->ptr, "number_cuts"); const float smoothness = 0.292f * RNA_float_get(op->ptr, "smoothness"); #ifdef BMW_EDGERING_NGON - const int use_onlyquads = FALSE; + const int use_only_quads = FALSE; #else - const int use_onlyquads = TRUE; + const int use_only_quads = TRUE; #endif if (lcd->eed) { @@ -332,7 +332,7 @@ static void ringsel_finish(bContext *C, wmOperator *op) smoothness, 0.0f, 0.0f, cuts, SUBDIV_SELECT_LOOPCUT, SUBD_PATH, 0, TRUE, - use_onlyquads, 0); + use_only_quads, 0); /* force edge slide to edge select mode in in face select mode */ if (em->selectmode & SCE_SELECT_FACE) { diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index b3093e0be12..609470955ad 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -891,7 +891,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent } if (rot_src) { - EDBM_op_callf(vc.em, op, "rotate verts=%hv cent=%v mat=%m3", + EDBM_op_callf(vc.em, op, "rotate verts=%hv cent=%v matrix=%m3", BM_ELEM_SELECT, cent, mat); /* also project the source, for retopo workflow */ @@ -900,7 +900,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent } edbm_extrude_edge(vc.obedit, vc.em, BM_ELEM_SELECT, nor); - EDBM_op_callf(vc.em, op, "rotate verts=%hv cent=%v mat=%m3", + EDBM_op_callf(vc.em, op, "rotate verts=%hv cent=%v matrix=%m3", BM_ELEM_SELECT, cent, mat); EDBM_op_callf(vc.em, op, "translate verts=%hv vec=%v", BM_ELEM_SELECT, min); @@ -2891,7 +2891,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) float isect = 0.0f; int len = 0, isected, i; short numcuts = 1, mode = RNA_int_get(op->ptr, "type"); - BMOpSlot *slot_edgepercents; + BMOpSlot *slot_edge_percents; /* allocd vars */ float (*screen_vert_coords)[2], (*sco)[2], (*mouse_path)[2]; @@ -2946,7 +2946,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) } /* store percentage of edge cut for KNIFE_EXACT here.*/ - slot_edgepercents = BMO_slot_get(bmop.slots_in, "edgepercents"); + slot_edge_percents = BMO_slot_get(bmop.slots_in, "edge_percents"); for (be = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL); be; be = BM_iter_step(&iter)) { int is_cut = FALSE; if (BM_elem_flag_test(be, BM_ELEM_SELECT)) { @@ -2959,7 +2959,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) if (isect != 0.0f) { if (mode != KNIFE_MULTICUT && mode != KNIFE_MIDPOINT) { - BMO_slot_map_float_insert(&bmop, slot_edgepercents, be, isect); + BMO_slot_map_float_insert(&bmop, slot_edge_percents, be, isect); } } } @@ -2980,8 +2980,8 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) BMO_slot_int_set(bmop.slots_in, "cuts", numcuts); BMO_slot_int_set(bmop.slots_in, "quad_corner_type", SUBD_STRAIGHT_CUT); - BMO_slot_bool_set(bmop.slots_in, "use_singleedge", FALSE); - BMO_slot_bool_set(bmop.slots_in, "use_gridfill", FALSE); + BMO_slot_bool_set(bmop.slots_in, "use_single_edge", FALSE); + BMO_slot_bool_set(bmop.slots_in, "use_grid_fill", FALSE); BMO_slot_float_set(bmop.slots_in, "radius", 0); -- cgit v1.2.3 From c5a8bd498d59abec7d3fdc4123d8b5f0d121396d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 28 Nov 2012 00:47:33 +0000 Subject: use radians for 'spin' bmesh operator (since the rest of the py api uses radians). also rename BMO_OP_SLOT_SUBTYPE_MAP_FLOAT -> BMO_OP_SLOT_SUBTYPE_MAP_FLT for consistency. --- source/blender/bmesh/intern/bmesh_opdefines.c | 6 +++--- source/blender/bmesh/intern/bmesh_operator_api.h | 2 +- source/blender/bmesh/intern/bmesh_operator_api_inline.h | 4 ++-- source/blender/bmesh/operators/bmo_dupe.c | 2 +- source/blender/editors/mesh/editmesh_tools.c | 17 ++++++++--------- source/blender/python/bmesh/bmesh_py_ops_call.c | 4 ++-- 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 502dafeb5c3..5a25861a74a 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -887,7 +887,7 @@ static BMOpDefine bmo_dissolve_faces_def = { static BMOpDefine bmo_dissolve_limit_def = { "dissolve_limit", /* slots_in */ - {{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (degrees) */ + {{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */ {"use_dissolve_boundaries", BMO_OP_SLOT_BOOL}, {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, @@ -951,7 +951,7 @@ static BMOpDefine bmo_subdivide_edges_def = { {"cuts", BMO_OP_SLOT_INT}, {"seed", BMO_OP_SLOT_INT}, {"custom_patterns", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL}}, /* uses custom pointers */ - {"edge_percents", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_FLOAT}}, + {"edge_percents", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_FLT}}, {"quad_corner_type", BMO_OP_SLOT_INT}, /* quad corner type, see bmesh_operators.h */ {"use_grid_fill", BMO_OP_SLOT_BOOL}, /* fill in fully-selected faces with a grid */ @@ -1054,7 +1054,7 @@ static BMOpDefine bmo_spin_def = { {"cent", BMO_OP_SLOT_VEC}, /* rotation center */ {"axis", BMO_OP_SLOT_VEC}, /* rotation axis */ {"dvec", BMO_OP_SLOT_VEC}, /* translation delta per step */ - {"angle", BMO_OP_SLOT_FLT}, /* total rotation angle (degrees) */ + {"angle", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */ {"steps", BMO_OP_SLOT_INT}, /* number of steps */ {"use_duplicate", BMO_OP_SLOT_BOOL}, /* duplicate or extrude? */ {{'\0'}}, diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h index df67f459a34..7df9c94a2f1 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api.h +++ b/source/blender/bmesh/intern/bmesh_operator_api.h @@ -123,7 +123,7 @@ typedef enum eBMOpSlotSubType_Elem { typedef enum eBMOpSlotSubType_Map { BMO_OP_SLOT_SUBTYPE_MAP_EMPTY = 64, /* use as a set(), unused value */ BMO_OP_SLOT_SUBTYPE_MAP_ELEM = 65, - BMO_OP_SLOT_SUBTYPE_MAP_FLOAT = 66, + BMO_OP_SLOT_SUBTYPE_MAP_FLT = 66, BMO_OP_SLOT_SUBTYPE_MAP_INT = 67, BMO_OP_SLOT_SUBTYPE_MAP_BOOL = 68, BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL = 69, /* python can't convert these */ diff --git a/source/blender/bmesh/intern/bmesh_operator_api_inline.h b/source/blender/bmesh/intern/bmesh_operator_api_inline.h index 96c37b45b05..ad116011421 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api_inline.h +++ b/source/blender/bmesh/intern/bmesh_operator_api_inline.h @@ -87,7 +87,7 @@ BLI_INLINE void BMO_slot_map_bool_insert(BMOperator *op, BMOpSlot *slot, BLI_INLINE void BMO_slot_map_float_insert(BMOperator *op, BMOpSlot *slot, void *element, const float val) { - BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLOAT); + BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLT); BMO_slot_map_insert(op, slot, element, &val, sizeof(float)); } @@ -154,7 +154,7 @@ BLI_INLINE void *BMO_slot_map_data_get(BMOpSlot *slot, const void *element) BLI_INLINE float BMO_slot_map_float_get(BMOpSlot *slot, const void *element) { float *val; - BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLOAT); + BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLT); val = (float *) BMO_slot_map_data_get(slot, element); if (val) return *val; diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c index 76a9d571b20..67460a0298e 100644 --- a/source/blender/bmesh/operators/bmo_dupe.c +++ b/source/blender/bmesh/operators/bmo_dupe.c @@ -494,7 +494,7 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op) BMO_slot_vec_get(op->slots_in, "dvec", dvec); usedvec = !is_zero_v3(dvec); steps = BMO_slot_int_get(op->slots_in, "steps"); - phi = BMO_slot_float_get(op->slots_in, "angle") * DEG2RADF(1.0f) / steps; + phi = BMO_slot_float_get(op->slots_in, "angle") / steps; do_dupli = BMO_slot_bool_get(op->slots_in, "use_duplicate"); axis_angle_to_mat3(rmat, axis, phi); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 609470955ad..c1401ea430a 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -3636,14 +3636,14 @@ static int edbm_spin_exec(bContext *C, wmOperator *op) float cent[3], axis[3], imat[3][3]; float d[3] = {0.0f, 0.0f, 0.0f}; int steps, dupli; - float degr; + float angle; RNA_float_get_array(op->ptr, "center", cent); RNA_float_get_array(op->ptr, "axis", axis); steps = RNA_int_get(op->ptr, "steps"); - degr = RNA_float_get(op->ptr, "degrees"); + angle = RNA_float_get(op->ptr, "angle"); //if (ts->editbutflag & B_CLOCKWISE) - degr = -degr; + angle = -angle; dupli = RNA_boolean_get(op->ptr, "dupli"); /* undo object transformation */ @@ -3654,7 +3654,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op) if (!EDBM_op_init(em, &spinop, op, "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f use_duplicate=%b", - BM_ELEM_SELECT, cent, axis, d, steps, degr, dupli)) + BM_ELEM_SELECT, cent, axis, d, steps, angle, dupli)) { return OPERATOR_CANCELLED; } @@ -3685,6 +3685,8 @@ static int edbm_spin_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) void MESH_OT_spin(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Spin"; ot->description = "Extrude selected vertices in a circle around the cursor in indicated viewport"; @@ -3701,7 +3703,8 @@ void MESH_OT_spin(wmOperatorType *ot) /* props */ RNA_def_int(ot->srna, "steps", 9, 0, INT_MAX, "Steps", "Steps", 0, INT_MAX); RNA_def_boolean(ot->srna, "dupli", 0, "Dupli", "Make Duplicates"); - RNA_def_float(ot->srna, "degrees", 90.0f, -FLT_MAX, FLT_MAX, "Degrees", "Degrees", -360.0f, 360.0f); + prop = RNA_def_float(ot->srna, "angle", DEG2RADF(90.0f), -FLT_MAX, FLT_MAX, "Angle", "Angle", DEG2RADF(-360.0f), DEG2RADF(360.0f)); + RNA_def_property_subtype(prop, PROP_ANGLE); RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX); RNA_def_float_vector(ot->srna, "axis", 3, NULL, -FLT_MAX, FLT_MAX, "Axis", "Axis in global view space", -1.0f, 1.0f); @@ -3739,15 +3742,11 @@ static int edbm_screw_exec(bContext *C, wmOperator *op) v1 = NULL; v2 = NULL; for (eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL); eve; eve = BM_iter_step(&iter)) { - valence = 0; - for (eed = BM_iter_new(&eiter, em->bm, BM_EDGES_OF_VERT, eve); eed; eed = BM_iter_step(&eiter)) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { valence++; } - } if (valence == 1) { diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c index 13dc2eef3ce..c538daf9e51 100644 --- a/source/blender/python/bmesh/bmesh_py_ops_call.c +++ b/source/blender/python/bmesh/bmesh_py_ops_call.c @@ -387,7 +387,7 @@ static int bpy_slot_from_py(BMesh *bm, BMOperator *bmop, BMOpSlot *slot, PyObjec } break; } - case BMO_OP_SLOT_SUBTYPE_MAP_FLOAT: + case BMO_OP_SLOT_SUBTYPE_MAP_FLT: { if (PyDict_Size(value) > 0) { PyObject *arg_key, *arg_value; @@ -593,7 +593,7 @@ static PyObject* bpy_slot_to_py(BMesh *bm, BMOpSlot *slot) } break; } - case BMO_OP_SLOT_SUBTYPE_MAP_FLOAT: + case BMO_OP_SLOT_SUBTYPE_MAP_FLT: { item = PyDict_New(); if (slot_hash) { -- cgit v1.2.3 From 4fe35721e647126c6f929725d20064d279783ac3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 28 Nov 2012 01:14:11 +0000 Subject: bmesh operator api reference - add in 'bmesh' arg at the start of each operator, also use :class: references. --- doc/python_api/rst/bge.logic.rst | 40 +++++++++++------------ doc/python_api/rst_from_bmesh_opdefines.py | 41 +++++++++++++----------- release/scripts/modules/bpy_extras/mesh_utils.py | 6 ++-- 3 files changed, 47 insertions(+), 40 deletions(-) diff --git a/doc/python_api/rst/bge.logic.rst b/doc/python_api/rst/bge.logic.rst index acf28706709..7d20aa31a36 100644 --- a/doc/python_api/rst/bge.logic.rst +++ b/doc/python_api/rst/bge.logic.rst @@ -416,9 +416,9 @@ Sensor Status .. data:: KX_SENSOR_ACTIVE .. data:: KX_SENSOR_JUST_DEACTIVATED -------------- +--------------- Armature Sensor -------------- +--------------- .. _armaturesensor-type: @@ -537,9 +537,9 @@ See :class:`bge.types.BL_ActionActuator` .. data:: KX_ACTIONACT_LOOPEND .. data:: KX_ACTIONACT_PROPERTY ---------------- +----------------- Armature Actuator ---------------- +----------------- .. _armatureactuator-constants-type: @@ -556,13 +556,13 @@ See :class:`bge.types.BL_ArmatureActuator.type` .. data:: KX_ACT_ARMATURE_ENABLE Enable the constraint. - + :value: 1 .. data:: KX_ACT_ARMATURE_DISABLE Disable the constraint (runtime constraint values are not updated). - + :value: 2 .. data:: KX_ACT_ARMATURE_SETTARGET @@ -809,9 +809,9 @@ See :class:`bge.types.KX_SoundActuator` :value: 6 --------------- +----------------- Steering Actuator --------------- +----------------- .. _logic-steering-actuator: @@ -961,9 +961,9 @@ See :class:`bge.types.BL_ArmatureChannel.rotation_mode` :value: 6 ----------------- +------------------- Armature Constraint ----------------- +------------------- .. _armatureconstraint-constants-type: See :class:`bge.types.BL_ArmatureConstraint.type` @@ -1075,9 +1075,9 @@ See :class:`bge.types.SCA_PythonKeyboard`, :class:`bge.types.SCA_PythonMouse`, : .. data:: KX_INPUT_ACTIVE .. data:: KX_INPUT_JUST_RELEASED ------------- +------------- KX_GameObject ------------ +------------- .. _gameobject-playaction-mode: See :class:`bge.types.KX_GameObject.playAction` @@ -1111,9 +1111,9 @@ See :class:`bge.types.SCA_MouseSensor` .. data:: KX_MOUSE_BUT_MIDDLE .. data:: KX_MOUSE_BUT_RIGHT ------------- +-------------------------- Navigation Mesh Draw Modes ------------- +-------------------------- .. _navmesh-draw-mode: @@ -1199,25 +1199,25 @@ See :class:`bge.types.KX_StateActuator.operation` .. data:: KX_STATE_OP_CLR Substract bits to state mask - + :value: 0 .. data:: KX_STATE_OP_CPY Copy state mask - + :value: 1 .. data:: KX_STATE_OP_NEG Invert bits to state mask - + :value: 2 - + .. data:: KX_STATE_OP_SET Add bits to state mask - + :value: 3 - + .. _Two-D-FilterActuator-mode: diff --git a/doc/python_api/rst_from_bmesh_opdefines.py b/doc/python_api/rst_from_bmesh_opdefines.py index 5803315ff86..3077798cbef 100644 --- a/doc/python_api/rst_from_bmesh_opdefines.py +++ b/doc/python_api/rst_from_bmesh_opdefines.py @@ -38,8 +38,8 @@ FILE_OP_DEFINES_C = os.path.join(SOURCE_DIR, "source", "blender", "bmesh", "inte OUT_RST = os.path.join(CURRENT_DIR, "rst", "bmesh.ops.rst") HEADER = r""" -BMesh Operators -=============== +BMesh Operators (bmesh.ops) +=========================== .. module:: bmesh.ops @@ -123,7 +123,7 @@ def main(): "BMO_OP_SLOT_SUBTYPE_MAP_ELEM", "BMO_OP_SLOT_SUBTYPE_MAP_BOOL", "BMO_OP_SLOT_SUBTYPE_MAP_INT", - "BMO_OP_SLOT_SUBTYPE_MAP_FLOAT", + "BMO_OP_SLOT_SUBTYPE_MAP_FLT", "BMO_OP_SLOT_SUBTYPE_MAP_EMPTY", "BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL", @@ -211,7 +211,7 @@ def main(): if args_out is not None: args_out_index[:] = [i for (i, a) in enumerate(args_out) if type(a) == tuple] - fw(".. function:: %s(%s)\n\n" % (b[0], ", ".join([args_in[i][0] for i in args_in_index]))) + fw(".. function:: %s(bm, %s)\n\n" % (b[0], ", ".join([args_in[i][0] for i in args_in_index]))) # -- wash the comment comment_washed = [] @@ -233,7 +233,7 @@ def main(): # get the args - def get_args_wash(args, args_index): + def get_args_wash(args, args_index, is_ret): args_wash = [] for i in args_index: arg = args[i] @@ -277,20 +277,22 @@ def main(): elif tp == BMO_OP_SLOT_BOOL: tp_str = "bool" elif tp == BMO_OP_SLOT_MAT: - tp_str = "matrix" + tp_str = ":class:`mathutils.Matrix`" elif tp == BMO_OP_SLOT_VEC: - tp_str = "matrix" + tp_str = ":class:`mathutils.Vector`" + if not is_ret: + tp_str += " or any sequence of 3 floats" elif tp == BMO_OP_SLOT_PTR: tp_str = "dict" assert(tp_sub is not None) if tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_BMESH: - tp_str = "BMesh" + tp_str = ":class:`bmesh.types.BMesh`" elif tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_SCENE: - tp_str = "Scene" + tp_str = ":class:`bpy.types.Scene`" elif tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_OBJECT: - tp_str = "Object" + tp_str = ":class:`bpy.types.Object`" elif tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_MESH: - tp_str = "Mesh" + tp_str = ":class:`bpy.types.Mesh`" else: print("Cant find", vars_dict_reverse[tp_sub]) assert(0) @@ -299,9 +301,9 @@ def main(): assert(tp_sub is not None) ls = [] - if tp_sub & BM_VERT: ls.append("vert") - if tp_sub & BM_EDGE: ls.append("edge") - if tp_sub & BM_FACE: ls.append("face") + if tp_sub & BM_VERT: ls.append(":class:`bmesh.types.BMVert`") + if tp_sub & BM_EDGE: ls.append(":class:`bmesh.types.BMEdge`") + if tp_sub & BM_FACE: ls.append(":class:`bmesh.types.BMFace`") assert(ls) # must be at least one if tp_sub & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE: @@ -319,10 +321,10 @@ def main(): tp_str += "bool" elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_INT: tp_str += "int" - elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_FLOAT: + elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_FLT: tp_str += "float" elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_ELEM: - tp_str += "vert/edge/face elements" + tp_str += ":class:`bmesh.types.BMVert`/:class:`bmesh.types.BMEdge`/:class:`bmesh.types.BMFace`" elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL: tp_str += "unknown internal data, not compatible with python" else: @@ -336,9 +338,12 @@ def main(): return args_wash # end get_args_wash + # all ops get this arg + fw(" :arg bm: The bmesh to operate on.\n") + fw(" :type bm: :class:`bmesh.types.BMesh`\n") - args_in_wash = get_args_wash(args_in, args_in_index) - args_out_wash = get_args_wash(args_out, args_out_index) + args_in_wash = get_args_wash(args_in, args_in_index, False) + args_out_wash = get_args_wash(args_out, args_out_index, True) for (name, tp, comment) in args_in_wash: if comment == "": diff --git a/release/scripts/modules/bpy_extras/mesh_utils.py b/release/scripts/modules/bpy_extras/mesh_utils.py index 2042cc1c8a1..0166f954dc9 100644 --- a/release/scripts/modules/bpy_extras/mesh_utils.py +++ b/release/scripts/modules/bpy_extras/mesh_utils.py @@ -325,10 +325,12 @@ def ngon_tessellate(from_data, indices, fix_loops=True): fgon to create from existing verts. from_data: either a mesh, or a list/tuple of vectors. - indices: a list of indices to use this list is the ordered closed polyline + :arg indices: a list of indices to use this list is the ordered closed polyline to fill, and can be a subset of the data given. - fix_loops: If this is enabled polylines that use loops to make multiple + :type indices: list + :arg fix_loops: If this is enabled polylines that use loops to make multiple polylines are delt with correctly. + :type fix_loops: bool """ from mathutils.geometry import tessellate_polygon -- cgit v1.2.3 From e35b235925608df1a8b06e4047592a363c3e28e9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 28 Nov 2012 02:49:06 +0000 Subject: fix [#33320] Decimate modifer in collapse is inconsistent when limiting to a vertex group --- source/blender/bmesh/tools/bmesh_decimate.h | 3 +++ source/blender/bmesh/tools/bmesh_decimate_collapse.c | 13 ++++++------- source/blender/modifiers/intern/MOD_decimate.c | 6 ++++-- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/source/blender/bmesh/tools/bmesh_decimate.h b/source/blender/bmesh/tools/bmesh_decimate.h index 4d382d65659..4a557c20ae3 100644 --- a/source/blender/bmesh/tools/bmesh_decimate.h +++ b/source/blender/bmesh/tools/bmesh_decimate.h @@ -37,5 +37,8 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const int BMEdge **einput_arr, const int einput_len); void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const int do_dissolve_boundaries); +/* these weights are accumulated so too high values may reach 'inf' too quickly */ +#define BM_MESH_DECIM_WEIGHT_MAX 100000.0f +#define BM_MESH_DECIM_WEIGHT_EPS (1.0f / BM_MESH_DECIM_WEIGHT_MAX) #endif /* __BMESH_DECIMATE_H__ */ diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c index eeb1774b83b..02283aa6e28 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c +++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c @@ -223,8 +223,8 @@ static void bm_decim_build_edge_cost_single(BMEdge *e, } if (vweights) { - if ((vweights[BM_elem_index_get(e->v1)] < FLT_EPSILON) && - (vweights[BM_elem_index_get(e->v2)] < FLT_EPSILON)) + if ((vweights[BM_elem_index_get(e->v1)] >= BM_MESH_DECIM_WEIGHT_MAX) && + (vweights[BM_elem_index_get(e->v2)] >= BM_MESH_DECIM_WEIGHT_MAX)) { /* skip collapsing this edge */ eheap_table[BM_elem_index_get(e)] = NULL; @@ -244,8 +244,9 @@ static void bm_decim_build_edge_cost_single(BMEdge *e, BLI_quadric_evaluate(q2, optimize_co)); } else { - cost = ((BLI_quadric_evaluate(q1, optimize_co) * vweights[BM_elem_index_get(e->v1)]) + - (BLI_quadric_evaluate(q2, optimize_co) * vweights[BM_elem_index_get(e->v2)])); + /* add 1.0 so planar edges are still weighted against */ + cost = (((BLI_quadric_evaluate(q1, optimize_co) + 1.0f) * vweights[BM_elem_index_get(e->v1)]) + + ((BLI_quadric_evaluate(q2, optimize_co) + 1.0f) * vweights[BM_elem_index_get(e->v2)])); } // print("COST %.12f\n"); @@ -877,9 +878,7 @@ static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e, int i; if (vweights) { - const int fac = CLAMPIS(customdata_fac, 0.0f, 1.0f); - vweights[BM_elem_index_get(v_other)] = (vweights[v_clear_index] * (1.0f - fac)) + - (vweights[BM_elem_index_get(v_other)] * fac); + vweights[BM_elem_index_get(v_other)] = vweights[v_clear_index] + vweights[BM_elem_index_get(v_other)]; } e = NULL; /* paranoid safety check */ diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index 3f8eaa438c9..28cdfa810fa 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -145,12 +145,14 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, if (dmd->flag & MOD_DECIM_FLAG_INVERT_VGROUP) { for (i = 0; i < vert_tot; i++) { - vweights[i] = 1.0f - defvert_find_weight(&dvert[i], defgrp_index); + const float f = 1.0f - defvert_find_weight(&dvert[i], defgrp_index); + vweights[i] = f > BM_MESH_DECIM_WEIGHT_EPS ? (1.0f / f) : BM_MESH_DECIM_WEIGHT_MAX; } } else { for (i = 0; i < vert_tot; i++) { - vweights[i] = defvert_find_weight(&dvert[i], defgrp_index); + const float f = defvert_find_weight(&dvert[i], defgrp_index); + vweights[i] = f > BM_MESH_DECIM_WEIGHT_EPS ? (1.0f / f) : BM_MESH_DECIM_WEIGHT_MAX; } } } -- cgit v1.2.3 From 71e7f9028f683b39fcdb0549da908751bce2e4d2 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Wed, 28 Nov 2012 05:07:04 +0000 Subject: Copy face attributes when creating new faces in BMO_symmetrize Fixes bug [#33269] Symmetrize doesnt honor shadesmooth projects.blender.org/tracker/index.php?func=detail&aid=33269&group_id=9&atid=498 --- source/blender/bmesh/operators/bmo_symmetrize.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c b/source/blender/bmesh/operators/bmo_symmetrize.c index 71d9e3295c6..a58db1e6961 100644 --- a/source/blender/bmesh/operators/bmo_symmetrize.c +++ b/source/blender/bmesh/operators/bmo_symmetrize.c @@ -245,6 +245,8 @@ typedef struct { /* True only if none of the polygon's edges were split */ int already_symmetric; + + BMFace *src_face; } SymmPoly; static void symm_poly_with_splits(const Symm *symm, @@ -255,6 +257,8 @@ static void symm_poly_with_splits(const Symm *symm, BMLoop *l; int i; + out->src_face = f; + /* Count vertices and check for edge splits */ out->len = f->len; out->already_symmetric = TRUE; @@ -351,7 +355,8 @@ static int symm_poly_next_crossing(const Symm *symm, return FALSE; } -static BMFace *symm_face_create_v(BMesh *bm, BMVert **fv, BMEdge **fe, int len) +static BMFace *symm_face_create_v(BMesh *bm, BMFace *example, + BMVert **fv, BMEdge **fe, int len) { BMFace *f_new; int i; @@ -365,6 +370,8 @@ static BMFace *symm_face_create_v(BMesh *bm, BMVert **fv, BMEdge **fe, int len) } } f_new = BM_face_create(bm, fv, fe, len, TRUE); + if (example) + BM_elem_attrs_copy(bm, bm, example, f_new); BM_face_select_set(bm, f_new, TRUE); BMO_elem_flag_enable(bm, f_new, SYMM_OUTPUT_GEOM); return f_new; @@ -399,7 +406,7 @@ static void symm_mesh_output_poly_zero_splits(Symm *symm, } } - symm_face_create_v(symm->bm, fv, fe, j); + symm_face_create_v(symm->bm, sp->src_face, fv, fe, j); } static void symm_mesh_output_poly_with_splits(Symm *symm, @@ -422,7 +429,7 @@ static void symm_mesh_output_poly_with_splits(Symm *symm, fv[i] = v; } - symm_face_create_v(symm->bm, fv, fe, segment_len); + symm_face_create_v(symm->bm, sp->src_face, fv, fe, segment_len); /* Output the kill side of the input polygon */ @@ -434,7 +441,7 @@ static void symm_mesh_output_poly_with_splits(Symm *symm, } - symm_face_create_v(symm->bm, fv, fe, segment_len); + symm_face_create_v(symm->bm, sp->src_face, fv, fe, segment_len); } static void symm_mirror_polygons(Symm *symm) @@ -482,7 +489,7 @@ static void symm_mirror_polygons(Symm *symm) fv[i] = l->v; } - symm_face_create_v(symm->bm, fv, fe, f->len); + symm_face_create_v(symm->bm, f, fv, fe, f->len); } else if (ignore_all) { BM_face_kill(symm->bm, f); @@ -589,7 +596,7 @@ static void symm_mirror_polygons(Symm *symm) BLI_assert(fv[0] && fv[1] && fv[2]); - symm_face_create_v(symm->bm, fv, fe, 3); + symm_face_create_v(symm->bm, NULL, fv, fe, 3); } } } -- cgit v1.2.3 From 0b9be7059183fd7b4e8b567aeab5fec0cab1f999 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 28 Nov 2012 06:43:04 +0000 Subject: typo's and some style cleanup, also added asserts into BLI_vsnprintf and BLI_sprintfN when invalid args are given. --- release/scripts/modules/bl_i18n_utils/update_trunk.py | 2 +- release/scripts/modules/bpy_types.py | 2 +- release/scripts/modules/rna_xml.py | 2 +- release/scripts/startup/bl_operators/uvcalc_lightmap.py | 2 +- release/scripts/startup/bl_operators/uvcalc_smart_project.py | 2 +- source/blender/blenlib/intern/string.c | 6 ++++++ source/blender/bmesh/tools/bmesh_decimate_collapse.c | 2 +- source/blender/compositor/intern/COM_ExecutionGroup.h | 6 +++--- source/blender/editors/mesh/editmesh_loopcut.c | 2 +- source/blender/editors/mesh/editmesh_rip.c | 2 +- source/blender/editors/sculpt_paint/paint_image.c | 2 +- source/blender/editors/space_outliner/outliner_tree.c | 2 +- source/blender/editors/transform/transform_conversions.c | 2 +- source/blender/ikplugin/intern/ikplugin_api.c | 2 +- source/blender/windowmanager/intern/wm_operators.c | 2 +- 15 files changed, 22 insertions(+), 16 deletions(-) diff --git a/release/scripts/modules/bl_i18n_utils/update_trunk.py b/release/scripts/modules/bl_i18n_utils/update_trunk.py index 9b904ec861a..b84a227ae0a 100755 --- a/release/scripts/modules/bl_i18n_utils/update_trunk.py +++ b/release/scripts/modules/bl_i18n_utils/update_trunk.py @@ -115,7 +115,7 @@ def main(): if not os.path.exists(os.path.join(TRUNK_PO_DIR, ".".join((lang, "po")))): failed.add(lang) - # Check and compile each po separatly, to keep track of those failing. + # Check and compile each po separately, to keep track of those failing. # XXX There should not be any failing at this stage, import step is # supposed to have already filtered them out! for po in os.listdir(TRUNK_PO_DIR): diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index 4cd823d9184..e42ae43aed6 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -394,7 +394,7 @@ class Mesh(bpy_types.ID): p.vertices = f loop_index += loop_len - # if no edges - calculae them + # if no edges - calculate them if faces and (not edges): self.update(calc_edges=True) diff --git a/release/scripts/modules/rna_xml.py b/release/scripts/modules/rna_xml.py index fc8e3125228..e21ccd08a35 100644 --- a/release/scripts/modules/rna_xml.py +++ b/release/scripts/modules/rna_xml.py @@ -178,7 +178,7 @@ def rna2xml(fw=print_ln, fw("%s\n" % (ident, value_type_name)) # ------------------------------------------------------------------------- - # needs re-workign to be generic + # needs re-working to be generic if root_node: fw("%s<%s>\n" % (root_ident, root_node)) diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py index 526d78c4c11..198b3660ff8 100644 --- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py +++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py @@ -552,7 +552,7 @@ class LightMapPack(Operator): # Disable REGISTER flag for now because this operator might create new # images. This leads to non-proper operator redo because current undo # stack is local for edit mode and can not remove images created by this - # oprtator. + # operator. # Proper solution would be to make undo stack aware of such things, # but for now just disable redo. Keep undo here so unwanted changes to uv # coords might be undone. diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py index dd4ced78422..160ca5c6977 100644 --- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py +++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py @@ -993,7 +993,7 @@ def main(context, if mostUniqueAngle < USER_PROJECTION_LIMIT_CONVERTED: #print 'adding', mostUniqueAngle, USER_PROJECTION_LIMIT, len(newProjectMeshFaces) # Now weight the vector to all its faces, will give a more direct projection - # if the face its self was not representive of the normal from surrounding faces. + # if the face its self was not representative of the normal from surrounding faces. newProjectVec = tempMeshFaces[mostUniqueIndex].no newProjectMeshFaces = [tempMeshFaces.pop(mostUniqueIndex)] diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index 14e0dc2f049..f23f75f69d9 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -85,6 +85,10 @@ size_t BLI_vsnprintf(char *__restrict buffer, size_t count, const char *__restri { size_t n; + BLI_assert(buffer != NULL); + BLI_assert(count > 0); + BLI_assert(format != NULL); + n = vsnprintf(buffer, count, format, arg); if (n != -1 && n < count) { @@ -115,6 +119,8 @@ char *BLI_sprintfN(const char *__restrict format, ...) va_list arg; char *n; + BLI_assert(format != NULL); + va_start(arg, format); ds = BLI_dynstr_new(); diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c index 02283aa6e28..7c054d84405 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c +++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c @@ -878,7 +878,7 @@ static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e, int i; if (vweights) { - vweights[BM_elem_index_get(v_other)] = vweights[v_clear_index] + vweights[BM_elem_index_get(v_other)]; + vweights[BM_elem_index_get(v_other)] += vweights[v_clear_index]; } e = NULL; /* paranoid safety check */ diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h index c7a7d06134e..00104c24194 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.h +++ b/source/blender/compositor/intern/COM_ExecutionGroup.h @@ -193,7 +193,7 @@ private: /** * @brief try to schedule a specific chunk. - * @note scheduling succeeds when all input requirements are met and the chunks hasen't been scheduled yet. + * @note scheduling succeeds when all input requirements are met and the chunks hasn't been scheduled yet. * @param graph * @param xChunk * @param yChunk @@ -245,7 +245,7 @@ public: /** * @brief add an operation to this ExecutionGroup - * @note this method will add input of the operations recursivly + * @note this method will add input of the operations recursively * @note this method can create multiple ExecutionGroup's * @param system * @param operation @@ -369,7 +369,7 @@ public: /** * @brief this method determines the MemoryProxy's where this execution group depends on. * @note After this method determineDependingAreaOfInterest can be called to determine - * @note the area of the MemoryProxy.creator thas has to be executed. + * @note the area of the MemoryProxy.creator that has to be executed. * @param memoryProxies result */ void determineDependingMemoryProxies(vector *memoryProxies); diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index 62eabd98aee..dec45b7f326 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -332,7 +332,7 @@ static void ringsel_finish(bContext *C, wmOperator *op) smoothness, 0.0f, 0.0f, cuts, SUBDIV_SELECT_LOOPCUT, SUBD_PATH, 0, TRUE, - use_only_quads, 0); + use_only_quads, 0); /* force edge slide to edge select mode in in face select mode */ if (em->selectmode & SCE_SELECT_FACE) { diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index d3a4c951e06..2ecc20b2ddb 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -60,7 +60,7 @@ * * \param inset is used so we get some useful distance * when comparing multiple edges that meet at the same - * point and would result in teh same distance. + * point and would result in the same distance. */ #define INSET_DEFAULT 0.00001f static float edbm_rip_edgedist(ARegion *ar, float mat[][4], diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 676f033af32..a929c3ef585 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -656,7 +656,7 @@ static float VecZDepthPersp(const float pt[2], * barycentric_weights_v2 would return, in this case its easiest just to * undo the 4th axis division and make it unit-sum * - * don't call barycentric_weights_v2() becaue our callers expect 'w' + * don't call barycentric_weights_v2() because our callers expect 'w' * to be weighted from the perspective */ w_tmp[0] = w[0] * v1[3]; w_tmp[1] = w[1] * v2[3]; diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index af890a81ad6..e6910280da4 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -133,7 +133,7 @@ static void outliner_storage_cleanup(SpaceOops *soops) } /* XXX - THIS FUNCTION IS INCREDIBLY SLOW - * ... it can bring blenders tools and viewport to a grinding halt becuase of searching + * ... it can bring blenders tools and viewport to a grinding halt because of searching * for duplicate items every times they are added. * * TODO (possible speedups) diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 1cf01bc1bbc..51efa2b0e40 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -938,7 +938,7 @@ static short pose_grab_with_ik(Object *ob) } /* iTaSC needs clear for new IK constraints */ - if(tot_ik) + if (tot_ik) BIK_clear_data(ob->pose); return (tot_ik) ? 1 : 0; diff --git a/source/blender/ikplugin/intern/ikplugin_api.c b/source/blender/ikplugin/intern/ikplugin_api.c index efe07b2c48c..507d54d7526 100644 --- a/source/blender/ikplugin/intern/ikplugin_api.c +++ b/source/blender/ikplugin/intern/ikplugin_api.c @@ -86,7 +86,7 @@ static IKPlugin ikplugin_tab[] = { static IKPlugin *get_plugin(bPose *pose) { - if (!pose || pose->iksolver < 0 || pose->iksolver > (sizeof(ikplugin_tab)/sizeof(IKPlugin) - 2)) + if (!pose || pose->iksolver < 0 || pose->iksolver > (sizeof(ikplugin_tab) / sizeof(IKPlugin) - 2)) return NULL; return &ikplugin_tab[pose->iksolver]; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index c64cb339445..9968d81e7b4 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1215,7 +1215,7 @@ static int wm_operator_props_popup_ex(bContext *C, wmOperator *op, const int do_ /* if we don't have global undo, we can't do undo push for automatic redo, * so we require manual OK clicking in this popup */ - if(!(U.uiflag & USER_GLOBALUNDO)) + if (!(U.uiflag & USER_GLOBALUNDO)) return WM_operator_props_dialog_popup(C, op, 300, UI_UNIT_Y); ED_undo_push_op(C, op); -- cgit v1.2.3 From 2eb21ef30c37fb1ac6ab3c6485f0e65daa7a8fdf Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 28 Nov 2012 09:01:00 +0000 Subject: Fix #33295: Shifted movie strip when rendering <100% resolution for strip with complex transform That was kind of a regression since fix for #32091: Crop and offset coordinates changes proxy render settings on image strips, which is now fixed in other way. Namely Offset/Crop values are filling in 100% scene resolution values, but getting scaled to proxy / scene percentage values. --- source/blender/blenkernel/intern/sequencer.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index e023a3e20ae..1c94d18fc05 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -1835,6 +1835,8 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra, StripCrop c = {0}; StripTransform t = {0}; int sx, sy, dx, dy; + double xscale = 1.0; + double yscale = 1.0; if (is_proxy_image) { double f = seq_rendersize_to_scale_factor(context.preview_render_size); @@ -1851,6 +1853,17 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra, t = *seq->strip->transform; } + xscale = context.scene->r.xsch ? ((float) context.rectx / (float) context.scene->r.xsch) : 1.0; + yscale = context.scene->r.ysch ? ((float) context.recty / (float) context.scene->r.ysch) : 1.0; + + xscale /= (float) context.rectx / ibuf->x; + yscale /= (float) context.recty / ibuf->y; + + c.left *= xscale; c.right *= xscale; + c.top *= yscale; c.bottom *= yscale; + + t.xofs *= xscale; t.yofs *= yscale; + sx = ibuf->x - c.left - c.right; sy = ibuf->y - c.top - c.bottom; dx = sx; -- cgit v1.2.3 From 25b7d354846d1576979b42db1e26c1da927feea6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 28 Nov 2012 09:10:27 +0000 Subject: fix/workaround [#33309] small + in few windows text/image/compo were missing '+', toggling adds them. --- release/datafiles/startup.blend | Bin 410796 -> 415348 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/release/datafiles/startup.blend b/release/datafiles/startup.blend index 6bb34002977..cdd43c74f3b 100644 Binary files a/release/datafiles/startup.blend and b/release/datafiles/startup.blend differ -- cgit v1.2.3 From b91cf6096275acc97a7df7840f745f2d262f054f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 28 Nov 2012 09:36:23 +0000 Subject: Fix #33330: Proxies are not built in Sequencer if preview is visible Was own regression when was solving conflict between sequencer preview and compositor jobs. Made it so now only compositor jobs are being killed from sequencer preview. --- source/blender/editors/space_sequencer/sequencer_draw.c | 2 +- source/blender/windowmanager/WM_api.h | 5 +++-- source/blender/windowmanager/intern/wm_jobs.c | 12 ++++++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 5fefafaa54a..1a84efa0b50 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -926,7 +926,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq /* stop all running jobs, except screen one. currently previews frustrate Render * needed to make so sequencer's rendering doesn't conflict with compositor */ - WM_jobs_kill_all_except(CTX_wm_manager(C), CTX_wm_screen(C)); + WM_jobs_kill_type(CTX_wm_manager(C), WM_JOB_TYPE_COMPOSITE); } render_size = sseq->render_size; diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index e35e3edfa33..1037542759f 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -360,8 +360,9 @@ void WM_jobs_start(struct wmWindowManager *wm, struct wmJob *); void WM_jobs_stop(struct wmWindowManager *wm, void *owner, void *startjob); void WM_jobs_kill(struct wmWindowManager *wm, void *owner, void (*)(void *, short int *, short int *, float *)); void WM_jobs_kill_all(struct wmWindowManager *wm); - void WM_jobs_kill_all_except(struct wmWindowManager *wm, void *owner); - +void WM_jobs_kill_all_except(struct wmWindowManager *wm, void *owner); +void WM_jobs_kill_type(struct wmWindowManager *wm, int job_type); + int WM_jobs_has_running(struct wmWindowManager *wm); /* clipboard */ diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index 7481c01d72b..3c3e2c0feaa 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -416,6 +416,18 @@ void WM_jobs_kill_all_except(wmWindowManager *wm, void *owner) } +void WM_jobs_kill_type(struct wmWindowManager *wm, int job_type) +{ + wmJob *wm_job, *next_job; + + for (wm_job = wm->jobs.first; wm_job; wm_job = next_job) { + next_job = wm_job->next; + + if (wm_job->job_type == job_type) + wm_jobs_kill_job(wm, wm_job); + } +} + /* signal job(s) from this owner or callback to stop, timer is required to get handled */ void WM_jobs_stop(wmWindowManager *wm, void *owner, void *startjob) { -- cgit v1.2.3 From a8905364c31955e3db8257f8d6a45cc8d49c836f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 28 Nov 2012 09:49:26 +0000 Subject: Typo fix in comment. No functional changes. --- intern/guardedalloc/intern/mallocn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c index a65871f4410..4a79f5d0de1 100644 --- a/intern/guardedalloc/intern/mallocn.c +++ b/intern/guardedalloc/intern/mallocn.c @@ -58,7 +58,7 @@ * store original buffer's name when doing MEM_dupallocN * helpful to profile issues with non-freed "dup_alloc" buffers, * but this introduces some overhead to memory header and makes - * things slower a bit, so betterto keep disabled by default + * things slower a bit, so better to keep disabled by default */ //#define DEBUG_MEMDUPLINAME -- cgit v1.2.3 From 1212237ae415caf77df6df544f14e92a412f21cc Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 28 Nov 2012 13:20:45 +0000 Subject: Fix normal compositing/shader node not showing normal widget. It would actually show after save and reload, the subtype and min/max were not properly initialized for node output sockets. --- source/blender/nodes/intern/node_socket.c | 57 +++++++++++++++++-------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/source/blender/nodes/intern/node_socket.c b/source/blender/nodes/intern/node_socket.c index 0335d295fba..69256fafc3d 100644 --- a/source/blender/nodes/intern/node_socket.c +++ b/source/blender/nodes/intern/node_socket.c @@ -473,6 +473,35 @@ void node_socket_convert_default_value(int to_type, void *to_default_value, int } } +static void node_socket_set_minmax_subtype(bNodeSocket *sock, struct bNodeSocketTemplate *stemp) +{ + switch (sock->type) { + case SOCK_FLOAT: + { + bNodeSocketValueFloat *dval= sock->default_value; + dval->min = stemp->min; + dval->max = stemp->max; + dval->subtype = stemp->subtype; + break; + } + case SOCK_INT: + { + bNodeSocketValueInt *dval= sock->default_value; + dval->min = stemp->min; + dval->max = stemp->max; + dval->subtype = stemp->subtype; + break; + } + case SOCK_VECTOR: + { + bNodeSocketValueVector *dval= sock->default_value; + dval->min = stemp->min; + dval->max = stemp->max; + dval->subtype = stemp->subtype; + break; + } + } +} struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp) { @@ -512,6 +541,7 @@ struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct struct bNodeSocket *node_add_output_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp) { bNodeSocket *sock = nodeAddSocket(ntree, node, SOCK_OUT, stemp->name, stemp->type); + node_socket_set_minmax_subtype(sock, stemp); return sock; } @@ -532,32 +562,7 @@ static bNodeSocket *verify_socket_template(bNodeTree *ntree, bNode *node, int in /* Copy the property range and subtype parameters in case the template changed. * NOT copying the actual value here, only button behavior changes! */ - switch (sock->type) { - case SOCK_FLOAT: - { - bNodeSocketValueFloat *dval= sock->default_value; - dval->min = stemp->min; - dval->max = stemp->max; - dval->subtype = stemp->subtype; - break; - } - case SOCK_INT: - { - bNodeSocketValueInt *dval= sock->default_value; - dval->min = stemp->min; - dval->max = stemp->max; - dval->subtype = stemp->subtype; - break; - } - case SOCK_VECTOR: - { - bNodeSocketValueVector *dval= sock->default_value; - dval->min = stemp->min; - dval->max = stemp->max; - dval->subtype = stemp->subtype; - break; - } - } + node_socket_set_minmax_subtype(sock, stemp); BLI_remlink(socklist, sock); -- cgit v1.2.3 From 406d680cee729171aba59dd079229e9c267f1ebb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 28 Nov 2012 13:27:12 +0000 Subject: Dependency builder: fixed sources directory not creating in some cases --- build_files/build_environment/install_deps.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 935f37b53da..b97fb283182 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -407,6 +407,7 @@ compile_OIIO() { prepare_opt if [ ! -d $_src ]; then + mkdir -p $SRC wget -c $OIIO_SOURCE -O "$_src.tar.gz" INFO "Unpacking OpenImageIO-$OIIO_VERSION" @@ -513,6 +514,7 @@ compile_LLVM() { prepare_opt if [ ! -d $_src -o true ]; then + mkdir -p $SRC wget -c $LLVM_SOURCE -O "$_src.tar.gz" wget -c $LLVM_CLANG_SOURCE -O "$_src_clang.tar.gz" @@ -603,6 +605,8 @@ compile_OSL() { prepare_opt if [ ! -d $_src ]; then + mkdir -p $SRC + # XXX Using git on my own repo for now, looks like archives are not updated immediately... :/ # wget -c $OSL_SOURCE -O "$_src.tar.gz" @@ -692,6 +696,7 @@ compile_FFmpeg() { if [ ! -d $_src ]; then INFO "Downloading ffmpeg-$FFMPEG_VERSION" + mkdir -p $SRC wget -c $FFMPEG_SOURCE -O "$_src.tar.bz2" INFO "Unpacking ffmpeg-$FFMPEG_VERSION" -- cgit v1.2.3 From 8d4741b5011cb53454ba554c884ac262ac519762 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 28 Nov 2012 13:34:44 +0000 Subject: Dependency builder: reduce amount of needed sudo commands by checking permissions for $INST folder --- build_files/build_environment/install_deps.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index b97fb283182..4e5a5c29675 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -188,9 +188,14 @@ detect_distro() { prepare_opt() { INFO "Ensuring $INST exists and is writable by us" - sudo mkdir -p $INST - sudo chown $USER $INST - sudo chmod 775 $INST + if [ ! -d $INST ]; then + sudo mkdir -p $INST + fi + + if [ ! -w $INST ]; then + sudo chown $USER $INST + sudo chmod 775 $INST + fi } # Check whether the current package needs to be recompiled, based on a dummy file containing a magic number in its name... -- cgit v1.2.3 From cac253a50236af8e8f427a2bf00d8dbdb1dee6e0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 28 Nov 2012 14:15:54 +0000 Subject: fix for minor annoyance - when extruding a circle there would always be one face flipped, now edges are all ordered in the same direction. --- source/blender/bmesh/operators/bmo_primitive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c index 38096b4ca6f..b8f154350ea 100644 --- a/source/blender/bmesh/operators/bmo_primitive.c +++ b/source/blender/bmesh/operators/bmo_primitive.c @@ -560,7 +560,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op) if (!a) return; - BM_edge_create(bm, lastv1, firstv1, NULL, FALSE); + BM_edge_create(bm, firstv1, lastv1, NULL, FALSE); if (cap_ends) { BMFace *f; -- cgit v1.2.3 From 96136d3d888289bdde6101469e53bcdf391ee554 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 28 Nov 2012 15:07:57 +0000 Subject: bmesh operator py api: - fix for incorrect bmesh operator type-check for mapping slots. - fix for python causing an assert when invalid args are given. - fix memory leak with some exceptions. --- source/blender/python/bmesh/bmesh_py_ops_call.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c index c538daf9e51..ded35363287 100644 --- a/source/blender/python/bmesh/bmesh_py_ops_call.c +++ b/source/blender/python/bmesh/bmesh_py_ops_call.c @@ -584,8 +584,6 @@ static PyObject* bpy_slot_to_py(BMesh *bm, BMOpSlot *slot) PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key); PyObject *py_val = BPy_BMElem_CreatePyObject(bm, *(void **)BMO_OP_SLOT_MAPPING_DATA(ele_val)); - BLI_assert(slot->slot_subtype.elem & ((BPy_BMElem *)py_val)->ele->head.htype); - PyDict_SetItem(item, py_key, py_val); Py_DECREF(py_key); Py_DECREF(py_val); @@ -714,19 +712,23 @@ PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw) Py_ssize_t pos = 0; while (PyDict_Next(kw, &pos, &key, &value)) { const char *slot_name = _PyUnicode_AsString(key); - BMOpSlot *slot = BMO_slot_get(bmop.slots_in, slot_name); + BMOpSlot *slot; - if (slot == NULL) { + if (!BMO_slot_exists(bmop.slots_in, slot_name)) { PyErr_Format(PyExc_TypeError, "%.200s: keyword \"%.200s\" is invalid for this operator", self->opname, slot_name); + BMO_op_finish(bm, &bmop); return NULL; } + slot = BMO_slot_get(bmop.slots_in, slot_name); + /* now assign the value */ if (bpy_slot_from_py(bm, &bmop, slot, value, self->opname, slot_name) == -1) { + BMO_op_finish(bm, &bmop); return NULL; } } -- cgit v1.2.3 From f828a318f5f77e4e167b2c4d5efd45460b239288 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 28 Nov 2012 15:08:45 +0000 Subject: include an example in the api docs for using bmesh operators to make 2 links in a chain. --- doc/python_api/examples/bmesh.ops.1.py | 106 +++++++++++++++++++++++++++++ doc/python_api/rst_from_bmesh_opdefines.py | 5 ++ 2 files changed, 111 insertions(+) create mode 100644 doc/python_api/examples/bmesh.ops.1.py diff --git a/doc/python_api/examples/bmesh.ops.1.py b/doc/python_api/examples/bmesh.ops.1.py new file mode 100644 index 00000000000..2eefb63a23d --- /dev/null +++ b/doc/python_api/examples/bmesh.ops.1.py @@ -0,0 +1,106 @@ +# This script uses bmesh operators to make 2 links of a chain. + +import bpy +import bmesh +import math +import mathutils + +# Make a new BMesh +bm = bmesh.new() + +# Add a circle XXX, should return all geometry created, not just verts. +bmesh.ops.create_circle( + bm, + cap_ends=False, + diameter=0.2, + segments=8) + + +# Spin and deal with geometry on side 'a' +edges_start_a = bm.edges[:] +geom_start_a = bm.verts[:] + edges_start_a +ret = bmesh.ops.spin( + bm, + geom=geom_start_a, + angle=math.radians(180.0), + steps=8, + axis=(1.0, 0.0, 0.0), + cent=(0.0, 1.0, 0.0)) +edges_end_a = [ele for ele in ret["geom_last"] + if isinstance(ele, bmesh.types.BMEdge)] +del ret + + +# Extrude and create geometry on side 'b' +ret = bmesh.ops.extrude_edge_only( + bm, + edges=edges_start_a) +geom_extrude_mid = ret["geom"] +del ret + + +# Collect the edges to spin XXX, 'extrude_edge_only' could return this. +verts_extrude_b = [ele for ele in geom_extrude_mid + if isinstance(ele, bmesh.types.BMVert)] +edges_extrude_b = [ele for ele in geom_extrude_mid + if isinstance(ele, bmesh.types.BMEdge) and ele.is_boundary] +bmesh.ops.translate( + bm, + verts=verts_extrude_b, + vec=(0.0, 0.0, 1.0)) + + +# Create the circle on side 'b' +ret = bmesh.ops.spin( + bm, + geom=verts_extrude_b + edges_extrude_b, + angle=-math.radians(180.0), + steps=8, + axis=(1.0, 0.0, 0.0), + cent=(0.0, 1.0, 1.0)) +edges_end_b = [ele for ele in ret["geom_last"] + if isinstance(ele, bmesh.types.BMEdge)] +del ret + + +# Bridge the resulting edge loops of both spins 'a & b' +bmesh.ops.bridge_loops( + bm, + edges=edges_end_a + edges_end_b) + + +# Now we have made a links of the chain, make a copy and rotate it +# (so this looks something like a chain) + +ret = bmesh.ops.duplicate( + bm, + geom=bm.verts[:] + bm.edges[:] + bm.faces[:]) +geom_dupe = ret["geom"] +verts_dupe = [ele for ele in geom_dupe if isinstance(ele, bmesh.types.BMVert)] +del ret + +# position the new link +bmesh.ops.translate( + bm, + verts=verts_dupe, + vec=(0.0, 0.0, 2.0)) +bmesh.ops.rotate( + bm, + verts=verts_dupe, + cent=(0.0, 1.0, 0.0), + matrix=mathutils.Matrix.Rotation(math.radians(90.0), 3, 'Z')) + +# Done with creating the mesh, simply link it into the scene so we can see it + +# Finish up, write the bmesh into a new mesh +me = bpy.data.meshes.new("Mesh") +bm.to_mesh(me) + +# Add the mesh to the scene +scene = bpy.context.scene +obj = bpy.data.objects.new("Object", me) +scene.objects.link(obj) + +# Select and make active +scene.objects.active = obj +obj.select = True diff --git a/doc/python_api/rst_from_bmesh_opdefines.py b/doc/python_api/rst_from_bmesh_opdefines.py index 3077798cbef..c1b6643389d 100644 --- a/doc/python_api/rst_from_bmesh_opdefines.py +++ b/doc/python_api/rst_from_bmesh_opdefines.py @@ -53,6 +53,11 @@ to perform useful operations. This API us new in 2.65 and not yet well tested. +Operator Example +++++++++++++++++ +This script shows how operators can be used to model a link of a chain. + +.. literalinclude:: ../examples/bmesh.ops.1.py """ -- cgit v1.2.3 From 33f451838aa3a4527f41dc5932c511bc8d1987f8 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 28 Nov 2012 16:19:45 +0000 Subject: For sure buildbot's release buildflags should include -DNDEBUG, otherwise asserts will abort execution for release builds. --- build_files/buildbot/config/user-config-glibc211-i686.py | 2 +- build_files/buildbot/config/user-config-glibc211-x86_64.py | 2 +- build_files/buildbot/config/user-config-glibc27-i686.py | 2 +- build_files/buildbot/config/user-config-glibc27-x86_64.py | 2 +- build_files/buildbot/config/user-config-player-glibc211-i686.py | 2 +- build_files/buildbot/config/user-config-player-glibc211-x86_64.py | 2 +- build_files/buildbot/config/user-config-player-glibc27-i686.py | 2 +- build_files/buildbot/config/user-config-player-glibc27-x86_64.py | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build_files/buildbot/config/user-config-glibc211-i686.py b/build_files/buildbot/config/user-config-glibc211-i686.py index e5afa2afe13..fa9122f732e 100644 --- a/build_files/buildbot/config/user-config-glibc211-i686.py +++ b/build_files/buildbot/config/user-config-glibc211-i686.py @@ -160,6 +160,6 @@ WITH_BF_OCEANSIM = True # Compilation and optimization BF_DEBUG = False -REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++ +REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++ PLATFORM_LINKFLAGS = ['-lrt'] BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map'] diff --git a/build_files/buildbot/config/user-config-glibc211-x86_64.py b/build_files/buildbot/config/user-config-glibc211-x86_64.py index dc901d25a92..420d9ed4db9 100644 --- a/build_files/buildbot/config/user-config-glibc211-x86_64.py +++ b/build_files/buildbot/config/user-config-glibc211-x86_64.py @@ -159,6 +159,6 @@ WITH_BF_OCEANSIM = True # Compilation and optimization BF_DEBUG = False -REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++ +REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++ PLATFORM_LINKFLAGS = ['-lrt'] BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map'] diff --git a/build_files/buildbot/config/user-config-glibc27-i686.py b/build_files/buildbot/config/user-config-glibc27-i686.py index dd3a63d0fd7..f359c09c887 100644 --- a/build_files/buildbot/config/user-config-glibc27-i686.py +++ b/build_files/buildbot/config/user-config-glibc27-i686.py @@ -145,6 +145,6 @@ WITH_BF_OCEANSIM = True # Compilation and optimization BF_DEBUG = False -REL_CCFLAGS = ['-O2'] # C & C++ +REL_CCFLAGS = ['-DNDEBUG', '-DNDEBUG', '-O2'] # C & C++ PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib32'] BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map'] diff --git a/build_files/buildbot/config/user-config-glibc27-x86_64.py b/build_files/buildbot/config/user-config-glibc27-x86_64.py index d9e50d258bc..7359e155586 100644 --- a/build_files/buildbot/config/user-config-glibc27-x86_64.py +++ b/build_files/buildbot/config/user-config-glibc27-x86_64.py @@ -144,6 +144,6 @@ WITH_BF_OCEANSIM = True # Compilation and optimization BF_DEBUG = False -REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++ +REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++ PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib64'] BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map'] diff --git a/build_files/buildbot/config/user-config-player-glibc211-i686.py b/build_files/buildbot/config/user-config-player-glibc211-i686.py index 00bfdbb16f2..96f201235c4 100644 --- a/build_files/buildbot/config/user-config-player-glibc211-i686.py +++ b/build_files/buildbot/config/user-config-player-glibc211-i686.py @@ -117,5 +117,5 @@ WITH_BF_OCEANSIM = True # Compilation and optimization BF_DEBUG = False -REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++ +REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++ PLATFORM_LINKFLAGS = ['-lrt'] diff --git a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py index f6eef4f89d9..75979d0bcfe 100644 --- a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py +++ b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py @@ -117,5 +117,5 @@ WITH_BF_OCEANSIM = True # Compilation and optimization BF_DEBUG = False -REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++ +REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++ PLATFORM_LINKFLAGS = ['-lrt'] diff --git a/build_files/buildbot/config/user-config-player-glibc27-i686.py b/build_files/buildbot/config/user-config-player-glibc27-i686.py index 1e834c0c8d2..82b105c4527 100644 --- a/build_files/buildbot/config/user-config-player-glibc27-i686.py +++ b/build_files/buildbot/config/user-config-player-glibc27-i686.py @@ -110,5 +110,5 @@ WITH_BF_OCEANSIM = True # Compilation and optimization BF_DEBUG = False -REL_CCFLAGS = ['-O2'] # C & C++ +REL_CCFLAGS = ['-DNDEBUG', '-O2'] # C & C++ PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib32'] diff --git a/build_files/buildbot/config/user-config-player-glibc27-x86_64.py b/build_files/buildbot/config/user-config-player-glibc27-x86_64.py index aa0a69c44d8..1e6aa4af802 100644 --- a/build_files/buildbot/config/user-config-player-glibc27-x86_64.py +++ b/build_files/buildbot/config/user-config-player-glibc27-x86_64.py @@ -110,5 +110,5 @@ WITH_BF_OCEANSIM = True # Compilation and optimization BF_DEBUG = False -REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++ +REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++ PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib64'] -- cgit v1.2.3 From 4c1363358255d4d11d8974df1ecf1cc8b32b8736 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 28 Nov 2012 16:42:32 +0000 Subject: Fix #33334: missing glossy label for OSL phong ramp caused assert. --- intern/cycles/kernel/closure/bsdf_phong_ramp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/kernel/closure/bsdf_phong_ramp.h b/intern/cycles/kernel/closure/bsdf_phong_ramp.h index a2df77c2d2b..575a798aed4 100644 --- a/intern/cycles/kernel/closure/bsdf_phong_ramp.h +++ b/intern/cycles/kernel/closure/bsdf_phong_ramp.h @@ -131,7 +131,7 @@ __device int bsdf_phong_ramp_sample(const ShaderClosure *sc, const float3 colors } } } - return LABEL_REFLECT; + return LABEL_REFLECT|LABEL_GLOSSY; } -- cgit v1.2.3 From 0aad9f674a1fcdd983946e8b3e011157492495a8 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 28 Nov 2012 16:42:39 +0000 Subject: Move to Layer: optimization so that the first change in the popup menu does not do an undo push & undo step, there's no reason this is needed. In principle this particular operator doesn't ever need an undo on changes, even for further steps, but that's harder to solve. --- source/blender/windowmanager/intern/wm_operators.c | 35 ++++++++++++++-------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 9968d81e7b4..80ceb5700e5 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1025,6 +1025,23 @@ wmOperator *WM_operator_last_redo(const bContext *C) return op; } +static void wm_block_redo_cb(bContext *C, void *arg_op, int UNUSED(arg_event)) +{ + wmOperator *op = arg_op; + + if (op == WM_operator_last_redo(C)) { + /* operator was already executed once? undo & repeat */ + ED_undo_operator_repeat(C, op); + } + else { + /* operator not executed yet, call it */ + ED_undo_push_op(C, op); + wm_operator_register(C, op); + + WM_operator_repeat(C, op); + } +} + static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) { wmOperator *op = arg_op; @@ -1032,7 +1049,6 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) uiLayout *layout; uiStyle *style = UI_GetStyle(); int width = 300; - block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); uiBlockClearFlag(block, UI_BLOCK_LOOP); @@ -1042,11 +1058,12 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) * ui_apply_but_funcs_after calls ED_undo_operator_repeate_cb and crashes */ assert(op->type->flag & OPTYPE_REGISTER); - uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, arg_op); + uiBlockSetHandleFunc(block, wm_block_redo_cb, arg_op); layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, width, UI_UNIT_Y, style); - if (!WM_operator_check_ui_enabled(C, op->type->name)) - uiLayoutSetEnabled(layout, FALSE); + if (op == WM_operator_last_redo(C)) + if (!WM_operator_check_ui_enabled(C, op->type->name)) + uiLayoutSetEnabled(layout, FALSE); if (op->type->flag & OPTYPE_MACRO) { for (op = op->macro.first; op; op = op->next) { @@ -1058,7 +1075,6 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE); } - uiPopupBoundsBlock(block, 4, 0, 0); uiEndBlock(C, block); @@ -1218,15 +1234,10 @@ static int wm_operator_props_popup_ex(bContext *C, wmOperator *op, const int do_ if (!(U.uiflag & USER_GLOBALUNDO)) return WM_operator_props_dialog_popup(C, op, 300, UI_UNIT_Y); - ED_undo_push_op(C, op); - - wm_operator_register(C, op); - uiPupBlock(C, wm_block_create_redo, op); - if (do_call) { - WM_operator_repeat(C, op); - } + if (do_call) + wm_block_redo_cb(C, op, 0); return OPERATOR_RUNNING_MODAL; } -- cgit v1.2.3 From 33f81187fbe1da71e0612b425f441ccad01ae0d2 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 28 Nov 2012 19:13:34 +0000 Subject: Fix #33335: cycles SVM closure issue in recent bugfix, incorrectly tagging node as done. --- intern/cycles/render/svm.cpp | 18 +++++++++++------- intern/cycles/render/svm.h | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index 50b3bb59ed4..4acd174e60f 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -487,7 +487,7 @@ void SVMCompiler::generate_closure(ShaderNode *node, set& done) } } -void SVMCompiler::generate_multi_closure(ShaderNode *node, set& done) +void SVMCompiler::generate_multi_closure(ShaderNode *node, set& done, set& closure_done) { /* todo: the weaks point here is that unlike the single closure sampling * we will evaluate all nodes even if they are used as input for closures @@ -495,10 +495,10 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set& don * nodes at runtime, especially if they are tangled up */ /* only generate once */ - if(done.find(node) != done.end()) + if(closure_done.find(node) != closure_done.end()) return; - done.insert(node); + closure_done.insert(node); if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) { /* weighting is already taken care of in ShaderGraph::transform_multi_closure */ @@ -506,9 +506,9 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set& don ShaderInput *cl2in = node->input("Closure2"); if(cl1in->link) - generate_multi_closure(cl1in->link->parent, done); + generate_multi_closure(cl1in->link->parent, done, closure_done); if(cl2in->link) - generate_multi_closure(cl2in->link->parent, done); + generate_multi_closure(cl2in->link->parent, done, closure_done); } else { /* execute dependencies for closure */ @@ -543,6 +543,8 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set& don if(node->name == ustring("transparent")) current_shader->has_surface_transparent = true; } + + done.insert(node); } @@ -613,8 +615,10 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty if(generate) { set done; - if(use_multi_closure) - generate_multi_closure(clin->link->parent, done); + if(use_multi_closure) { + set closure_done; + generate_multi_closure(clin->link->parent, done, closure_done); + } else generate_closure(clin->link->parent, done); } diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h index 720531c8c4b..0b15c5aaa1e 100644 --- a/intern/cycles/render/svm.h +++ b/intern/cycles/render/svm.h @@ -130,7 +130,7 @@ protected: void generate_closure(ShaderNode *node, set& done); /* multi closure */ - void generate_multi_closure(ShaderNode *node, set& done); + void generate_multi_closure(ShaderNode *node, set& done, set& closure_done); /* compile */ void compile_type(Shader *shader, ShaderGraph *graph, ShaderType type); -- cgit v1.2.3 From 777449029b4f40b676a19d8a12228650f49c26c2 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 28 Nov 2012 19:37:37 +0000 Subject: Seems cmake in debian squeeze is broken and fails to handle BOOST_ROOT I would recommend using debian-backports repo for cmake --- build_files/build_environment/install_deps.sh | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 4e5a5c29675..9d01ed744c0 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -821,6 +821,29 @@ install_DEB() { INFO "$COMMON_INFO" INFO "" + if [ ! -z "`cat /etc/debian_version | grep ^6`" ]; then + if [ -z "`cat /etc/apt/sources.list | grep backports.debian.org`" ]; then + INFO "Looks like you're using Debian Squeeze which does have broken CMake" + INFO "It is highly recommended to install cmake from backports, otherwise" + INFO "compilation of some libraries could fail" + INFO "" + INFO "You could install newer CMake from debian-backports repository" + INFO "Add this this line to your /etc/apt/sources.lixt:" + INFO "" + INFO "deb http://backports.debian.org/debian-backports squeeze-backports main" + INFO "" + INFO "and then run:" + INFO "" + INFO "sudo apt-get update && sudo apt-get install cmake=2.8.7-4~bpo60+1 sudo apt-get install cmake=2.8.7-4~bpo60+1" + INFO "" + INFO "(you could also add this reporisotry using GUI like synaptic)" + INFO "" + INFO "Hit Enter to continue running the script, or hit Ctrl-C to abort the script" + + read + fi + fi + sudo apt-get update # XXX Why in hell? Let's let this stuff to the user's responsability!!! # sudo apt-get -y upgrade @@ -835,7 +858,7 @@ install_DEB() { libfreetype6-dev libx11-dev libxi-dev wget libsqlite3-dev libbz2-dev libncurses5-dev \ libssl-dev liblzma-dev libreadline-dev $OPENJPEG_DEV libopenexr-dev libopenal-dev \ libglew-dev yasm $SCHRO_DEV $THEORA_DEV $VORBIS_DEV libsdl1.2-dev \ - libfftw3-dev libjack-dev python-dev patch + libfftw3-dev libjack-dev python-dev patch bzip2 OPENJPEG_USE=true SCHRO_USE=true -- cgit v1.2.3 From bb0195e0396a66c40a03e9f9c6a87c9b8a5ecc47 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 28 Nov 2012 19:57:29 +0000 Subject: Fix #33337: cycles crash with progressive refine and multiple render layers. --- intern/cycles/render/session.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index 003b722b5a5..1d1a3d54893 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -637,6 +637,15 @@ void Session::reset(BufferParams& buffer_params, int samples) reset_gpu(buffer_params, samples); else reset_cpu(buffer_params, samples); + + if(params.progressive_refine) { + thread_scoped_lock buffers_lock(buffers_mutex); + + foreach(RenderBuffers *buffers, tile_buffers) + delete buffers; + + tile_buffers.clear(); + } } void Session::set_samples(int samples) -- cgit v1.2.3 From 0d6976ad0ce4570e286ca33b852ee3b6a07a09ab Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 29 Nov 2012 00:43:50 +0000 Subject: Fix #32900: object motion blur not working on the GPU. To make this work I disabled motion blurring of scale animation, probably not a big loss in practice since it's not so common to animate this, can be added back later. --- intern/cycles/kernel/kernel_camera.h | 6 +++--- intern/cycles/kernel/kernel_object.h | 28 +++++++++++--------------- intern/cycles/kernel/kernel_types.h | 6 +----- intern/cycles/render/camera.cpp | 2 +- intern/cycles/render/object.cpp | 14 ++++++------- intern/cycles/util/util_transform.cpp | 24 +++++++++++++++++------ intern/cycles/util/util_transform.h | 37 +++++++++++++++++++++-------------- 7 files changed, 63 insertions(+), 54 deletions(-) diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h index abc63d99c74..97d37a8b3f4 100644 --- a/intern/cycles/kernel/kernel_camera.h +++ b/intern/cycles/kernel/kernel_camera.h @@ -65,7 +65,7 @@ __device void camera_sample_perspective(KernelGlobals *kg, float raster_x, float #ifdef __CAMERA_MOTION__ if(kernel_data.cam.have_motion) - transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time); + transform_motion_interpolate(&cameratoworld, (const DecompMotionTransform*)&kernel_data.cam.motion, ray->time); #endif ray->P = transform_point(&cameratoworld, ray->P); @@ -108,7 +108,7 @@ __device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, floa #ifdef __CAMERA_MOTION__ if(kernel_data.cam.have_motion) - transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time); + transform_motion_interpolate(&cameratoworld, (const DecompMotionTransform*)&kernel_data.cam.motion, ray->time); #endif ray->P = transform_point(&cameratoworld, ray->P); @@ -182,7 +182,7 @@ __device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float ra #ifdef __CAMERA_MOTION__ if(kernel_data.cam.have_motion) - transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time); + transform_motion_interpolate(&cameratoworld, (const DecompMotionTransform*)&kernel_data.cam.motion, ray->time); #endif ray->P = transform_point(&cameratoworld, ray->P); diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h index 112bfbb86b5..2b38544e527 100644 --- a/intern/cycles/kernel/kernel_object.h +++ b/intern/cycles/kernel/kernel_object.h @@ -23,9 +23,8 @@ enum ObjectTransform { OBJECT_INVERSE_TRANSFORM = 3, OBJECT_PROPERTIES = 6, OBJECT_TRANSFORM_MOTION_PRE = 8, - OBJECT_TRANSFORM_MOTION_MID = 12, - OBJECT_TRANSFORM_MOTION_POST = 16, - OBJECT_DUPLI = 20 + OBJECT_TRANSFORM_MOTION_POST = 12, + OBJECT_DUPLI = 16 }; __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type) @@ -44,24 +43,19 @@ __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, #ifdef __OBJECT_MOTION__ __device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time) { - MotionTransform motion; + DecompMotionTransform motion; int offset = object*OBJECT_SIZE + (int)OBJECT_TRANSFORM_MOTION_PRE; - motion.pre.x = kernel_tex_fetch(__objects, offset + 0); - motion.pre.y = kernel_tex_fetch(__objects, offset + 1); - motion.pre.z = kernel_tex_fetch(__objects, offset + 2); - motion.pre.w = kernel_tex_fetch(__objects, offset + 3); + motion.mid.x = kernel_tex_fetch(__objects, offset + 0); + motion.mid.y = kernel_tex_fetch(__objects, offset + 1); + motion.mid.z = kernel_tex_fetch(__objects, offset + 2); + motion.mid.w = kernel_tex_fetch(__objects, offset + 3); - motion.mid.x = kernel_tex_fetch(__objects, offset + 4); - motion.mid.y = kernel_tex_fetch(__objects, offset + 5); - motion.mid.z = kernel_tex_fetch(__objects, offset + 6); - motion.mid.w = kernel_tex_fetch(__objects, offset + 7); - - motion.post.x = kernel_tex_fetch(__objects, offset + 8); - motion.post.y = kernel_tex_fetch(__objects, offset + 9); - motion.post.z = kernel_tex_fetch(__objects, offset + 10); - motion.post.w = kernel_tex_fetch(__objects, offset + 11); + motion.pre_x = kernel_tex_fetch(__objects, offset + 4); + motion.pre_y = kernel_tex_fetch(__objects, offset + 5); + motion.post_x = kernel_tex_fetch(__objects, offset + 6); + motion.post_y = kernel_tex_fetch(__objects, offset + 7); Transform tfm; transform_motion_interpolate(&tfm, &motion, time); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 977fb8c4fd4..a7bf6b28e7e 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -29,7 +29,7 @@ CCL_NAMESPACE_BEGIN /* constants */ -#define OBJECT_SIZE 22 +#define OBJECT_SIZE 18 #define LIGHT_SIZE 4 #define FILTER_TABLE_SIZE 256 #define RAMP_TABLE_SIZE 256 @@ -112,13 +112,9 @@ CCL_NAMESPACE_BEGIN #define __AO__ #define __CAMERA_MOTION__ #define __ANISOTROPIC__ - -#ifndef __KERNEL_CUDA__ #define __OBJECT_MOTION__ #endif -#endif - //#define __SOBOL_FULL_SCREEN__ /* Shader Evaluation */ diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index 32c273c1248..a78ede979b2 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -202,7 +202,7 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) #ifdef __CAMERA_MOTION__ else if(need_motion == Scene::MOTION_BLUR) { if(use_motion) { - transform_motion_decompose(&kcam->motion, &motion, &matrix); + transform_motion_decompose((DecompMotionTransform*)&kcam->motion, &motion, &matrix); kcam->have_motion = 1; } } diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 25b4d1f08cc..d08cb07fc3c 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -56,7 +56,7 @@ void Object::compute_bounds(bool motion_blur, float shuttertime) BoundBox mbounds = mesh->bounds; if(motion_blur && use_motion) { - MotionTransform decomp; + DecompMotionTransform decomp; transform_motion_decompose(&decomp, &motion, &tfm); bounds = BoundBox::empty; @@ -222,29 +222,29 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene mtfm_post = mtfm_post * itfm; memcpy(&objects[offset+8], &mtfm_pre, sizeof(float4)*4); - memcpy(&objects[offset+16], &mtfm_post, sizeof(float4)*4); + memcpy(&objects[offset+12], &mtfm_post, sizeof(float4)*4); } #ifdef __OBJECT_MOTION__ else if(need_motion == Scene::MOTION_BLUR) { if(ob->use_motion) { /* decompose transformations for interpolation */ - MotionTransform decomp; + DecompMotionTransform decomp; transform_motion_decompose(&decomp, &ob->motion, &ob->tfm); - memcpy(&objects[offset+8], &decomp, sizeof(float4)*12); + memcpy(&objects[offset+8], &decomp, sizeof(float4)*8); flag |= SD_OBJECT_MOTION; have_motion = true; } else { float4 no_motion = make_float4(FLT_MAX); - memcpy(&objects[offset+8], &no_motion, sizeof(float4)*12); + memcpy(&objects[offset+8], &no_motion, sizeof(float4)*8); } } #endif /* dupli object coords */ - objects[offset+20] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f); - objects[offset+21] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f); + objects[offset+16] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f); + objects[offset+17] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f); /* object flag */ if(ob->use_holdout) diff --git a/intern/cycles/util/util_transform.cpp b/intern/cycles/util/util_transform.cpp index 4eee024990f..ca19146e125 100644 --- a/intern/cycles/util/util_transform.cpp +++ b/intern/cycles/util/util_transform.cpp @@ -246,18 +246,30 @@ static void transform_decompose(Transform *decomp, const Transform *tfm) decomp->w = make_float4(scale.y.z, scale.z.x, scale.z.y, scale.z.z); } -void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid) +void transform_motion_decompose(DecompMotionTransform *decomp, const MotionTransform *motion, const Transform *mid) { - transform_decompose(&decomp->pre, &motion->pre); + Transform pre, post; + + transform_decompose(&pre, &motion->pre); transform_decompose(&decomp->mid, mid); - transform_decompose(&decomp->post, &motion->post); + transform_decompose(&post, &motion->post); /* ensure rotation around shortest angle, negated quaternions are the same * but this means we don't have to do the check in quat_interpolate */ - if(dot(decomp->mid.x, decomp->post.x) < 0.0f) + if(dot(decomp->mid.x, post.x) < 0.0f) decomp->mid.x = -decomp->mid.x; - if(dot(decomp->pre.x, decomp->mid.x) < 0.0f) - decomp->pre.x = -decomp->pre.x; + if(dot(pre.x, decomp->mid.x) < 0.0f) + pre.x = -pre.x; + + /* drop scale of pre/post */ + pre.y.w = decomp->mid.y.w; + post.y.w = decomp->mid.y.w; + + /* store translation/rotation part of pre/post */ + decomp->pre_x = pre.x; + decomp->pre_y = pre.y; + decomp->post_x = post.x; + decomp->post_y = post.y; } CCL_NAMESPACE_END diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h index 65162ebf4e6..dbf88cb67a0 100644 --- a/intern/cycles/util/util_transform.h +++ b/intern/cycles/util/util_transform.h @@ -41,7 +41,9 @@ typedef struct Transform { /* transform decomposed in rotation/translation/scale. we use the same data * structure as Transform, and tightly pack decomposition into it. first the - * rotation (4), then translation (3), then 3x3 scale matrix (9) */ + * rotation (4), then translation (3), then 3x3 scale matrix (9). + * + * For the DecompMotionTransform we drop scale from pre/post. */ typedef struct MotionTransform { Transform pre; @@ -49,6 +51,12 @@ typedef struct MotionTransform { Transform post; } MotionTransform; +typedef struct DecompMotionTransform { + Transform mid; + float4 pre_x, pre_y; + float4 post_x, post_y; +} DecompMotionTransform; + /* Functions */ __device_inline float3 transform_perspective(const Transform *t, const float3 a) @@ -384,7 +392,7 @@ __device_inline void transform_compose(Transform *tfm, const Transform *decomp) /* Disabled for now, need arc-length parametrization for constant speed motion. * #define CURVED_MOTION_INTERPOLATE */ -__device void transform_motion_interpolate(Transform *tfm, const MotionTransform *motion, float t) +__device void transform_motion_interpolate(Transform *tfm, const DecompMotionTransform *motion, float t) { /* possible optimization: is it worth it adding a check to skip scaling? * it's probably quite uncommon to have scaling objects. or can we skip @@ -393,9 +401,9 @@ __device void transform_motion_interpolate(Transform *tfm, const MotionTransform #ifdef CURVED_MOTION_INTERPOLATE /* 3 point bezier curve interpolation for position */ - float3 Ppre = float4_to_float3(motion->pre.y); + float3 Ppre = float4_to_float3(motion->pre_y); float3 Pmid = float4_to_float3(motion->mid.y); - float3 Ppost = float4_to_float3(motion->post.y); + float3 Ppost = float4_to_float3(motion->post_y); float3 Pcontrol = 2.0f*Pmid - 0.5f*(Ppre + Ppost); float3 P = Ppre*t*t + Pcontrol*2.0f*t*(1.0f - t) + Ppost*(1.0f - t)*(1.0f - t); @@ -409,28 +417,27 @@ __device void transform_motion_interpolate(Transform *tfm, const MotionTransform if(t < 0.5f) { t *= 2.0f; - decomp.x = quat_interpolate(motion->pre.x, motion->mid.x, t); + decomp.x = quat_interpolate(motion->pre_x, motion->mid.x, t); #ifdef CURVED_MOTION_INTERPOLATE - decomp.y.w = (1.0f - t)*motion->pre.y.w + t*motion->mid.y.w; + decomp.y.w = (1.0f - t)*motion->pre_y.w + t*motion->mid.y.w; #else - decomp.y = (1.0f - t)*motion->pre.y + t*motion->mid.y; + decomp.y = (1.0f - t)*motion->pre_y + t*motion->mid.y; #endif - decomp.z = (1.0f - t)*motion->pre.z + t*motion->mid.z; - decomp.w = (1.0f - t)*motion->pre.w + t*motion->mid.w; } else { t = (t - 0.5f)*2.0f; - decomp.x = quat_interpolate(motion->mid.x, motion->post.x, t); + decomp.x = quat_interpolate(motion->mid.x, motion->post_x, t); #ifdef CURVED_MOTION_INTERPOLATE - decomp.y.w = (1.0f - t)*motion->mid.y.w + t*motion->post.y.w; + decomp.y.w = (1.0f - t)*motion->mid.y.w + t*motion->post_y.w; #else - decomp.y = (1.0f - t)*motion->mid.y + t*motion->post.y; + decomp.y = (1.0f - t)*motion->mid.y + t*motion->post_y; #endif - decomp.z = (1.0f - t)*motion->mid.z + t*motion->post.z; - decomp.w = (1.0f - t)*motion->mid.w + t*motion->post.w; } + decomp.z = motion->mid.z; + decomp.w = motion->mid.w; + /* compose rotation, translation, scale into matrix */ transform_compose(tfm, &decomp); } @@ -442,7 +449,7 @@ __device_inline bool operator==(const MotionTransform& A, const MotionTransform& return (A.pre == B.pre && A.post == B.post); } -void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid); +void transform_motion_decompose(DecompMotionTransform *decomp, const MotionTransform *motion, const Transform *mid); #endif -- cgit v1.2.3 From c3e18138206d4d841cf9e08b58a7e9ed792655e3 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 29 Nov 2012 01:25:38 +0000 Subject: Fix related to #33340: add a warning to bge from_id documentation to not store id() in game object integer properties since it may not fit in 32 bits integers. --- doc/python_api/rst/bge.types.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/python_api/rst/bge.types.rst b/doc/python_api/rst/bge.types.rst index f7a63b48f61..8cf9ccb794c 100644 --- a/doc/python_api/rst/bge.types.rst +++ b/doc/python_api/rst/bge.types.rst @@ -759,6 +759,10 @@ Types The id is derived from a memory location and will be different each time the game engine starts. + .. warning:: + + The id can't be stored as an integer in game object properties, as those only have a limited range that the id may not be contained in. Instead an id can be stored as a string game property and converted back to an integer for use in from_id lookups. + .. class:: KX_BlenderMaterial(PyObjectPlus) KX_BlenderMaterial -- cgit v1.2.3 From 9653c929ed3d0a35831d591d33d63a9a774c6c44 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 29 Nov 2012 02:37:39 +0000 Subject: skip recalculating tessface when adding objects if 'EnterEdit-mode' is disabled. --- source/blender/editors/mesh/editmesh_add.c | 3 ++- source/blender/editors/object/object_add.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 23f7c307356..cd6063b12d0 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -86,7 +86,8 @@ static void make_prim_finish(bContext *C, Object *obedit, int *state, int enter_ * to push this up to edges & faces. */ EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX); - EDBM_update_generic(C, em, TRUE); + /* only recalc editmode tessface if we are staying in editmode */ + EDBM_update_generic(C, em, enter_editmode); /* userdef */ if (*state && !enter_editmode) { diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 4d1f2bbc4e9..ad1e2816c10 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -271,7 +271,7 @@ int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float loc[3], fl if (RNA_struct_property_is_set(op->ptr, "enter_editmode") && enter_editmode) *enter_editmode = RNA_boolean_get(op->ptr, "enter_editmode"); else { - *enter_editmode = U.flag & USER_ADD_EDITMODE; + *enter_editmode = (U.flag & USER_ADD_EDITMODE) != 0; RNA_boolean_set(op->ptr, "enter_editmode", *enter_editmode); } } -- cgit v1.2.3 From 078487e98e9e06bd971b132fb7e856ba174b02c6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 29 Nov 2012 02:44:06 +0000 Subject: bmesh py api: add BMeshFaceSeq.active attribute- bm.faces.active --- source/blender/python/bmesh/bmesh_py_types.c | 49 ++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 51c2a2be1fd..108581ac0da 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -555,6 +555,53 @@ static PyObject *bpy_bmelemseq_layers_get(BPy_BMElemSeq *self, void *htype) return BPy_BMLayerAccess_CreatePyObject(self->bm, GET_INT_FROM_POINTER(htype)); } +/* FaceSeq + * ^^^^^^^ */ + +PyDoc_STRVAR(bpy_bmfaceseq_active_doc, +"active face.\n\n:type: :class:`BMFace` or None" +); +static PyObject *bpy_bmfaceseq_active_get(BPy_BMElemSeq *self, void *UNUSED(closure)) +{ + BMesh *bm = self->bm; + BPY_BM_CHECK_OBJ(self); + + if (bm->act_face) { + return BPy_BMElem_CreatePyObject(bm, (BMHeader *)bm->act_face); + } + else { + Py_RETURN_NONE; + } +} + +static int bpy_bmfaceseq_active_set(BPy_BMElem *self, PyObject *value, void *UNUSED(closure)) +{ + BMesh *bm = self->bm; + if (value == Py_None) { + bm->act_face = NULL; + return 0; + } + else if (BPy_BMFace_Check(value)) { + BPY_BM_CHECK_INT(value); + + if (((BPy_BMFace *)value)->bm != bm) { + PyErr_SetString(PyExc_ValueError, + "faces.active = f: f is from another mesh"); + return -1; + } + else { + bm->act_face = ((BPy_BMFace *)value)->f; + return 0; + } + } + else { + PyErr_Format(PyExc_TypeError, + "faces.active = f: expected BMFace or None, not %.200s", + Py_TYPE(value)->tp_name); + return -1; + } +} + static PyGetSetDef bpy_bmesh_getseters[] = { {(char *)"verts", (getter)bpy_bmvertseq_get, (setter)NULL, (char *)bpy_bmvertseq_doc, NULL}, {(char *)"edges", (getter)bpy_bmedgeseq_get, (setter)NULL, (char *)bpy_bmedgeseq_doc, NULL}, @@ -676,6 +723,8 @@ static PyGetSetDef bpy_bmedgeseq_getseters[] = { }; static PyGetSetDef bpy_bmfaceseq_getseters[] = { {(char *)"layers", (getter)bpy_bmelemseq_layers_get, (setter)NULL, (char *)bpy_bmelemseq_layers_doc, (void *)BM_FACE}, + /* face only */ + {(char *)"active", (getter)bpy_bmfaceseq_active_get, (setter)bpy_bmfaceseq_active_set, (char *)bpy_bmfaceseq_active_doc, NULL}, {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; static PyGetSetDef bpy_bmloopseq_getseters[] = { -- cgit v1.2.3 From c86045d7a29c2ffe3f102955560fda214d9f7f2d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 29 Nov 2012 03:25:37 +0000 Subject: bmesh py api: use generic checking macros to see if an object if from the same bmesh. - was such a common operation so this saves having exceptions set inline all over the place. --- source/blender/python/bmesh/bmesh_py_types.c | 84 +++++++--------------- source/blender/python/bmesh/bmesh_py_types.h | 20 ++++-- .../python/bmesh/bmesh_py_types_customdata.c | 12 +--- .../blender/python/bmesh/bmesh_py_types_select.c | 14 +--- source/blender/python/bmesh/bmesh_py_utils.c | 10 +-- 5 files changed, 47 insertions(+), 93 deletions(-) diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 108581ac0da..307bbc3f6ad 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -582,17 +582,10 @@ static int bpy_bmfaceseq_active_set(BPy_BMElem *self, PyObject *value, void *UNU return 0; } else if (BPy_BMFace_Check(value)) { - BPY_BM_CHECK_INT(value); + BPY_BM_CHECK_SOURCE_INT(value, bm, "faces.active = f"); - if (((BPy_BMFace *)value)->bm != bm) { - PyErr_SetString(PyExc_ValueError, - "faces.active = f: f is from another mesh"); - return -1; - } - else { - bm->act_face = ((BPy_BMFace *)value)->f; - return 0; - } + bm->act_face = ((BPy_BMFace *)value)->f; + return 0; } else { PyErr_Format(PyExc_TypeError, @@ -1281,13 +1274,7 @@ static PyObject *bpy_bmvert_copy_from_face_interp(BPy_BMVert *self, PyObject *ar else { BMesh *bm = self->bm; - BPY_BM_CHECK_OBJ(py_face); - - if (py_face->bm != bm) { - PyErr_SetString(PyExc_ValueError, - "BMVert.copy_from_face_interp(face): face is from another mesh"); - return NULL; - } + BPY_BM_CHECK_SOURCE_OBJ(py_face, bm, "copy_from_face_interp()"); BM_vert_interp_from_face(bm, self->v, py_face->f); @@ -1421,13 +1408,7 @@ static PyObject *bpy_bmedge_other_vert(BPy_BMEdge *self, BPy_BMVert *value) return NULL; } - BPY_BM_CHECK_OBJ(value); - - if (self->bm != value->bm) { - PyErr_SetString(PyExc_ValueError, - "BMEdge.other_vert(vert): vert is from another mesh"); - return NULL; - } + BPY_BM_CHECK_SOURCE_OBJ(value, self->bm, "BMEdge.other_vert(vert)"); other = BM_edge_other_vert(self->e, value->v); @@ -1481,13 +1462,7 @@ static PyObject *bpy_bmface_copy_from_face_interp(BPy_BMFace *self, PyObject *ar else { BMesh *bm = self->bm; - BPY_BM_CHECK_OBJ(py_face); - - if (py_face->bm != bm) { - PyErr_SetString(PyExc_ValueError, - "BMFace.copy_from_face_interp(face): face is from another mesh"); - return NULL; - } + BPY_BM_CHECK_SOURCE_OBJ(py_face, bm, "BMFace.copy_from_face_interp(face)"); BM_face_interp_from_face(bm, self->f, py_face->f); @@ -1653,13 +1628,7 @@ static PyObject *bpy_bmloop_copy_from_face_interp(BPy_BMLoop *self, PyObject *ar else { BMesh *bm = self->bm; - BPY_BM_CHECK_OBJ(py_face); - - if (py_face->bm != bm) { - PyErr_SetString(PyExc_ValueError, - "BMLoop.copy_from_face_interp(face): face is from another mesh"); - return NULL; - } + BPY_BM_CHECK_SOURCE_OBJ(py_face, bm, "BMLoop.copy_from_face_interp(face)"); BM_loop_interp_from_face(bm, self->l, py_face->f, do_vertex, do_multires); @@ -1955,13 +1924,7 @@ static PyObject *bpy_bmvertseq_remove(BPy_BMElemSeq *self, BPy_BMVert *value) else { BMesh *bm = self->bm; - BPY_BM_CHECK_OBJ(value); - - if (value->bm != bm) { - PyErr_SetString(PyExc_ValueError, - "verts.remove(vert): vert is from another mesh"); - return NULL; - } + BPY_BM_CHECK_SOURCE_OBJ(value, bm, "verts.remove(vert)"); BM_vert_kill(bm, value->v); bpy_bm_generic_invalidate((BPy_BMGeneric *)value); @@ -1985,13 +1948,7 @@ static PyObject *bpy_bmedgeseq_remove(BPy_BMElemSeq *self, BPy_BMEdge *value) else { BMesh *bm = self->bm; - BPY_BM_CHECK_OBJ(value); - - if (value->bm != bm) { - PyErr_SetString(PyExc_ValueError, - "edges.remove(edge): edge is from another mesh"); - return NULL; - } + BPY_BM_CHECK_SOURCE_OBJ(value, bm, "edges.remove(edges)"); BM_edge_kill(bm, value->e); bpy_bm_generic_invalidate((BPy_BMGeneric *)value); @@ -2015,13 +1972,7 @@ static PyObject *bpy_bmfaceseq_remove(BPy_BMElemSeq *self, BPy_BMFace *value) else { BMesh *bm = self->bm; - BPY_BM_CHECK_OBJ(value); - - if (value->bm != bm) { - PyErr_SetString(PyExc_ValueError, - "faces.remove(face): face is from another mesh"); - return NULL; - } + BPY_BM_CHECK_SOURCE_OBJ(value, bm, "faces.remove(face)"); BM_face_kill(bm, value->f); bpy_bm_generic_invalidate((BPy_BMGeneric *)value); @@ -3450,6 +3401,21 @@ int bpy_bm_generic_valid_check(BPy_BMGeneric *self) } } +int bpy_bm_generic_valid_check_source(BPy_BMGeneric *self, BMesh *bm_source, const char *error_prefix) +{ + int ret = bpy_bm_generic_valid_check(self); + if (LIKELY(ret == 0)) { + if (UNLIKELY(self->bm != bm_source)) { + /* could give more info here */ + PyErr_Format(PyExc_ValueError, + "%.200s: BMesh data of type %.200s is from another mesh", + error_prefix, Py_TYPE(self)->tp_name); + ret = -1; + } + } + return ret; +} + void bpy_bm_generic_invalidate(BPy_BMGeneric *self) { self->bm = NULL; diff --git a/source/blender/python/bmesh/bmesh_py_types.h b/source/blender/python/bmesh/bmesh_py_types.h index 8de69c2d8a2..d15918a3c11 100644 --- a/source/blender/python/bmesh/bmesh_py_types.h +++ b/source/blender/python/bmesh/bmesh_py_types.h @@ -158,9 +158,6 @@ PyObject *BPy_BMIter_CreatePyObject(BMesh *bm); PyObject *BPy_BMElem_CreatePyObject(BMesh *bm, BMHeader *ele); /* just checks type and creates v/e/f/l */ -int bpy_bm_generic_valid_check(BPy_BMGeneric *self); -void bpy_bm_generic_invalidate(BPy_BMGeneric *self); - void *BPy_BMElem_PySeq_As_Array(BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_ssize_t max, Py_ssize_t *r_size, const char htype, const char do_unique_check, const char do_bm_check, @@ -171,9 +168,20 @@ int BPy_BMElem_CheckHType(PyTypeObject *type, const char htype); char *BPy_BMElem_StringFromHType_ex(const char htype, char ret[32]); char *BPy_BMElem_StringFromHType(const char htype); - -#define BPY_BM_CHECK_OBJ(obj) if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { return NULL; } (void)0 -#define BPY_BM_CHECK_INT(obj) if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { return -1; } (void)0 +void bpy_bm_generic_invalidate(BPy_BMGeneric *self); +int bpy_bm_generic_valid_check(BPy_BMGeneric *self); +int bpy_bm_generic_valid_check_source(BPy_BMGeneric *self, BMesh *bm_source, const char *error_prefix); + +#define BPY_BM_CHECK_OBJ(obj) \ + if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { return NULL; } (void)0 +#define BPY_BM_CHECK_INT(obj) \ + if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { return -1; } (void)0 + +/* macros like BPY_BM_CHECK_OBJ/BPY_BM_CHECK_INT that ensure we're from the right BMesh */ +#define BPY_BM_CHECK_SOURCE_OBJ(obj, bm, errmsg) \ + if (UNLIKELY(bpy_bm_generic_valid_check_source((BPy_BMGeneric *)obj, bm, errmsg) == -1)) { return NULL; } (void)0 +#define BPY_BM_CHECK_SOURCE_INT(obj, bm, errmsg) \ + if (UNLIKELY(bpy_bm_generic_valid_check_source((BPy_BMGeneric *)obj, bm, errmsg) == -1)) { return -1; } (void)0 #define BPY_BM_IS_VALID(obj) (LIKELY((obj)->bm != NULL)) diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c index 14132d08fe6..fd31f3c40cc 100644 --- a/source/blender/python/bmesh/bmesh_py_types_customdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c @@ -262,16 +262,10 @@ static PyObject *bpy_bmlayeritem_copy_from(BPy_BMLayerItem *self, BPy_BMLayerIte } BPY_BM_CHECK_OBJ(self); - BPY_BM_CHECK_OBJ(value); - - if (self->bm != value->bm) { - PyErr_SetString(PyExc_ValueError, - "layer.copy_from(): layer is from another mesh"); - return NULL; - } + BPY_BM_CHECK_SOURCE_OBJ(value, self->bm, "layer.copy_from()"); - else if ((self->htype != value->htype) || - (self->type != value->type)) + if ((self->htype != value->htype) || + (self->type != value->type)) { PyErr_SetString(PyExc_ValueError, "layer.copy_from(other): layer type mismatch"); diff --git a/source/blender/python/bmesh/bmesh_py_types_select.c b/source/blender/python/bmesh/bmesh_py_types_select.c index 2ff731559d1..dfcfbeb0ab5 100644 --- a/source/blender/python/bmesh/bmesh_py_types_select.c +++ b/source/blender/python/bmesh/bmesh_py_types_select.c @@ -114,13 +114,7 @@ static PyObject *bpy_bmeditselseq_add(BPy_BMEditSelSeq *self, BPy_BMElem *value) return NULL; } - BPY_BM_CHECK_OBJ(value); - - if (self->bm != value->bm) { - PyErr_SetString(PyExc_ValueError, - "Element is not from this mesh"); - return NULL; - } + BPY_BM_CHECK_SOURCE_OBJ(value, self->bm, "select_history.add()"); BM_select_history_store(self->bm, value->ele); @@ -145,11 +139,9 @@ static PyObject *bpy_bmeditselseq_remove(BPy_BMEditSelSeq *self, BPy_BMElem *val return NULL; } - BPY_BM_CHECK_OBJ(value); + BPY_BM_CHECK_SOURCE_OBJ(value, self->bm, "select_history.remove()"); - if ((self->bm != value->bm) || - (BM_select_history_remove(self->bm, value->ele) == FALSE)) - { + if (BM_select_history_remove(self->bm, value->ele) == FALSE) { PyErr_SetString(PyExc_ValueError, "Element not found in selection history"); return NULL; diff --git a/source/blender/python/bmesh/bmesh_py_utils.c b/source/blender/python/bmesh/bmesh_py_utils.c index b70df53aff0..f85c3347104 100644 --- a/source/blender/python/bmesh/bmesh_py_utils.c +++ b/source/blender/python/bmesh/bmesh_py_utils.c @@ -557,16 +557,10 @@ static PyObject *bpy_bm_utils_face_vert_separate(PyObject *UNUSED(self), PyObjec return NULL; } - BPY_BM_CHECK_OBJ(py_face); - BPY_BM_CHECK_OBJ(py_vert); - bm = py_face->bm; - if (bm != py_vert->bm) { - PyErr_SetString(PyExc_ValueError, - "mesh elements are from different meshes"); - return NULL; - } + BPY_BM_CHECK_OBJ(py_face); + BPY_BM_CHECK_SOURCE_OBJ(py_vert, bm, "face_vert_separate()"); l = BM_face_vert_share_loop(py_face->f, py_vert->v); -- cgit v1.2.3 From ede703ab855e7a4608631780949334984e05c2b4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 29 Nov 2012 03:55:07 +0000 Subject: some minor edits - script stub printed resource warning with py3.3 (not closing a file). - bmesh customdata layer access had bad docstring. - float/double conversion warnings in sequencer code (use doubles since result is double) - remove unused var --- release/scripts/templates/script_stub.py | 4 +++- source/blender/blenkernel/intern/sequencer.c | 12 ++++++------ source/blender/python/bmesh/bmesh_py_types.c | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/release/scripts/templates/script_stub.py b/release/scripts/templates/script_stub.py index 143c7c5104a..80eca9663df 100644 --- a/release/scripts/templates/script_stub.py +++ b/release/scripts/templates/script_stub.py @@ -9,4 +9,6 @@ filename = "my_script.py" filepath = os.path.join(os.path.dirname(bpy.data.filepath), filename) global_namespace = {"__file__": filepath, "__name__": "__main__"} -exec(compile(open(filepath).read(), filepath, 'exec'), global_namespace) +file_handle = open(filepath, 'rb') +exec(compile(file_handle.read(), filepath, 'exec'), global_namespace) +file_handle.close() diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 1c94d18fc05..acce3740c98 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -1853,11 +1853,11 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra, t = *seq->strip->transform; } - xscale = context.scene->r.xsch ? ((float) context.rectx / (float) context.scene->r.xsch) : 1.0; - yscale = context.scene->r.ysch ? ((float) context.recty / (float) context.scene->r.ysch) : 1.0; + xscale = context.scene->r.xsch ? ((double)context.rectx / (double)context.scene->r.xsch) : 1.0; + yscale = context.scene->r.ysch ? ((double)context.recty / (double)context.scene->r.ysch) : 1.0; - xscale /= (float) context.rectx / ibuf->x; - yscale /= (float) context.recty / ibuf->y; + xscale /= (double)context.rectx / (double)ibuf->x; + yscale /= (double)context.recty / (double)ibuf->y; c.left *= xscale; c.right *= xscale; c.top *= yscale; c.bottom *= yscale; @@ -2356,7 +2356,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float 0 /* (context.scene->r.seq_flag & R_SEQ_GL_REND) */ : (context.scene->r.seq_flag & R_SEQ_GL_PREV); int do_seq; - int have_seq = FALSE; + // int have_seq = FALSE; /* UNUSED */ int have_comp = FALSE; Scene *scene; int is_thread_main = BLI_thread_is_main(); @@ -2369,7 +2369,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float scene = seq->scene; frame = scene->r.sfra + nr + seq->anim_startofs; - have_seq = (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first; + // have_seq = (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first; /* UNUSED */ have_comp = (scene->r.scemode & R_DOCOMP) && scene->use_nodes && scene->nodetree; oldcfra = scene->r.cfra; diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 307bbc3f6ad..e78e761e8de 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -546,7 +546,7 @@ static PyObject *bpy_bmloop_link_loop_prev_get(BPy_BMLoop *self) /* note: use for bmvert/edge/face/loop seq's use these, not bmelemseq directly */ PyDoc_STRVAR(bpy_bmelemseq_layers_doc, -"blah blah (read-only).\n\n:type: :class:`BMLayerAccess`" +"custom-data layers (read-only).\n\n:type: :class:`BMLayerAccess`" ); static PyObject *bpy_bmelemseq_layers_get(BPy_BMElemSeq *self, void *htype) { -- cgit v1.2.3 From 858149d7c7f3bd4d6a254d560d3a0810e5739ae5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 29 Nov 2012 05:02:06 +0000 Subject: bmesh py api: add bmesh.update_edit_mode(), there was no way to redraw the 3d view or re-calculate face tessellation from python. add py template for editing meshes in editmode. also remove double call to CTX_wm_region which does a string lookup. --- release/scripts/templates/bmesh_simple_editmode.py | 23 ++++++++++ source/blender/bmesh/intern/bmesh_opdefines.c | 6 +-- source/blender/python/bmesh/bmesh_py_api.c | 50 +++++++++++++++++++++- .../blender/windowmanager/intern/wm_event_system.c | 6 ++- 4 files changed, 78 insertions(+), 7 deletions(-) create mode 100644 release/scripts/templates/bmesh_simple_editmode.py diff --git a/release/scripts/templates/bmesh_simple_editmode.py b/release/scripts/templates/bmesh_simple_editmode.py new file mode 100644 index 00000000000..d79ba02c2cb --- /dev/null +++ b/release/scripts/templates/bmesh_simple_editmode.py @@ -0,0 +1,23 @@ +# This example assumes we have a mesh object in edit-mode + +import bpy +import bmesh + +# Get the active mesh +obj = bpy.context.edit_object +me = obj.data + + +# Get a BMesh representation +bm = bmesh.from_edit_mesh(me) + +bm.faces.active = None + +# Modify the BMesh, can do anything here... +for v in bm.verts: + v.co.x += 1.0 + + +# Show the updates in the viewport +# and recalculate n-gon tessellation. +bmesh.update_edit_mesh(me, True) diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 5a25861a74a..58c6e051e48 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -581,8 +581,7 @@ static BMOpDefine bmo_edgenet_prepare_def = { /* * Rotate. * - * Rotate vertices around a center, using a 3x3 rotation - * matrix. Equivalent of the old rotateflag function. + * Rotate vertices around a center, using a 3x3 rotation matrix. */ static BMOpDefine bmo_rotate_def = { "rotate", @@ -600,8 +599,7 @@ static BMOpDefine bmo_rotate_def = { /* * Translate. * - * Translate vertices by an offset. Equivalent of the - * old translateflag function. + * Translate vertices by an offset. */ static BMOpDefine bmo_translate_def = { "translate", diff --git a/source/blender/python/bmesh/bmesh_py_api.c b/source/blender/python/bmesh/bmesh_py_api.c index e02efc79da0..697a9259b37 100644 --- a/source/blender/python/bmesh/bmesh_py_api.c +++ b/source/blender/python/bmesh/bmesh_py_api.c @@ -51,7 +51,6 @@ #include "bmesh_py_api.h" /* own include */ - PyDoc_STRVAR(bpy_bm_new_doc, ".. method:: new()\n" "\n" @@ -73,6 +72,8 @@ PyDoc_STRVAR(bpy_bm_from_edit_mesh_doc, "\n" " Return a BMesh from this mesh, currently the mesh must already be in editmode.\n" "\n" +" :arg mesh: The editmode mesh.\n" +" :type mesh: :class:`bpy.types.Mesh`\n" " :return: the BMesh associated with this mesh.\n" " :rtype: :class:`bmesh.types.BMesh`\n" ); @@ -96,9 +97,56 @@ static PyObject *bpy_bm_from_edit_mesh(PyObject *UNUSED(self), PyObject *value) return BPy_BMesh_CreatePyObject(bm, BPY_BMFLAG_IS_WRAPPED); } +PyDoc_STRVAR(bpy_bm_update_edit_mesh_doc, +".. method:: update_edit_mesh(mesh, tessface=True)\n" +"\n" +" Update the mesh after changes to the BMesh in editmode, \n" +" optionally recalculating n-gon tessellation.\n" +"\n" +" :arg mesh: The editmode mesh.\n" +" :type mesh: :class:`bpy.types.Mesh`\n" +" :arg tessface: Option to recalculate n-gon tessellation.\n" +" :type tessface: boolean\n" +); +static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args) +{ + PyObject *py_me; + Mesh *me; + int do_tessface = TRUE; + + if (!PyArg_ParseTuple(args, "O|i:update_edit_mesh", &py_me, &do_tessface)) { + return NULL; + } + + me = PyC_RNA_AsPointer(py_me, "Mesh"); + + if (me == NULL) { + return NULL; + } + + if (me->edit_btmesh == NULL) { + PyErr_SetString(PyExc_ValueError, + "The mesh must be in editmode"); + return NULL; + } + + { + /* XXX, not great - infact this function could just not use the context at all + * postpone that change until after release: BMESH_TODO - campbell */ + extern struct bContext *BPy_GetContext(void); + extern void EDBM_update_generic(struct bContext *C, BMEditMesh *em, const short do_tessface); + + struct bContext *C = BPy_GetContext(); + EDBM_update_generic(C, me->edit_btmesh, do_tessface); + } + + Py_RETURN_NONE; +} + static struct PyMethodDef BPy_BM_methods[] = { {"new", (PyCFunction)bpy_bm_new, METH_NOARGS, bpy_bm_new_doc}, {"from_edit_mesh", (PyCFunction)bpy_bm_from_edit_mesh, METH_O, bpy_bm_from_edit_mesh_doc}, + {"update_edit_mesh", (PyCFunction)bpy_bm_update_edit_mesh, METH_VARARGS, bpy_bm_update_edit_mesh_doc}, {NULL, NULL, 0, NULL} }; diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index b3c9cfbc79e..c0e3b19c716 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -135,6 +135,7 @@ static int wm_test_duplicate_notifier(wmWindowManager *wm, unsigned int type, vo /* XXX: in future, which notifiers to send to other windows? */ void WM_event_add_notifier(const bContext *C, unsigned int type, void *reference) { + ARegion *ar; wmNotifier *note = MEM_callocN(sizeof(wmNotifier), "notifier"); note->wm = CTX_wm_manager(C); @@ -142,8 +143,9 @@ void WM_event_add_notifier(const bContext *C, unsigned int type, void *reference note->window = CTX_wm_window(C); - if (CTX_wm_region(C)) - note->swinid = CTX_wm_region(C)->swinid; + ar = CTX_wm_region(C); + if (ar) + note->swinid = ar->swinid; note->category = type & NOTE_CATEGORY; note->data = type & NOTE_DATA; -- cgit v1.2.3 From 5ce13d0c6c19c63987da0b1f8cbeb7ff61ee9570 Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Thu, 29 Nov 2012 05:21:24 +0000 Subject: BGE: Fixing the double-click issue for mouse events too. The previous fix only fixed double-click keyboard events. --- source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp b/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp index aa2392ded08..8d90eacd27f 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp @@ -121,7 +121,7 @@ bool KX_BlenderMouseDevice::ConvertBlenderEvent(unsigned short incode,short val) // only process it, if it's a key if (kxevent > KX_BEGINMOUSE && kxevent < KX_ENDMOUSEBUTTONS) { - if (val == KM_PRESS) + if (val == KM_PRESS || val == KM_DBL_CLICK) { m_eventStatusTables[m_currentTable][kxevent].m_eventval = val ; //??? -- cgit v1.2.3 From 149b60714121dbe028b61b3218a88e9fab025832 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 29 Nov 2012 05:54:35 +0000 Subject: py/bmesh api: add radial prev/next attributes to the loop --- source/blender/python/bmesh/bmesh_py_types.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index e78e761e8de..f302f6ac38d 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -541,6 +541,24 @@ static PyObject *bpy_bmloop_link_loop_prev_get(BPy_BMLoop *self) return BPy_BMLoop_CreatePyObject(self->bm, self->l->prev); } +PyDoc_STRVAR(bpy_bmloop_link_loop_radial_next_doc, +"The next loop around the edge (read-only).\n\n:type: :class:`BMLoop`" +); +static PyObject *bpy_bmloop_link_loop_radial_next_get(BPy_BMLoop *self) +{ + BPY_BM_CHECK_OBJ(self); + return BPy_BMLoop_CreatePyObject(self->bm, self->l->radial_next); +} + +PyDoc_STRVAR(bpy_bmloop_link_loop_radial_prev_doc, +"The previous loop around the edge (read-only).\n\n:type: :class:`BMLoop`" +); +static PyObject *bpy_bmloop_link_loop_radial_prev_get(BPy_BMLoop *self) +{ + BPY_BM_CHECK_OBJ(self); + return BPy_BMLoop_CreatePyObject(self->bm, self->l->radial_prev); +} + /* ElemSeq * ^^^^^^^ */ @@ -699,6 +717,8 @@ static PyGetSetDef bpy_bmloop_getseters[] = { {(char *)"link_loops", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmloops_link_loops_doc, (void *)BM_LOOPS_OF_LOOP}, {(char *)"link_loop_next", (getter)bpy_bmloop_link_loop_next_get, (setter)NULL, (char *)bpy_bmloop_link_loop_next_doc, NULL}, {(char *)"link_loop_prev", (getter)bpy_bmloop_link_loop_prev_get, (setter)NULL, (char *)bpy_bmloop_link_loop_prev_doc, NULL}, + {(char *)"link_loop_radial_next", (getter)bpy_bmloop_link_loop_radial_next_get, (setter)NULL, (char *)bpy_bmloop_link_loop_radial_next_doc, NULL}, + {(char *)"link_loop_radial_prev", (getter)bpy_bmloop_link_loop_radial_prev_get, (setter)NULL, (char *)bpy_bmloop_link_loop_radial_prev_doc, NULL}, /* readonly checks */ {(char *)"is_valid", (getter)bpy_bm_is_valid_get, (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL}, -- cgit v1.2.3 From 40e75fd2ebd7b992ad988f02fc2e77ff53c752fd Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 29 Nov 2012 08:22:02 +0000 Subject: Dependencies Builder: disable LINKSTATIC for OIIO It'll likely give issues with system boost libraries in ubuntu/debian due to this distros doesn't like static linking and not building static libs with -fPIC flag. Disabling LINKSTATIC should be quite painless since blender requires the same image libraries as oiio does. --- build_files/build_environment/install_deps.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 9d01ed744c0..f8cef63f301 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -456,12 +456,16 @@ EOF cmake_d="$cmake_d -D CMAKE_PREFIX_PATH=$_inst" cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst" cmake_d="$cmake_d -D BUILDSTATIC=ON" - cmake_d="$cmake_d -D LINKSTATIC=ON" + + # linking statically could give issues on Debian/Ubuntu (and probably other distros + # which doesn't like static linking) when linking shared oiio library due to missing + # text symbols (static libs should be compiled with -fPIC) + # cmake_d="$cmake_d -D LINKSTATIC=ON" if [ -d $INST/boost ]; then cmake_d="$cmake_d -D BOOST_ROOT=$INST/boost -D Boost_NO_SYSTEM_PATHS=ON" if $ALL_STATIC; then - cmake_d="$cmake_d -D Boost_USE_STATIC_LIBS=ON" + cmake_d="$cmake_d -D Boost_USE_STATIC_LIBS=ON" fi fi -- cgit v1.2.3 From df4e1953ac4e71b2f31258079ab05d5ab7e77f3b Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Thu, 29 Nov 2012 10:28:06 +0000 Subject: we need 2.8.8 for cmake on mac - patch by Jens Verwiebe --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 69ddaa189d6..0954d5ce878 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -271,6 +271,9 @@ mark_as_advanced(WITH_ASSERT_ABORT) if(APPLE) + cmake_minimum_required(VERSION 2.8.8) + cmake_policy(VERSION 2.8.8) + if(NOT CMAKE_OSX_ARCHITECTURES) set(CMAKE_OSX_ARCHITECTURES x86_64 CACHE STRING "Choose the architecture you want to build Blender for: i386, x86_64 or ppc" -- cgit v1.2.3 From d387dcd1104ec822b19530ebca9b5347a0f31413 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 29 Nov 2012 12:22:07 +0000 Subject: Fix compile error with clang. Patch by sambler via irc --- intern/cycles/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt index 2a1eddcec27..12829f15aed 100644 --- a/intern/cycles/CMakeLists.txt +++ b/intern/cycles/CMakeLists.txt @@ -23,7 +23,7 @@ endif() # for OSL if(WIN32 AND MSVC) set(RTTI_DISABLE_FLAGS "/GR- -DBOOST_NO_RTTI -DBOOST_NO_TYPEID") -elseif(CMAKE_COMPILER_IS_GNUCC) +elseif(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang")) set(RTTI_DISABLE_FLAGS "-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID") endif() -- cgit v1.2.3 From 186bdbd8d8543f7cb610e17e2487f7ca28a2663b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 29 Nov 2012 13:07:45 +0000 Subject: Fix #33344: cycles motion blur was still crashing on CUDA sm 2.0. Solution now is also an optimization, use quaternion nlerp instead of slerp, there's no good reason to use slerp, and nlerp is faster too. --- intern/cycles/util/util_transform.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h index dbf88cb67a0..a1c12ddf0e1 100644 --- a/intern/cycles/util/util_transform.h +++ b/intern/cycles/util/util_transform.h @@ -311,6 +311,10 @@ __device_inline Transform transform_clear_scale(const Transform& tfm) __device_inline float4 quat_interpolate(float4 q1, float4 q2, float t) { + /* use simpe nlerp instead of slerp. it's faster and almost the same */ + return normalize((1.0f - t)*q1 + t*q2); + +#if 0 /* note: this does not ensure rotation around shortest angle, q1 and q2 * are assumed to be matched already in transform_motion_decompose */ float costheta = dot(q1, q2); @@ -328,6 +332,7 @@ __device_inline float4 quat_interpolate(float4 q1, float4 q2, float t) float thetap = theta * t; return q1 * cosf(thetap) + qperp * sinf(thetap); } +#endif } __device_inline Transform transform_quick_inverse(Transform M) -- cgit v1.2.3 From 4e981dc566736b89e4e288d3dfd18f9d3a88dcaa Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 29 Nov 2012 13:24:02 +0000 Subject: Fix #33345: Crash when using bpy.ops.sculpt.brush_stroke It was kind of a regression in behavior in svn rev46862 which made it so blender crashes if stroke is done from the script. It should bring back the behavior back and made it so blender doesn't crash, however it's probably not full fix and some further work is needed to make call of stroke operator usable from the addon. --- source/blender/editors/sculpt_paint/sculpt.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 38dbdcd8337..25ea08a4bb1 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -3356,7 +3356,10 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio sculpt_init_mirror_clipping(ob, ss); /* Initial mouse location */ - copy_v2_v2(ss->cache->initial_mouse, mouse); + if (mouse) + copy_v2_v2(ss->cache->initial_mouse, mouse); + else + zero_v2(ss->cache->initial_mouse); mode = RNA_enum_get(op->ptr, "mode"); cache->invert = mode == BRUSH_STROKE_INVERT; @@ -3890,8 +3893,8 @@ static int sculpt_stroke_test_start(bContext *C, struct wmOperator *op, const float mouse[2]) { /* Don't start the stroke until mouse goes over the mesh. - * note: event will only be null when re-executing the saved stroke. */ - if (over_mesh(C, op, mouse[0], mouse[1])) { + * note: mouse will only be null when re-executing the saved stroke. */ + if (!mouse || over_mesh(C, op, mouse[0], mouse[1])) { Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; Sculpt *sd = CTX_data_tool_settings(C)->sculpt; -- cgit v1.2.3 From fb27a69124150f0efd54dfdec784672d154e6328 Mon Sep 17 00:00:00 2001 From: Howard Trickey Date: Thu, 29 Nov 2012 13:54:39 +0000 Subject: Bevel: partial fix for distortion (bug 33280). Sometimes it is impossible to have same offset from both edges that are on angled faces. The fix here at least doesn't distort the non-beveled part of the model, and looks much better than before on bug example, but is still not perfect. --- source/blender/bmesh/tools/bmesh_bevel.c | 37 +++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 0d16d0af114..62465ea9849 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -365,13 +365,19 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, } /* Like offset_meet, but here f1 and f2 must not be NULL and give the - * planes in which to run the offset lines. They may not meet exactly, - * but the line intersection routine will find the closest approach point. */ -static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, - BMFace *f1, BMFace *f2, float meetco[3]) + * planes in which to run the offset lines. + * They may not meet exactly: the offsets for the edges may be different + * or both the planes and the lines may be angled so that they can't meet. + * In that case, pick a close point on emid, which should be the dividing + * edge between the two planes. + * TODO: should have a global 'offset consistency' prepass to adjust offset + * widths so that all edges have the same offset at both ends. */ +static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, + BMVert *v, BMFace *f1, BMFace *f2, float meetco[3]) { float dir1[3], dir2[3], norm_perp1[3], norm_perp2[3], - off1a[3], off1b[3], off2a[3], off2b[3], isect2[3]; + off1a[3], off1b[3], off2a[3], off2b[3], isect2[3], co[3]; + int iret; BLI_assert(f1 != NULL && f2 != NULL); @@ -397,9 +403,21 @@ static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, /* lines are parallel; off1a is a good meet point */ copy_v3_v3(meetco, off1a); } - else if (!isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2)) { - /* another test says they are parallel */ - copy_v3_v3(meetco, off1a); + else { + iret =isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2); + if (iret == 0) { + /* lines colinear: another test says they are parallel. so shouldn't happen */ + copy_v3_v3(meetco, off1a); + } + else if (iret == 2) { + /* lines are not coplanar; meetco and isect2 are nearest to first and second lines */ + if (len_v3v3(meetco, isect2) > 100.0f * (float)BEVEL_EPSILON) { + /* offset lines don't meet: project average onto emid; this is not ideal (see TODO above) */ + mid_v3_v3v3(co, meetco, isect2); + closest_to_line_v3(meetco, co, v->co, BM_edge_other_vert(emid->e, v)->co); + } + } + /* else iret == 1 and the lines are coplanar so meetco has the intersection */ } } @@ -753,8 +771,7 @@ static void build_boundary(MemArena *mem_arena, BevVert *bv) if (e->prev->prev->is_bev) { BLI_assert(e->prev->prev != e); /* see: edgecount 2, selcount 1 case */ /* find meet point between e->prev->prev and e and attach e->prev there */ - /* TODO: fix case when one or both faces in following are NULL */ - offset_in_two_planes(e->prev->prev, e, bv->v, + offset_in_two_planes(e->prev->prev, e, e->prev, bv->v, e->prev->prev->fnext, e->fprev, co); v = add_new_bound_vert(mem_arena, vm, co); v->efirst = e->prev->prev; -- cgit v1.2.3 From f23b6be620a0c43c9811a2242b6c97e271746ffb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 29 Nov 2012 14:02:28 +0000 Subject: fix [#33332] UV follow active quads rewrite the script to use bmesh connectivity info. --- .../startup/bl_operators/uvcalc_follow_active.py | 279 ++++++++------------- 1 file changed, 104 insertions(+), 175 deletions(-) diff --git a/release/scripts/startup/bl_operators/uvcalc_follow_active.py b/release/scripts/startup/bl_operators/uvcalc_follow_active.py index b60b5257984..727c4ad739f 100644 --- a/release/scripts/startup/bl_operators/uvcalc_follow_active.py +++ b/release/scripts/startup/bl_operators/uvcalc_follow_active.py @@ -26,195 +26,124 @@ from bpy.types import Operator def extend(obj, operator, EXTEND_MODE): - from bpy_extras import mesh_utils - + import bmesh me = obj.data - me_verts = me.vertices - # script will fail without UVs if not me.uv_textures: me.uv_textures.new() + + bm = bmesh.from_edit_mesh(me) + + f_act = bm.faces.active + uv_act = bm.loops.layers.uv.active + + if f_act is None: + operator.report({'ERROR'}, "No active face") + return + elif len(f_act.verts) != 4: + operator.report({'ERROR'}, "Active face must be a quad") + return - # Toggle Edit mode - is_editmode = (obj.mode == 'EDIT') - if is_editmode: - bpy.ops.object.mode_set(mode='OBJECT') - - #t = sys.time() - edge_average_lengths = {} - - OTHER_INDEX = 2, 3, 0, 1 - - def extend_uvs(face_source, face_target, edge_key): - """ - Takes 2 faces, - Projects its extends its UV coords onto the face next to it. - Both faces must share an edge - """ - - def face_edge_vs(vi): - vlen = len(vi) - return [(vi[i], vi[(i + 1) % vlen]) for i in range(vlen)] - - vidx_source = face_source.vertices - vidx_target = face_target.vertices - - uv_layer = me.uv_layers.active.data - uvs_source = [uv_layer[i].uv for i in face_source.loop_indices] - uvs_target = [uv_layer[i].uv for i in face_target.loop_indices] - - # vertex index is the key, uv is the value - - uvs_vhash_source = {vindex: uvs_source[i] for i, vindex in enumerate(vidx_source)} - - uvs_vhash_target = {vindex: uvs_target[i] for i, vindex in enumerate(vidx_target)} - - edge_idxs_source = face_edge_vs(vidx_source) - edge_idxs_target = face_edge_vs(vidx_target) - - source_matching_edge = -1 - target_matching_edge = -1 - - edge_key_swap = edge_key[1], edge_key[0] - - try: - source_matching_edge = edge_idxs_source.index(edge_key) - except: - source_matching_edge = edge_idxs_source.index(edge_key_swap) - try: - target_matching_edge = edge_idxs_target.index(edge_key) - except: - target_matching_edge = edge_idxs_target.index(edge_key_swap) - - edgepair_inner_source = edge_idxs_source[source_matching_edge] - edgepair_inner_target = edge_idxs_target[target_matching_edge] - edgepair_outer_source = edge_idxs_source[OTHER_INDEX[source_matching_edge]] - edgepair_outer_target = edge_idxs_target[OTHER_INDEX[target_matching_edge]] - - if edge_idxs_source[source_matching_edge] == edge_idxs_target[target_matching_edge]: - iA = 0 # Flipped, most common - iB = 1 - else: # The normals of these faces must be different - iA = 1 - iB = 0 + faces = [f for f in bm.faces if f.select and len(f.verts) == 4] + + for f in faces: + f.tag = False + f_act.tag = True + + + # our own local walker + def walk_face(f): + # all faces in this list must be tagged + f.tag = True + faces_a = [f] + faces_b = [] + + while faces_a: + for f in faces_a: + for l in f.loops: + l_edge = l.edge + if (l_edge.is_manifold is True) and (l_edge.seam is False): + l_other = l.link_loop_radial_next + f_other = l_other.face + if not f_other.tag: + yield (f, l, f_other) + f_other.tag = True + faces_b.append(f_other) + # swap + faces_a, faces_b = faces_b, faces_a + faces_b.clear() + + def extrapolate_uv(fac, + l_a_outer, l_a_inner, + l_b_outer, l_b_inner): + l_b_inner[:] = l_a_inner + l_b_outer[:] = l_a_inner + ((l_a_inner - l_a_outer) * fac) + + def apply_uv(f_prev, l_prev, f_next): + l_a = [None, None, None, None] + l_b = [None, None, None, None] + + l_a[0] = l_prev + l_a[1] = l_a[0].link_loop_next + l_a[2] = l_a[1].link_loop_next + l_a[3] = l_a[2].link_loop_next + + # l_b + # +-----------+ + # |(3) |(2) + # | | + # |l_next(0) |(1) + # +-----------+ + # ^ + # l_a | + # +-----------+ + # |l_prev(0) |(1) + # | (f) | + # |(3) |(2) + # +-----------+ + # copy from this face to the one above. + + # get the other loops + l_next = l_prev.link_loop_radial_next + if l_next.vert != l_prev.vert: + l_b[1] = l_next + l_b[0] = l_b[1].link_loop_next + l_b[3] = l_b[0].link_loop_next + l_b[2] = l_b[3].link_loop_next + else: + l_b[0] = l_next + l_b[1] = l_b[0].link_loop_next + l_b[2] = l_b[1].link_loop_next + l_b[3] = l_b[2].link_loop_next - # Set the target UV's touching source face, no tricky calculations needed, - uvs_vhash_target[edgepair_inner_target[0]][:] = uvs_vhash_source[edgepair_inner_source[iA]] - uvs_vhash_target[edgepair_inner_target[1]][:] = uvs_vhash_source[edgepair_inner_source[iB]] + l_a_uv = [l[uv_act].uv for l in l_a] + l_b_uv = [l[uv_act].uv for l in l_b] - # Set the 2 UV's on the target face that are not touching - # for this we need to do basic expanding on the source faces UV's if EXTEND_MODE == 'LENGTH': + a0, b0, c0 = l_a[3].vert.co, l_a[0].vert.co, l_b[3].vert.co + a1, b1, c1 = l_a[2].vert.co, l_a[1].vert.co, l_b[2].vert.co - try: # divide by zero is possible - ''' - measure the length of each face from the middle of each edge to the opposite - along the axis we are copying, use this - ''' - i1a = edgepair_outer_target[iB] - i2a = edgepair_inner_target[iA] - if i1a > i2a: - i1a, i2a = i2a, i1a - - i1b = edgepair_outer_source[iB] - i2b = edgepair_inner_source[iA] - if i1b > i2b: - i1b, i2b = i2b, i1b - # print edge_average_lengths - factor = edge_average_lengths[i1a, i2a][0] / edge_average_lengths[i1b, i2b][0] - except: - # Div By Zero? - factor = 1.0 - - uvs_vhash_target[edgepair_outer_target[iB]][:] = uvs_vhash_source[edgepair_inner_source[0]] + factor * (uvs_vhash_source[edgepair_inner_source[0]] - uvs_vhash_source[edgepair_outer_source[1]]) - uvs_vhash_target[edgepair_outer_target[iA]][:] = uvs_vhash_source[edgepair_inner_source[1]] + factor * (uvs_vhash_source[edgepair_inner_source[1]] - uvs_vhash_source[edgepair_outer_source[0]]) - + d1 = (a0 - b0).length + (a1 - b1).length + d2 = (b0 - c0).length + (b1 - c1).length + try: + fac = d2 / d1 + except ZeroDivisionError: + fac = 1.0 else: - # same as above but with no factors - uvs_vhash_target[edgepair_outer_target[iB]][:] = uvs_vhash_source[edgepair_inner_source[0]] + (uvs_vhash_source[edgepair_inner_source[0]] - uvs_vhash_source[edgepair_outer_source[1]]) - uvs_vhash_target[edgepair_outer_target[iA]][:] = uvs_vhash_source[edgepair_inner_source[1]] + (uvs_vhash_source[edgepair_inner_source[1]] - uvs_vhash_source[edgepair_outer_source[0]]) + fac = 1.0 - face_act = me.polygons.active - if face_act == -1: - operator.report({'ERROR'}, "No active face") - return + extrapolate_uv(fac, + l_a_uv[3], l_a_uv[0], + l_b_uv[3], l_b_uv[0]) - face_sel = [f for f in me.polygons if len(f.vertices) == 4 and f.select] + extrapolate_uv(fac, + l_a_uv[2], l_a_uv[1], + l_b_uv[2], l_b_uv[1]) - face_act_local_index = -1 - for i, f in enumerate(face_sel): - if f.index == face_act: - face_act_local_index = i - break + for f_triple in walk_face(f_act): + apply_uv(*f_triple) - if face_act_local_index == -1: - operator.report({'ERROR'}, "Active face not selected") - return - - # Modes - # 0 not yet searched for. - # 1:mapped, use search from this face - removed! - # 2:all siblings have been searched. don't search again. - face_modes = [0] * len(face_sel) - face_modes[face_act_local_index] = 1 # extend UV's from this face. - - # Edge connectivity - edge_faces = {} - for i, f in enumerate(face_sel): - for edkey in f.edge_keys: - try: - edge_faces[edkey].append(i) - except: - edge_faces[edkey] = [i] - - if EXTEND_MODE == 'LENGTH': - edge_loops = mesh_utils.edge_loops_from_tessfaces(me, face_sel, [ed.key for ed in me.edges if ed.use_seam]) - me_verts = me.vertices - for loop in edge_loops: - looplen = [0.0] - for ed in loop: - edge_average_lengths[ed] = looplen - looplen[0] += (me_verts[ed[0]].co - me_verts[ed[1]].co).length - looplen[0] = looplen[0] / len(loop) - - # remove seams, so we don't map across seams. - for ed in me.edges: - if ed.use_seam: - # remove the edge pair if we can - try: - del edge_faces[ed.key] - except: - pass - # Done finding seams - - # face connectivity - faces around each face - # only store a list of indices for each face. - face_faces = [[] for i in range(len(face_sel))] - - for edge_key, faces in edge_faces.items(): - if len(faces) == 2: # Only do edges with 2 face users for now - face_faces[faces[0]].append((faces[1], edge_key)) - face_faces[faces[1]].append((faces[0], edge_key)) - - # Now we know what face is connected to what other face, map them by connectivity - ok = True - while ok: - ok = False - for i in range(len(face_sel)): - if face_modes[i] == 1: # searchable - for f_sibling, edge_key in face_faces[i]: - if face_modes[f_sibling] == 0: - face_modes[f_sibling] = 1 # mapped and search from. - extend_uvs(face_sel[i], face_sel[f_sibling], edge_key) - face_modes[i] = 1 # we can map from this one now. - ok = True # keep searching - - face_modes[i] = 2 # don't search again - - if is_editmode: - bpy.ops.object.mode_set(mode='EDIT') - else: - me.update_tag() + bmesh.update_edit_mesh(me, False) def main(context, operator): -- cgit v1.2.3 From f1745706adcd2337fe183e30c1b026a05c198839 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 29 Nov 2012 16:11:37 +0000 Subject: Fix cycles motion blur + OSL + object texture coordinates issue. --- intern/cycles/kernel/osl/osl_services.cpp | 13 +++++++++++-- intern/cycles/kernel/osl/osl_shader.cpp | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index e79c509b144..e593387093c 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -80,7 +80,12 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr if (object != ~0) { #ifdef __OBJECT_MOTION__ - Transform tfm = object_fetch_transform_motion_test(kg, object, time, NULL); + Transform tfm; + + if(time == sd->time) + tfm = sd->ob_tfm; + else + tfm = object_fetch_transform_motion_test(kg, object, time, NULL); #else Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); #endif @@ -106,7 +111,11 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform if (object != ~0) { #ifdef __OBJECT_MOTION__ Transform itfm; - object_fetch_transform_motion_test(kg, object, time, &itfm); + + if(time == sd->time) + itfm = sd->ob_itfm; + else + object_fetch_transform_motion_test(kg, object, time, &itfm); #else Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); #endif diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index abf7c041cb3..2d025f12055 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -106,6 +106,7 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd, globals->dPdu = TO_VEC3(sd->dPdu); globals->dPdv = TO_VEC3(sd->dPdv); globals->surfacearea = (sd->object == ~0) ? 1.0f : object_surface_area(kg, sd->object); + globals->time = sd->time; /* booleans */ globals->raytype = path_flag; /* todo: add our own ray types */ -- cgit v1.2.3 From 07ccd3ee3f9700730a60013a66b09466af2585d3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 29 Nov 2012 16:26:39 +0000 Subject: fix [#33029] Applying modifier leaks memory Thanks for Sergey for finding the bug & patching, This fix works a bit differently. Theres no need to allocate the customdata in the first place - since its written into. So add a flag for vert/edge/face/loop creation functions so they can skip customdata creation. --- source/blender/blenkernel/intern/modifiers_bmesh.c | 6 +- source/blender/bmesh/intern/bmesh_construct.c | 28 +++--- source/blender/bmesh/intern/bmesh_construct.h | 4 +- source/blender/bmesh/intern/bmesh_core.c | 102 ++++++++++++--------- source/blender/bmesh/intern/bmesh_core.h | 15 ++- source/blender/bmesh/intern/bmesh_mesh_conv.c | 6 +- source/blender/bmesh/operators/bmo_create.c | 24 ++--- source/blender/bmesh/operators/bmo_dupe.c | 6 +- source/blender/bmesh/operators/bmo_extrude.c | 14 +-- source/blender/bmesh/operators/bmo_hull.c | 6 +- source/blender/bmesh/operators/bmo_inset.c | 4 +- source/blender/bmesh/operators/bmo_primitive.c | 46 +++++----- source/blender/bmesh/operators/bmo_removedoubles.c | 4 +- source/blender/bmesh/operators/bmo_symmetrize.c | 18 ++-- source/blender/bmesh/operators/bmo_utils.c | 2 +- source/blender/bmesh/operators/bmo_wireframe.c | 8 +- source/blender/bmesh/tools/bmesh_bevel.c | 8 +- source/blender/editors/mesh/editmesh_knife.c | 2 +- source/blender/modifiers/intern/MOD_skin.c | 16 ++-- source/blender/python/bmesh/bmesh_py_types.c | 10 +- 20 files changed, 177 insertions(+), 152 deletions(-) diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index 98eac9b95af..381e4350391 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -79,7 +79,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) /*do verts*/ mv = mvert = dm->dupVertArray(dm); for (i = 0; i < totvert; i++, mv++) { - v = BM_vert_create(bm, mv->co, NULL); + v = BM_vert_create(bm, mv->co, NULL, BM_CREATE_SKIP_CD); normal_short_to_float_v3(v->no, mv->no); v->head.hflag = BM_vert_flag_from_mflag(mv->flag); BM_elem_index_set(v, i); /* set_inline */ @@ -97,7 +97,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) me = medge = dm->dupEdgeArray(dm); for (i = 0; i < totedge; i++, me++) { //BLI_assert(BM_edge_exists(vtable[me->v1], vtable[me->v2]) == NULL); - e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, FALSE); + e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, BM_CREATE_SKIP_CD); e->head.hflag = BM_edge_flag_from_mflag(me->flag); BM_elem_index_set(e, i); /* set_inline */ @@ -134,7 +134,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) edges[j] = etable[ml->e]; } - f = BM_face_create_ngon(bm, verts[0], verts[1], edges, mp->totloop, FALSE); + f = BM_face_create_ngon(bm, verts[0], verts[1], edges, mp->totloop, BM_CREATE_SKIP_CD); if (UNLIKELY(f == NULL)) { continue; diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index 770196108f0..8b7fac1eacd 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -105,17 +105,17 @@ BMFace *BM_face_create_quad_tri_v(BMesh *bm, BMVert **verts, int len, const BMFa /* make new face */ if ((f == NULL) && (!is_overlap)) { BMEdge *edar[4] = {NULL}; - edar[0] = BM_edge_create(bm, verts[0], verts[1], NULL, TRUE); - edar[1] = BM_edge_create(bm, verts[1], verts[2], NULL, TRUE); + edar[0] = BM_edge_create(bm, verts[0], verts[1], NULL, BM_CREATE_NO_DOUBLE); + edar[1] = BM_edge_create(bm, verts[1], verts[2], NULL, BM_CREATE_NO_DOUBLE); if (len == 4) { - edar[2] = BM_edge_create(bm, verts[2], verts[3], NULL, TRUE); - edar[3] = BM_edge_create(bm, verts[3], verts[0], NULL, TRUE); + edar[2] = BM_edge_create(bm, verts[2], verts[3], NULL, BM_CREATE_NO_DOUBLE); + edar[3] = BM_edge_create(bm, verts[3], verts[0], NULL, BM_CREATE_NO_DOUBLE); } else { - edar[2] = BM_edge_create(bm, verts[2], verts[0], NULL, TRUE); + edar[2] = BM_edge_create(bm, verts[2], verts[0], NULL, BM_CREATE_NO_DOUBLE); } - f = BM_face_create(bm, verts, edar, len, FALSE); + f = BM_face_create(bm, verts, edar, len, 0); if (example && f) { BM_elem_attrs_copy(bm, bm, example, f); @@ -171,7 +171,7 @@ void BM_face_copy_shared(BMesh *bm, BMFace *f) * #BM_face_create should be considered over this function as it * avoids some unnecessary work. */ -BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, int nodouble) +BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, const int create_flag) { BMEdge **edges2 = NULL; BLI_array_staticdeclare(edges2, BM_DEFAULT_NGON_STACK_SIZE); @@ -282,7 +282,7 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i BM_ELEM_API_FLAG_DISABLE(verts[i], _FLAG_MV); } - f = BM_face_create(bm, verts, edges2, len, nodouble); + f = BM_face_create(bm, verts, edges2, len, create_flag); /* clean up flags */ for (i = 0; i < len; i++) { @@ -338,7 +338,7 @@ static int angle_index_pair_cmp(const void *e1, const void *e2) * * \note Since this is a vcloud there is no direction. */ -BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int totv, int nodouble) +BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int totv, const int create_flag) { BMFace *f; @@ -464,7 +464,7 @@ BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int totv, int n i_prev = totv - 1; for (i = 0; i < totv; i++) { - edge_arr[i] = BM_edge_create(bm, vert_arr_map[i_prev], vert_arr_map[i], NULL, TRUE); + edge_arr[i] = BM_edge_create(bm, vert_arr_map[i_prev], vert_arr_map[i], NULL, BM_CREATE_NO_DOUBLE); /* the edge may exist already and be attached to a face * in this case we can find the best winding to use for the new face */ @@ -493,7 +493,7 @@ BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int totv, int n /* --- */ /* create the face */ - f = BM_face_create_ngon(bm, vert_arr_map[winding[0]], vert_arr_map[winding[1]], edge_arr, totv, nodouble); + f = BM_face_create_ngon(bm, vert_arr_map[winding[0]], vert_arr_map[winding[1]], edge_arr, totv, create_flag); MEM_freeN(edge_arr); MEM_freeN(vert_arr_map); @@ -856,7 +856,7 @@ BMesh *BM_mesh_copy(BMesh *bm_old) v = BM_iter_new(&iter, bm_old, BM_VERTS_OF_MESH, NULL); for (i = 0; v; v = BM_iter_step(&iter), i++) { - v2 = BM_vert_create(bm_new, v->co, NULL); /* copy between meshes so cant use 'example' argument */ + v2 = BM_vert_create(bm_new, v->co, NULL, BM_CREATE_SKIP_CD); /* copy between meshes so cant use 'example' argument */ BM_elem_attrs_copy(bm_old, bm_new, v, v2); vtable[i] = v2; BM_elem_index_set(v, i); /* set_inline */ @@ -873,7 +873,7 @@ BMesh *BM_mesh_copy(BMesh *bm_old) e2 = BM_edge_create(bm_new, vtable[BM_elem_index_get(e->v1)], vtable[BM_elem_index_get(e->v2)], - e, FALSE); + e, BM_CREATE_SKIP_CD); BM_elem_attrs_copy(bm_old, bm_new, e, e2); etable[i] = e2; @@ -909,7 +909,7 @@ BMesh *BM_mesh_copy(BMesh *bm_old) v2 = vtable[BM_elem_index_get(loops[0]->v)]; } - f2 = BM_face_create_ngon(bm_new, v, v2, edges, f->len, FALSE); + f2 = BM_face_create_ngon(bm_new, v, v2, edges, f->len, BM_CREATE_SKIP_CD); if (UNLIKELY(f2 == NULL)) { continue; } diff --git a/source/blender/bmesh/intern/bmesh_construct.h b/source/blender/bmesh/intern/bmesh_construct.h index 29b84046884..60c465e5f5a 100644 --- a/source/blender/bmesh/intern/bmesh_construct.h +++ b/source/blender/bmesh/intern/bmesh_construct.h @@ -36,9 +36,9 @@ BMFace *BM_face_create_quad_tri(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, B void BM_face_copy_shared(BMesh *bm, BMFace *f); -BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, int nodouble); +BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, const int create_flag); -BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int len, int nodouble); +BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int len, const int create_flag); void BMO_remove_tagged_faces(BMesh *bm, const short oflag); void BMO_remove_tagged_edges(BMesh *bm, const short oflag); diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 541ac28bf1a..059f9de5a42 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -54,7 +54,7 @@ /** * \brief Main function for creating a new vertex. */ -BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example) +BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example, const eBMCreateFlag create_flag) { BMVert *v = BLI_mempool_calloc(bm->vpool); @@ -64,6 +64,9 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example) BM_elem_index_set(v, -1); /* set_ok_invalid */ #endif + /* disallow this flag for verts - its meaningless */ + BLI_assert((create_flag & BM_CREATE_NO_DOUBLE) == 0); + bm->elem_index_dirty |= BM_VERT; /* may add to middle of the pool */ bm->totvert++; @@ -80,17 +83,20 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example) v->oflags = BLI_mempool_calloc(bm->toolflagpool); } - CustomData_bmesh_set_default(&bm->vdata, &v->head.data); - - if (example) { - int *keyi; + if (!(create_flag & BM_CREATE_SKIP_CD)) { + if (example) { + int *keyi; - BM_elem_attrs_copy(bm, bm, example, v); + BM_elem_attrs_copy(bm, bm, example, v); - /* exception: don't copy the original shapekey index */ - keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX); - if (keyi) { - *keyi = ORIGINDEX_NONE; + /* exception: don't copy the original shapekey index */ + keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX); + if (keyi) { + *keyi = ORIGINDEX_NONE; + } + } + else { + CustomData_bmesh_set_default(&bm->vdata, &v->head.data); } } @@ -105,11 +111,11 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example) * \note Duplicate edges are supported by the API however users should _never_ see them. * so unless you need a unique edge or know the edge won't exist, you should call with \a nodouble = TRUE */ -BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, int nodouble) +BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, const eBMCreateFlag create_flag) { BMEdge *e; - if (nodouble && (e = BM_edge_exists(v1, v2))) + if ((create_flag & BM_CREATE_NO_DOUBLE) && (e = BM_edge_exists(v1, v2))) return e; e = BLI_mempool_calloc(bm->epool); @@ -136,20 +142,26 @@ BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, BM_elem_flag_enable(e, BM_ELEM_SMOOTH | BM_ELEM_DRAW); - CustomData_bmesh_set_default(&bm->edata, &e->head.data); - bmesh_disk_edge_append(e, e->v1); bmesh_disk_edge_append(e, e->v2); - if (example) - BM_elem_attrs_copy(bm, bm, example, e); + if (!(create_flag & BM_CREATE_SKIP_CD)) { + if (example) { + BM_elem_attrs_copy(bm, bm, example, e); + } + else { + CustomData_bmesh_set_default(&bm->edata, &e->head.data); + } + } + BM_CHECK_ELEMENT(e); return e; } -static BMLoop *bm_loop_create(BMesh *bm, BMVert *v, BMEdge *e, BMFace *f, const BMLoop *example) +static BMLoop *bm_loop_create(BMesh *bm, BMVert *v, BMEdge *e, BMFace *f, + const BMLoop *example, const eBMCreateFlag create_flag) { BMLoop *l = NULL; @@ -164,22 +176,24 @@ static BMLoop *bm_loop_create(BMesh *bm, BMVert *v, BMEdge *e, BMFace *f, const bm->totloop++; - if (example) { - CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, example->head.data, &l->head.data); - } - else { - CustomData_bmesh_set_default(&bm->ldata, &l->head.data); + if (!(create_flag & BM_CREATE_SKIP_CD)) { + if (example) { + CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, example->head.data, &l->head.data); + } + else { + CustomData_bmesh_set_default(&bm->ldata, &l->head.data); + } } return l; } -static BMLoop *bm_face_boundary_add(BMesh *bm, BMFace *f, BMVert *startv, BMEdge *starte) +static BMLoop *bm_face_boundary_add(BMesh *bm, BMFace *f, BMVert *startv, BMEdge *starte, const int create_flag) { #ifdef USE_BMESH_HOLES BMLoopList *lst = BLI_mempool_calloc(bm->looplistpool); #endif - BMLoop *l = bm_loop_create(bm, startv, starte, f, NULL); + BMLoop *l = bm_loop_create(bm, startv, starte, f, starte->l, create_flag); bmesh_radial_append(starte, l); @@ -211,7 +225,7 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co i = 0; do { if (copyverts) { - verts[i] = BM_vert_create(bm, l_iter->v->co, l_iter->v); + verts[i] = BM_vert_create(bm, l_iter->v->co, l_iter->v, 0); } else { verts[i] = l_iter->v; @@ -234,7 +248,7 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co v1 = verts[(i + 1) % f->len]; } - edges[i] = BM_edge_create(bm, v1, v2, l_iter->e, FALSE); + edges[i] = BM_edge_create(bm, v1, v2, l_iter->e, 0); } else { edges[i] = l_iter->e; @@ -242,7 +256,7 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co i++; } while ((l_iter = l_iter->next) != l_first); - f_copy = BM_face_create(bm, verts, edges, f->len, FALSE); + f_copy = BM_face_create(bm, verts, edges, f->len, BM_CREATE_SKIP_CD); BM_elem_attrs_copy(bm, bm, f, f_copy); @@ -263,7 +277,7 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co * only create the face, since this calloc's the length is initialized to 0, * leave adding loops to the caller. */ -BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm) +BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm, const eBMCreateFlag create_flag) { BMFace *f; @@ -286,7 +300,9 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm) f->oflags = BLI_mempool_calloc(bm->toolflagpool); } - CustomData_bmesh_set_default(&bm->pdata, &f->head.data); + if (!(create_flag & BM_CREATE_SKIP_CD)) { + CustomData_bmesh_set_default(&bm->pdata, &f->head.data); + } #ifdef USE_BMESH_HOLES f->totbounds = 0; @@ -298,7 +314,7 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm) /** * \brief Main face creation function */ -BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, int nodouble) +BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, const eBMCreateFlag create_flag) { BMFace *f = NULL; BMLoop *l, *startl, *lastl; @@ -309,7 +325,7 @@ BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, return NULL; } - if (nodouble) { + if (create_flag & BM_CREATE_NO_DOUBLE) { /* Check if face already exists */ overlap = BM_face_exists(verts, len, &f); if (overlap) { @@ -320,14 +336,14 @@ BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, } } - f = bm_face_create__internal(bm); + f = bm_face_create__internal(bm, create_flag); - startl = lastl = bm_face_boundary_add(bm, f, verts[0], edges[0]); + startl = lastl = bm_face_boundary_add(bm, f, verts[0], edges[0], create_flag); startl->v = verts[0]; startl->e = edges[0]; for (i = 1; i < len; i++) { - l = bm_loop_create(bm, verts[i], edges[i], f, edges[i]->l); + l = bm_loop_create(bm, verts[i], edges[i], f, edges[i]->l, create_flag); l->f = f; bmesh_radial_append(edges[i], l); @@ -1033,7 +1049,7 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del } /* create region face */ - newf = BM_face_create_ngon(bm, v1, v2, edges, tote, FALSE); + newf = BM_face_create_ngon(bm, v1, v2, edges, tote, 0); if (UNLIKELY(!newf || BMO_error_occurred(bm))) { if (!BMO_error_occurred(bm)) err = N_("Invalid boundary region to join faces"); @@ -1139,7 +1155,7 @@ static BMFace *bm_face_create__sfme(BMesh *bm, BMFace *UNUSED(example)) BMLoopList *lst; #endif - f = bm_face_create__internal(bm); + f = bm_face_create__internal(bm, 0); #ifdef USE_BMESH_HOLES lst = BLI_mempool_calloc(bm->looplistpool); @@ -1226,8 +1242,8 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, e = BM_edge_create(bm, v1, v2, example, nodouble); f2 = bm_face_create__sfme(bm, f); - f1loop = bm_loop_create(bm, v2, e, f, v2loop); - f2loop = bm_loop_create(bm, v1, e, f2, v1loop); + f1loop = bm_loop_create(bm, v2, e, f, v2loop, 0); + f2loop = bm_loop_create(bm, v1, e, f2, v1loop, 0); f1loop->prev = v2loop->prev; f2loop->prev = v1loop->prev; @@ -1359,8 +1375,8 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) valence2 = bmesh_disk_count(tv); - nv = BM_vert_create(bm, tv->co, tv); - ne = BM_edge_create(bm, nv, tv, e, FALSE); + nv = BM_vert_create(bm, tv->co, tv, 0); + ne = BM_edge_create(bm, nv, tv, e, 0); bmesh_disk_edge_remove(ne, tv); bmesh_disk_edge_remove(ne, nv); @@ -1403,7 +1419,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) nextl = nextl != nextl->radial_next ? nextl->radial_next : NULL; bmesh_radial_loop_remove(l, NULL); - nl = bm_loop_create(bm, NULL, NULL, l->f, l); + nl = bm_loop_create(bm, NULL, NULL, l->f, l, 0); nl->prev = l; nl->next = (l->next); nl->prev->next = nl; @@ -1919,7 +1935,7 @@ int bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len) verts = MEM_callocN(sizeof(BMVert *) * maxindex, __func__); verts[0] = v; for (i = 1; i < maxindex; i++) { - verts[i] = BM_vert_create(bm, v->co, v); + verts[i] = BM_vert_create(bm, v->co, v, 0); } /* Replace v with the new verts in each group */ @@ -2085,7 +2101,7 @@ int bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep) e->l = l_sep->radial_next; } - ne = BM_edge_create(bm, e->v1, e->v2, e, FALSE); + ne = BM_edge_create(bm, e->v1, e->v2, e, 0); bmesh_radial_loop_remove(l_sep, e); bmesh_radial_append(ne, l_sep); l_sep->e = ne; diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h index 0667ed9ea1c..5fd4a6ec7df 100644 --- a/source/blender/bmesh/intern/bmesh_core.h +++ b/source/blender/bmesh/intern/bmesh_core.h @@ -29,9 +29,18 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short copyedges); -BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example); -BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, int nodouble); -BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, int nodouble); +typedef enum eBMCreateFlag { + /* faces and edges only */ + BM_CREATE_NO_DOUBLE = (1 << 1), + /* Skip CustomData - for all element types data, + * use if we immediately write customdata into the element so this skips copying from 'example' + * args or setting defaults, speeds up conversion when data is converted all at once. */ + BM_CREATE_SKIP_CD = (1 << 2), +} eBMCreateFlag; + +BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example, const eBMCreateFlag create_flag); +BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, const eBMCreateFlag create_flag); +BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, const eBMCreateFlag create_flag); void BM_face_edges_kill(BMesh *bm, BMFace *f); void BM_face_verts_kill(BMesh *bm, BMFace *f); diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index 62abf43829b..6617cc806c7 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -206,7 +206,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE); for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) { - v = BM_vert_create(bm, keyco && set_key ? keyco[i] : mvert->co, NULL); + v = BM_vert_create(bm, keyco && set_key ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD); BM_elem_index_set(v, i); /* set_ok */ vt[i] = v; @@ -254,7 +254,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) medge = me->medge; for (i = 0; i < me->totedge; i++, medge++) { - e = BM_edge_create(bm, vt[medge->v1], vt[medge->v2], NULL, FALSE); + e = BM_edge_create(bm, vt[medge->v1], vt[medge->v2], NULL, BM_CREATE_SKIP_CD); BM_elem_index_set(e, i); /* set_ok */ et[i] = e; @@ -312,7 +312,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) } #endif - f = BM_face_create(bm, verts, fedges, mpoly->totloop, FALSE); + f = BM_face_create(bm, verts, fedges, mpoly->totloop, BM_CREATE_SKIP_CD); if (UNLIKELY(f == NULL)) { printf("%s: Warning! Bad face in mesh" diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c index a6bbd092760..aa69806fb37 100644 --- a/source/blender/bmesh/operators/bmo_create.c +++ b/source/blender/bmesh/operators/bmo_create.c @@ -274,7 +274,7 @@ static int UNUSED_FUNCTION(rotsys_fill_faces)(BMesh *bm, EdgeData *edata, VertDa if (!ok || BLI_array_count(edges) < 3) continue; - f = BM_face_create_ngon(bm, verts[0], verts[1], edges, BLI_array_count(edges), TRUE); + f = BM_face_create_ngon(bm, verts[0], verts[1], edges, BLI_array_count(edges), BM_CREATE_NO_DOUBLE); if (UNLIKELY(f == NULL)) { continue; } @@ -611,11 +611,11 @@ static void init_rotsys(BMesh *bm, EdgeData *edata, VertData *vdata) v2 = BM_vert_create(bm, co, NULL); BM_elem_index_set(v2, -1); /* set_dirty! */ - //BM_edge_create(bm, cv, v2, NULL, FALSE); + //BM_edge_create(bm, cv, v2, NULL, 0); BM_vert_select_set(bm, v2, TRUE); if (lastv) { - e2 = BM_edge_create(bm, lastv, v2, NULL, FALSE); + e2 = BM_edge_create(bm, lastv, v2, NULL, 0); BM_edge_select_set(bm, e2, TRUE); } @@ -1051,7 +1051,7 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op) /* fairly expensive check - see if there are already faces filling this area */ (BM_face_exists_multi_edge(edges, i) == FALSE)) { - f = BM_face_create_ngon(bm, v1, v2, edges, i, TRUE); + f = BM_face_create_ngon(bm, v1, v2, edges, i, BM_CREATE_NO_DOUBLE); if (f && !BMO_elem_flag_test(bm, f, ELE_ORIG)) { BMO_elem_flag_enable(bm, f, FACE_NEW); f->mat_nr = mat_nr; @@ -1249,9 +1249,9 @@ void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op) SWAP(BMVert *, v3, v4); } - e = BM_edge_create(bm, v1, v3, NULL, TRUE); + e = BM_edge_create(bm, v1, v3, NULL, BM_CREATE_NO_DOUBLE); BMO_elem_flag_enable(bm, e, ELE_NEW); - e = BM_edge_create(bm, v2, v4, NULL, TRUE); + e = BM_edge_create(bm, v2, v4, NULL, BM_CREATE_NO_DOUBLE); BMO_elem_flag_enable(bm, e, ELE_NEW); } else if (edges1) { @@ -1261,7 +1261,7 @@ void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op) v1 = BM_vert_in_edge(edges1[1], edges1[0]->v1) ? edges1[0]->v2 : edges1[0]->v1; i = BLI_array_count(edges1) - 1; v2 = BM_vert_in_edge(edges1[i - 1], edges1[i]->v1) ? edges1[i]->v2 : edges1[i]->v1; - e = BM_edge_create(bm, v1, v2, NULL, TRUE); + e = BM_edge_create(bm, v1, v2, NULL, BM_CREATE_NO_DOUBLE); BMO_elem_flag_enable(bm, e, ELE_NEW); } } @@ -1359,10 +1359,10 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) } if (ok == TRUE && v_free && v_a && v_b) { - e = BM_edge_create(bm, v_free, v_a, NULL, TRUE); + e = BM_edge_create(bm, v_free, v_a, NULL, BM_CREATE_NO_DOUBLE); BMO_elem_flag_enable(bm, e, ELE_NEW); - e = BM_edge_create(bm, v_free, v_b, NULL, TRUE); + e = BM_edge_create(bm, v_free, v_b, NULL, BM_CREATE_NO_DOUBLE); BMO_elem_flag_enable(bm, e, ELE_NEW); } } @@ -1420,7 +1420,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) if (amount == 2) { /* create edge */ - e = BM_edge_create(bm, verts[0], verts[1], NULL, TRUE); + e = BM_edge_create(bm, verts[0], verts[1], NULL, BM_CREATE_NO_DOUBLE); BMO_elem_flag_enable(bm, e, ELE_OUT); BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, ELE_OUT); } @@ -1461,7 +1461,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) if (ese->htype == BM_VERT) { v = (BMVert *)ese->ele; if (v_prev) { - e = BM_edge_create(bm, v, v_prev, NULL, TRUE); + e = BM_edge_create(bm, v, v_prev, NULL, BM_CREATE_NO_DOUBLE); BMO_elem_flag_enable(bm, e, ELE_OUT); } v_prev = v; @@ -1483,7 +1483,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) i++; } - f = BM_face_create_ngon_vcloud(bm, vert_arr, totv, TRUE); + f = BM_face_create_ngon_vcloud(bm, vert_arr, totv, BM_CREATE_NO_DOUBLE); if (f) { BMO_elem_flag_enable(bm, f, ELE_OUT); diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c index 67460a0298e..9a58d7acfb9 100644 --- a/source/blender/bmesh/operators/bmo_dupe.c +++ b/source/blender/bmesh/operators/bmo_dupe.c @@ -49,7 +49,7 @@ static BMVert *copy_vertex(BMesh *source_mesh, BMVert *source_vertex, BMesh *tar BMVert *target_vertex = NULL; /* Create a new vertex */ - target_vertex = BM_vert_create(target_mesh, source_vertex->co, NULL); + target_vertex = BM_vert_create(target_mesh, source_vertex->co, NULL, BM_CREATE_SKIP_CD); /* Insert new vertex into the vert hash */ BLI_ghash_insert(vhash, source_vertex, target_vertex); @@ -98,7 +98,7 @@ static BMEdge *copy_edge(BMOperator *op, target_vert2 = BLI_ghash_lookup(vhash, source_edge->v2); /* Create a new edge */ - target_edge = BM_edge_create(target_mesh, target_vert1, target_vert2, NULL, FALSE); + target_edge = BM_edge_create(target_mesh, target_vert1, target_vert2, NULL, BM_CREATE_SKIP_CD); /* add to new/old edge map if necassary */ if (rlen < 2) { @@ -156,7 +156,7 @@ static BMFace *copy_face(BMOperator *op, } /* create new face */ - target_face = BM_face_create(target_mesh, vtar, edar, source_face->len, FALSE); + target_face = BM_face_create(target_mesh, vtar, edar, source_face->len, BM_CREATE_SKIP_CD); BMO_slot_map_elem_insert(op, slot_facemap_out, source_face, target_face); BMO_slot_map_elem_insert(op, slot_facemap_out, target_face, source_face); diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c index 1ab640ba6a5..065a1b57737 100644 --- a/source/blender/bmesh/operators/bmo_extrude.c +++ b/source/blender/bmesh/operators/bmo_extrude.c @@ -67,11 +67,11 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op) i = 0; firstv = lastv = NULL; BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - v = BM_vert_create(bm, l->v->co, l->v); + v = BM_vert_create(bm, l->v->co, l->v, 0); /* skip on the first iteration */ if (lastv) { - e = BM_edge_create(bm, lastv, v, l->e, FALSE); + e = BM_edge_create(bm, lastv, v, l->e, 0); edges[i++] = e; } @@ -81,12 +81,12 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op) } /* this fits in the array because we skip one in the loop above */ - e = BM_edge_create(bm, v, firstv, laste, FALSE); + e = BM_edge_create(bm, v, firstv, laste, 0); edges[i++] = e; BMO_elem_flag_enable(bm, f, EXT_DEL); - f2 = BM_face_create_ngon(bm, firstv, BM_edge_other_vert(edges[0], firstv), edges, f->len, FALSE); + f2 = BM_face_create_ngon(bm, firstv, BM_edge_other_vert(edges[0], firstv), edges, f->len, 0); if (UNLIKELY(f2 == NULL)) { BMO_error_raise(bm, op, BMERR_MESH_ERROR, "Extrude failed: could not create face"); BLI_array_free(edges); @@ -241,11 +241,11 @@ void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op) const int has_vskin = CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN); for (v = BMO_iter_new(&siter, op->slots_in, "verts", BM_VERT); v; v = BMO_iter_step(&siter)) { - dupev = BM_vert_create(bm, v->co, v); + dupev = BM_vert_create(bm, v->co, v, 0); if (has_vskin) bm_extrude_disable_skin_root(bm, v); - e = BM_edge_create(bm, v, dupev, NULL, FALSE); + e = BM_edge_create(bm, v, dupev, NULL, 0); BMO_elem_flag_enable(bm, e, EXT_KEEP); BMO_elem_flag_enable(bm, dupev, EXT_KEEP); @@ -430,7 +430,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) /* link isolated vert */ for (v = BMO_iter_new(&siter, dupeop.slots_out, "isovert_map.out", 0); v; v = BMO_iter_step(&siter)) { v2 = *((void **)BMO_iter_map_value(&siter)); - BM_edge_create(bm, v, v2, v->e, TRUE); + BM_edge_create(bm, v, v2, v->e, BM_CREATE_NO_DOUBLE); } /* cleanup */ diff --git a/source/blender/bmesh/operators/bmo_hull.c b/source/blender/bmesh/operators/bmo_hull.c index 08fc97ea262..e2da4f4f89c 100644 --- a/source/blender/bmesh/operators/bmo_hull.c +++ b/source/blender/bmesh/operators/bmo_hull.c @@ -113,9 +113,9 @@ static void hull_output_triangles(BMesh *bm, GHash *hull_triangles) if (!t->skip) { BMEdge *edges[3] = { - BM_edge_create(bm, t->v[0], t->v[1], NULL, TRUE), - BM_edge_create(bm, t->v[1], t->v[2], NULL, TRUE), - BM_edge_create(bm, t->v[2], t->v[0], NULL, TRUE) + BM_edge_create(bm, t->v[0], t->v[1], NULL, BM_CREATE_NO_DOUBLE), + BM_edge_create(bm, t->v[1], t->v[2], NULL, BM_CREATE_NO_DOUBLE), + BM_edge_create(bm, t->v[2], t->v[0], NULL, BM_CREATE_NO_DOUBLE) }; BMFace *f, *example = NULL; diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c index 9abf129a529..cef1181f63b 100644 --- a/source/blender/bmesh/operators/bmo_inset.c +++ b/source/blender/bmesh/operators/bmo_inset.c @@ -181,7 +181,7 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op) if (es->e_new == es->e_old) { /* happens on boundary edges */ /* take care here, we're creating this double edge which _must_ have its verts replaced later on */ - es->e_old = BM_edge_create(bm, es->e_new->v1, es->e_new->v2, es->e_new, FALSE); + es->e_old = BM_edge_create(bm, es->e_new->v1, es->e_new->v2, es->e_new, 0); } /* store index back to original in 'edge_info' */ @@ -205,7 +205,7 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op) v1 = BM_vert_create(bm, tvec, NULL); v2 = BM_vert_create(bm, tvec, NULL); madd_v3_v3fl(v2->co, es->no, 0.1f); - BM_edge_create(bm, v1, v2, NULL, FALSE); + BM_edge_create(bm, v1, v2, NULL, 0); } #endif diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c index b8f154350ea..c582f710f43 100644 --- a/source/blender/bmesh/operators/bmo_primitive.c +++ b/source/blender/bmesh/operators/bmo_primitive.c @@ -248,11 +248,11 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op) vec[2] = 0.0f; mul_m4_v3(mat, vec); - eve = BM_vert_create(bm, vec, NULL); + eve = BM_vert_create(bm, vec, NULL, 0); BMO_elem_flag_enable(bm, eve, VERT_MARK); if (a != 0) { - e = BM_edge_create(bm, preveve, eve, NULL, TRUE); + e = BM_edge_create(bm, preveve, eve, NULL, BM_CREATE_NO_DOUBLE); BMO_elem_flag_enable(bm, e, EDGE_ORIG); } @@ -317,11 +317,11 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op) vec[0] = -dia * sinf(phi); vec[1] = 0.0; vec[2] = dia * cosf(phi); - eve = BM_vert_create(bm, vec, NULL); + eve = BM_vert_create(bm, vec, NULL, 0); BMO_elem_flag_enable(bm, eve, VERT_MARK); if (a != 0) { - e = BM_edge_create(bm, preveve, eve, NULL, FALSE); + e = BM_edge_create(bm, preveve, eve, NULL, 0); BMO_elem_flag_enable(bm, e, EDGE_ORIG); } @@ -407,7 +407,7 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op) vec[0] = dia_div * icovert[a][0]; vec[1] = dia_div * icovert[a][1]; vec[2] = dia_div * icovert[a][2]; - eva[a] = BM_vert_create(bm, vec, NULL); + eva[a] = BM_vert_create(bm, vec, NULL, 0); BMO_elem_flag_enable(bm, eva[a], VERT_MARK); } @@ -470,12 +470,12 @@ void bmo_create_monkey_exec(BMesh *bm, BMOperator *op) v[0] = (monkeyv[i][0] + 127) / 128.0, v[1] = monkeyv[i][1] / 128.0, v[2] = monkeyv[i][2] / 128.0; - tv[i] = BM_vert_create(bm, v, NULL); + tv[i] = BM_vert_create(bm, v, NULL, 0); BMO_elem_flag_enable(bm, tv[i], VERT_MARK); tv[monkeynv + i] = (fabsf(v[0] = -v[0]) < 0.001f) ? tv[i] : - (eve = BM_vert_create(bm, v, NULL), mul_m4_v3(mat, eve->co), eve); + (eve = BM_vert_create(bm, v, NULL, 0), mul_m4_v3(mat, eve->co), eve); BMO_elem_flag_enable(bm, tv[monkeynv + i], VERT_MARK); @@ -527,7 +527,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op) zero_v3(vec); mul_m4_v3(mat, vec); - cent1 = BM_vert_create(bm, vec, NULL); + cent1 = BM_vert_create(bm, vec, NULL, 0); BMO_elem_flag_enable(bm, cent1, VERT_MARK); } @@ -537,12 +537,12 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op) vec[1] = dia * cosf(phi); vec[2] = 0.0f; mul_m4_v3(mat, vec); - v1 = BM_vert_create(bm, vec, NULL); + v1 = BM_vert_create(bm, vec, NULL, 0); BMO_elem_flag_enable(bm, v1, VERT_MARK); if (lastv1) - BM_edge_create(bm, v1, lastv1, NULL, FALSE); + BM_edge_create(bm, v1, lastv1, NULL, 0); if (a && cap_ends) { BMFace *f; @@ -560,7 +560,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op) if (!a) return; - BM_edge_create(bm, firstv1, lastv1, NULL, FALSE); + BM_edge_create(bm, firstv1, lastv1, NULL, 0); if (cap_ends) { BMFace *f; @@ -602,13 +602,13 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op) vec[2] = -depth; mul_m4_v3(mat, vec); - cent1 = BM_vert_create(bm, vec, NULL); + cent1 = BM_vert_create(bm, vec, NULL, 0); vec[0] = vec[1] = 0.0f; vec[2] = depth; mul_m4_v3(mat, vec); - cent2 = BM_vert_create(bm, vec, NULL); + cent2 = BM_vert_create(bm, vec, NULL, 0); BMO_elem_flag_enable(bm, cent1, VERT_MARK); BMO_elem_flag_enable(bm, cent2, VERT_MARK); @@ -619,13 +619,13 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op) vec[1] = dia1 * cosf(phi); vec[2] = -depth; mul_m4_v3(mat, vec); - v1 = BM_vert_create(bm, vec, NULL); + v1 = BM_vert_create(bm, vec, NULL, 0); vec[0] = dia2 * sinf(phi); vec[1] = dia2 * cosf(phi); vec[2] = depth; mul_m4_v3(mat, vec); - v2 = BM_vert_create(bm, vec, NULL); + v2 = BM_vert_create(bm, vec, NULL, 0); BMO_elem_flag_enable(bm, v1, VERT_MARK); BMO_elem_flag_enable(bm, v2, VERT_MARK); @@ -685,56 +685,56 @@ void bmo_create_cube_exec(BMesh *bm, BMOperator *op) vec[1] = -off; vec[2] = -off; mul_m4_v3(mat, vec); - v1 = BM_vert_create(bm, vec, NULL); + v1 = BM_vert_create(bm, vec, NULL, 0); BMO_elem_flag_enable(bm, v1, VERT_MARK); vec[0] = -off; vec[1] = off; vec[2] = -off; mul_m4_v3(mat, vec); - v2 = BM_vert_create(bm, vec, NULL); + v2 = BM_vert_create(bm, vec, NULL, 0); BMO_elem_flag_enable(bm, v2, VERT_MARK); vec[0] = off; vec[1] = off; vec[2] = -off; mul_m4_v3(mat, vec); - v3 = BM_vert_create(bm, vec, NULL); + v3 = BM_vert_create(bm, vec, NULL, 0); BMO_elem_flag_enable(bm, v3, VERT_MARK); vec[0] = off; vec[1] = -off; vec[2] = -off; mul_m4_v3(mat, vec); - v4 = BM_vert_create(bm, vec, NULL); + v4 = BM_vert_create(bm, vec, NULL, 0); BMO_elem_flag_enable(bm, v4, VERT_MARK); vec[0] = -off; vec[1] = -off; vec[2] = off; mul_m4_v3(mat, vec); - v5 = BM_vert_create(bm, vec, NULL); + v5 = BM_vert_create(bm, vec, NULL, 0); BMO_elem_flag_enable(bm, v5, VERT_MARK); vec[0] = -off; vec[1] = off; vec[2] = off; mul_m4_v3(mat, vec); - v6 = BM_vert_create(bm, vec, NULL); + v6 = BM_vert_create(bm, vec, NULL, 0); BMO_elem_flag_enable(bm, v6, VERT_MARK); vec[0] = off; vec[1] = off; vec[2] = off; mul_m4_v3(mat, vec); - v7 = BM_vert_create(bm, vec, NULL); + v7 = BM_vert_create(bm, vec, NULL, 0); BMO_elem_flag_enable(bm, v7, VERT_MARK); vec[0] = off; vec[1] = -off; vec[2] = off; mul_m4_v3(mat, vec); - v8 = BM_vert_create(bm, vec, NULL); + v8 = BM_vert_create(bm, vec, NULL, 0); BMO_elem_flag_enable(bm, v8, VERT_MARK); /* the four sides */ diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c index d27a90f0366..87e26f11d4b 100644 --- a/source/blender/bmesh/operators/bmo_removedoubles.c +++ b/source/blender/bmesh/operators/bmo_removedoubles.c @@ -136,7 +136,7 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op) BMO_elem_flag_enable(bm, e, EDGE_COL); } else if (!BM_edge_exists(v, v2)) { - BM_edge_create(bm, v, v2, e, TRUE); + BM_edge_create(bm, v, v2, e, BM_CREATE_NO_DOUBLE); } BMO_elem_flag_enable(bm, e, ELE_DEL); @@ -214,7 +214,7 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op) v2 = BMO_slot_map_elem_get(slot_targetmap, v2); } - f2 = BM_face_create_ngon(bm, v, v2, edges, a, TRUE); + f2 = BM_face_create_ngon(bm, v, v2, edges, a, BM_CREATE_NO_DOUBLE); if (f2 && (f2 != f)) { BM_elem_attrs_copy(bm, bm, f, f2); diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c b/source/blender/bmesh/operators/bmo_symmetrize.c index a58db1e6961..248c7268ac6 100644 --- a/source/blender/bmesh/operators/bmo_symmetrize.c +++ b/source/blender/bmesh/operators/bmo_symmetrize.c @@ -106,7 +106,7 @@ static void symm_verts_mirror(Symm *symm) copy_v3_v3(co, src_v->co); co[symm->axis] = -co[symm->axis]; - dst_v = BM_vert_create(symm->bm, co, src_v); + dst_v = BM_vert_create(symm->bm, co, src_v, 0); BMO_elem_flag_enable(symm->bm, dst_v, SYMM_OUTPUT_GEOM); BLI_ghash_insert(symm->vert_symm_map, src_v, dst_v); break; @@ -183,7 +183,7 @@ static void symm_split_asymmetric_edges(Symm *symm) co[symm->axis] = 0; /* Edge is asymmetric, split it with a new vertex */ - v = BM_vert_create(symm->bm, co, e->v1); + v = BM_vert_create(symm->bm, co, e->v1, 0); BMO_elem_flag_enable(symm->bm, v, SYMM_OUTPUT_GEOM); BLI_ghash_insert(symm->edge_split_map, e, v); } @@ -203,7 +203,7 @@ static void symm_mirror_edges(Symm *symm) v2 = BLI_ghash_lookup(symm->vert_symm_map, e->v2); if (v1 && v2) { - e_new = BM_edge_create(symm->bm, v1, v2, e, TRUE); + e_new = BM_edge_create(symm->bm, v1, v2, e, BM_CREATE_NO_DOUBLE); BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM); } else if (v1 || v2) { @@ -212,18 +212,18 @@ static void symm_mirror_edges(Symm *symm) /* Output the keep side of the split edge */ if (!v1) { - e_new = BM_edge_create(symm->bm, v_split, e->v2, e, TRUE); + e_new = BM_edge_create(symm->bm, v_split, e->v2, e, BM_CREATE_NO_DOUBLE); BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM); v1 = v_split; } else { - e_new = BM_edge_create(symm->bm, e->v1, v_split, e, TRUE); + e_new = BM_edge_create(symm->bm, e->v1, v_split, e, BM_CREATE_NO_DOUBLE); BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM); v2 = v_split; } /* Output the kill side of the split edge */ - e_new = BM_edge_create(symm->bm, v1, v2, e, TRUE); + e_new = BM_edge_create(symm->bm, v1, v2, e, BM_CREATE_NO_DOUBLE); BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM); } } @@ -356,7 +356,7 @@ static int symm_poly_next_crossing(const Symm *symm, } static BMFace *symm_face_create_v(BMesh *bm, BMFace *example, - BMVert **fv, BMEdge **fe, int len) + BMVert **fv, BMEdge **fe, int len) { BMFace *f_new; int i; @@ -365,11 +365,11 @@ static BMFace *symm_face_create_v(BMesh *bm, BMFace *example, int j = (i + 1) % len; fe[i] = BM_edge_exists(fv[i], fv[j]); if (!fe[i]) { - fe[i] = BM_edge_create(bm, fv[i], fv[j], NULL, FALSE); + fe[i] = BM_edge_create(bm, fv[i], fv[j], NULL, 0); BMO_elem_flag_enable(bm, fe[i], SYMM_OUTPUT_GEOM); } } - f_new = BM_face_create(bm, fv, fe, len, TRUE); + f_new = BM_face_create(bm, fv, fe, len, BM_CREATE_NO_DOUBLE); if (example) BM_elem_attrs_copy(bm, bm, example, f_new); BM_face_select_set(bm, f_new, TRUE); diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index b88bc51f586..64dbf0cc0e7 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -47,7 +47,7 @@ void bmo_create_vert_exec(BMesh *bm, BMOperator *op) BMO_slot_vec_get(op->slots_in, "co", vec); - BMO_elem_flag_enable(bm, BM_vert_create(bm, vec, NULL), 1); + BMO_elem_flag_enable(bm, BM_vert_create(bm, vec, NULL, 0), 1); BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "vert.out", BM_VERT, 1); } diff --git a/source/blender/bmesh/operators/bmo_wireframe.c b/source/blender/bmesh/operators/bmo_wireframe.c index 532145ab129..7401704310f 100644 --- a/source/blender/bmesh/operators/bmo_wireframe.c +++ b/source/blender/bmesh/operators/bmo_wireframe.c @@ -227,9 +227,9 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op) } madd_v3_v3v3fl(tvec, v_src->co, v_src->no, -fac); - verts_neg[i] = BM_vert_create(bm, tvec, v_src); + verts_neg[i] = BM_vert_create(bm, tvec, v_src, 0); madd_v3_v3v3fl(tvec, v_src->co, v_src->no, fac); - verts_pos[i] = BM_vert_create(bm, tvec, v_src); + verts_pos[i] = BM_vert_create(bm, tvec, v_src, 0); } else { /* could skip this */ @@ -267,7 +267,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op) } madd_v3_v3v3fl(tvec, l->v->co, tvec, fac); - verts_loop[verts_loop_tot] = BM_vert_create(bm, tvec, l->v); + verts_loop[verts_loop_tot] = BM_vert_create(bm, tvec, l->v, 0); if (use_boundary) { @@ -301,7 +301,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op) fac *= verts_relfac[BM_elem_index_get(l_pair[i]->v)]; } madd_v3_v3v3fl(tvec, l_pair[i]->v->co, tvec, fac); - verts_boundary[BM_elem_index_get(l_pair[i]->v)] = BM_vert_create(bm, tvec, l_pair[i]->v); + verts_boundary[BM_elem_index_get(l_pair[i]->v)] = BM_vert_create(bm, tvec, l_pair[i]->v, 0); } } } diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 62465ea9849..cb35616a1f7 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -164,7 +164,7 @@ static NewVert *mesh_vert(VMesh *vm, int i, int j, int k) static void create_mesh_bmvert(BMesh *bm, VMesh *vm, int i, int j, int k, BMVert *eg) { NewVert *nv = mesh_vert(vm, i, j, k); - nv->v = BM_vert_create(bm, nv->co, eg); + nv->v = BM_vert_create(bm, nv->co, eg, 0); } static void copy_mesh_vert(VMesh *vm, int ito, int jto, int kto, @@ -267,9 +267,9 @@ static BMFace *bev_create_ngon(BMesh *bm, BMVert **vert_arr, const int totv, BMF BLI_array_fixedstack_declare(ee, BM_DEFAULT_NGON_STACK_SIZE, totv, __func__); for (i = 0; i < totv; i++) { - ee[i] = BM_edge_create(bm, vert_arr[i], vert_arr[(i + 1) % totv], NULL, TRUE); + ee[i] = BM_edge_create(bm, vert_arr[i], vert_arr[(i + 1) % totv], NULL, BM_CREATE_NO_DOUBLE); } - f = BM_face_create_ngon(bm, vert_arr[0], vert_arr[1], ee, totv, FALSE); + f = BM_face_create_ngon(bm, vert_arr[0], vert_arr[1], ee, totv, 0); BLI_array_fixedstack_free(ee); } if (facerep && f) { @@ -1064,7 +1064,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv) } } while ((v = v->next) != vm->boundstart); mul_v3_fl(midco, 1.0f / nn); - bmv = BM_vert_create(bm, midco, NULL); + bmv = BM_vert_create(bm, midco, NULL, 0); v = vm->boundstart; do { i = v->index; diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 47add7afb56..9dc68848c69 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1965,7 +1965,7 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd) kfe->e = NULL; } - kfe->e = BM_edge_create(bm, kfe->v1->v, kfe->v2->v, NULL, TRUE); + kfe->e = BM_edge_create(bm, kfe->v1->v, kfe->v2->v, NULL, BM_CREATE_NO_DOUBLE); BMO_elem_flag_enable(bm, kfe->e, BOUNDARY); for (ref = kfe->faces.first; ref; ref = ref->next) { diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index a37835e11dc..a73d52a0a63 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -941,18 +941,18 @@ static void add_poly(SkinOutput *so, BLI_assert(v3 != v4); BLI_assert(v1 && v2 && v3); - edges[0] = BM_edge_create(so->bm, v1, v2, NULL, TRUE); - edges[1] = BM_edge_create(so->bm, v2, v3, NULL, TRUE); + edges[0] = BM_edge_create(so->bm, v1, v2, NULL, BM_CREATE_NO_DOUBLE); + edges[1] = BM_edge_create(so->bm, v2, v3, NULL, BM_CREATE_NO_DOUBLE); if (v4) { - edges[2] = BM_edge_create(so->bm, v3, v4, NULL, TRUE); - edges[3] = BM_edge_create(so->bm, v4, v1, NULL, TRUE); + edges[2] = BM_edge_create(so->bm, v3, v4, NULL, BM_CREATE_NO_DOUBLE); + edges[3] = BM_edge_create(so->bm, v4, v1, NULL, BM_CREATE_NO_DOUBLE); } else { - edges[2] = BM_edge_create(so->bm, v3, v1, NULL, TRUE); + edges[2] = BM_edge_create(so->bm, v3, v1, NULL, BM_CREATE_NO_DOUBLE); edges[3] = NULL; } - f = BM_face_create(so->bm, verts, edges, v4 ? 4 : 3, TRUE); + f = BM_face_create(so->bm, verts, edges, v4 ? 4 : 3, BM_CREATE_NO_DOUBLE); if (so->smd->flag & MOD_SKIN_SMOOTH_SHADING) BM_elem_flag_enable(f, BM_ELEM_SMOOTH); f->mat_nr = so->mat_nr; @@ -996,7 +996,7 @@ static void output_frames(BMesh *bm, f = &sn->frames[i]; for (j = 0; j < 4; j++) { if (!f->merge[j].frame) { - BMVert *v = f->verts[j] = BM_vert_create(bm, f->co[j], NULL); + BMVert *v = f->verts[j] = BM_vert_create(bm, f->co[j], NULL, 0); if (input_dvert) { MDeformVert *dv; @@ -1309,7 +1309,7 @@ static void skin_hole_detach_partially_attached_frame(BMesh *bm, Frame *frame) /* Detach everything */ for (i = 0; i < totattached; i++) { BMVert **av = &frame->verts[attached[i]]; - (*av) = BM_vert_create(bm, (*av)->co, *av); + (*av) = BM_vert_create(bm, (*av)->co, *av, 0); } } diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index f302f6ac38d..5db9962e690 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -728,7 +728,7 @@ static PyGetSetDef bpy_bmloop_getseters[] = { static PyGetSetDef bpy_bmvertseq_getseters[] = { {(char *)"layers", (getter)bpy_bmelemseq_layers_get, (setter)NULL, (char *)bpy_bmelemseq_layers_doc, (void *)BM_VERT}, - {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ + {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; static PyGetSetDef bpy_bmedgeseq_getseters[] = { {(char *)"layers", (getter)bpy_bmelemseq_layers_get, (setter)NULL, (char *)bpy_bmelemseq_layers_doc, (void *)BM_EDGE}, @@ -1746,7 +1746,7 @@ static PyObject *bpy_bmvertseq_new(BPy_BMElemSeq *self, PyObject *args) return NULL; } - v = BM_vert_create(bm, co, NULL); + v = BM_vert_create(bm, co, NULL, 0); if (v == NULL) { PyErr_SetString(PyExc_ValueError, @@ -1815,7 +1815,7 @@ static PyObject *bpy_bmedgeseq_new(BPy_BMElemSeq *self, PyObject *args) goto cleanup; } - e = BM_edge_create(bm, vert_array[0], vert_array[1], NULL, FALSE); + e = BM_edge_create(bm, vert_array[0], vert_array[1], NULL, 0); if (e == NULL) { PyErr_SetString(PyExc_ValueError, @@ -1901,10 +1901,10 @@ static PyObject *bpy_bmfaceseq_new(BPy_BMElemSeq *self, PyObject *args) /* ensure edges */ for (i = vert_seq_len - 1, i_next = 0; i_next < vert_seq_len; (i = i_next++)) { - edge_array[i] = BM_edge_create(bm, vert_array[i], vert_array[i_next], NULL, TRUE); + edge_array[i] = BM_edge_create(bm, vert_array[i], vert_array[i_next], NULL, BM_CREATE_NO_DOUBLE); } - f_new = BM_face_create(bm, vert_array, edge_array, vert_seq_len, FALSE); + f_new = BM_face_create(bm, vert_array, edge_array, vert_seq_len, 0); if (UNLIKELY(f_new == NULL)) { PyErr_SetString(PyExc_ValueError, -- cgit v1.2.3 From 7d62e6d94a1c658a1c009b1df4d0c0a44e18d679 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 29 Nov 2012 16:34:09 +0000 Subject: Fix navmesh after recent bmsh api changes. --- source/blender/editors/mesh/mesh_navmesh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c index f6f8eee0a69..83a1261e981 100644 --- a/source/blender/editors/mesh/mesh_navmesh.c +++ b/source/blender/editors/mesh/mesh_navmesh.c @@ -341,7 +341,7 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh, co[1] = bmin[1] + v[1] * ch; co[2] = bmin[2] + v[2] * cs; SWAP(float, co[1], co[2]); - BM_vert_create(em->bm, co, NULL); + BM_vert_create(em->bm, co, NULL, 0); } /* create custom data layer to save polygon idx */ @@ -372,7 +372,7 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh, for (j = nv; j < ndv; j++) { copy_v3_v3(co, &dverts[3 * (vbase + j)]); SWAP(float, co[1], co[2]); - BM_vert_create(em->bm, co, NULL); + BM_vert_create(em->bm, co, NULL, 0); } EDBM_index_arrays_init(em, 1, 0, 0); -- cgit v1.2.3 From ce3ea8942cc9d01deab18e1517ecd7629887ba44 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 29 Nov 2012 16:36:16 +0000 Subject: remove unneeded mesh->bmesh conversion code that copied BMLoop data in a separate loop (since there is no longer pre-allocated loop data on the new BMLoops). --- source/blender/bmesh/intern/bmesh_mesh_conv.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index 6617cc806c7..c23fd85458c 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -338,7 +338,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) j = 0; BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, j) { /* Save index of correspsonding MLoop */ - BM_elem_index_set(l, mpoly->loopstart + j); /* set_loop */ + CustomData_to_bmesh_block(&me->ldata, &bm->ldata, mpoly->loopstart + j, &l->head.data); } /* Copy Custom Data */ @@ -347,23 +347,6 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) bm->elem_index_dirty &= ~BM_FACE; /* added in order, clear dirty flag */ - { - BMIter fiter; - BMIter liter; - - /* Copy over loop CustomData. Doing this in a separate loop isn't necessary - * but is an optimization, to avoid copying a bunch of interpolated customdata - * for each BMLoop (from previous BMLoops using the same edge), always followed - * by freeing the interpolated data and overwriting it with data from the Mesh. */ - BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { - BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - int li = BM_elem_index_get(l); - CustomData_to_bmesh_block(&me->ldata, &bm->ldata, li, &l->head.data); - BM_elem_index_set(l, 0); /* set_loop */ - } - } - } - if (me->mselect && me->totselect != 0) { BMVert **vert_array = MEM_callocN(sizeof(BMVert *) * bm->totvert, -- cgit v1.2.3 From 5321669ef6935cb4863637d8068c2d265eef0a31 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 29 Nov 2012 19:04:33 +0000 Subject: Fix render from local view 3d viewport not using lamps in render. Fix missing GLSL updates for objects without materials. --- source/blender/editors/render/render_internal.c | 17 ++++++++++++++--- source/blender/editors/render/render_update.c | 11 +++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 7b67f63c646..9a49a1970a0 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -553,13 +553,20 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) rj->win = CTX_wm_window(C); rj->srl = srl; rj->camera_override = camera_override; - rj->lay = (v3d) ? v3d->lay : scene->lay; + rj->lay = scene->lay; rj->anim = is_animation; rj->write_still = is_write_still && !is_animation; rj->iuser.scene = scene; rj->iuser.ok = 1; rj->reports = op->reports; + if(v3d) { + rj->lay = v3d->lay; + + if(v3d->localvd) + rj->lay |= v3d->localvd->lay; + } + /* setup job */ if (RE_seq_render_active(scene, &scene->r)) name = "Sequence Render"; else name = "Render"; @@ -611,6 +618,8 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) /* contextual render, using current scene, view3d? */ void RENDER_OT_render(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Render"; ot->description = "Render active scene"; @@ -625,7 +634,9 @@ void RENDER_OT_render(wmOperatorType *ot) RNA_def_boolean(ot->srna, "animation", 0, "Animation", "Render files from the animation range of this scene"); RNA_def_boolean(ot->srna, "write_still", 0, "Write Image", "Save rendered the image to the output path (used only when animation is disabled)"); - RNA_def_string(ot->srna, "layer", "", RE_MAXNAME, "Render Layer", "Single render layer to re-render (used only when animation is disabled)"); - RNA_def_string(ot->srna, "scene", "", MAX_ID_NAME - 2, "Scene", "Scene to render, current scene if not specified"); + prop = RNA_def_string(ot->srna, "layer", "", RE_MAXNAME, "Render Layer", "Single render layer to re-render (used only when animation is disabled)"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_string(ot->srna, "scene", "", MAX_ID_NAME - 2, "Scene", "Scene to render, current scene if not specified"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index 3f438c5948e..e9fbb3a0885 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -65,6 +65,8 @@ #include "render_intern.h" // own include +extern Material defmaterial; + /***************************** Render Engines ********************************/ void ED_render_scene_update(Main *bmain, Scene *scene, int updated) @@ -266,6 +268,9 @@ static void lamp_changed(Main *bmain, Lamp *la) for (ma = bmain->mat.first; ma; ma = ma->id.next) if (ma->gpumaterial.first) GPU_material_free(ma); + + if (defmaterial.gpumaterial.first) + GPU_material_free(&defmaterial); } static void texture_changed(Main *bmain, Tex *tex) @@ -347,6 +352,9 @@ static void world_changed(Main *bmain, World *wo) for (ma = bmain->mat.first; ma; ma = ma->id.next) if (ma->gpumaterial.first) GPU_material_free(ma); + + if (defmaterial.gpumaterial.first) + GPU_material_free(&defmaterial); } static void image_changed(Main *bmain, Image *ima) @@ -375,6 +383,9 @@ static void scene_changed(Main *bmain, Scene *UNUSED(scene)) for (ma = bmain->mat.first; ma; ma = ma->id.next) if (ma->gpumaterial.first) GPU_material_free(ma); + + if (defmaterial.gpumaterial.first) + GPU_material_free(&defmaterial); } void ED_render_id_flush_update(Main *bmain, ID *id) -- cgit v1.2.3 From c3406db4f5e87402d43a5d2a5e0049b16479d2d5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 30 Nov 2012 04:25:58 +0000 Subject: fix for view-all operator not taking the view-angle into account. --- source/blender/editors/include/ED_view3d.h | 1 + source/blender/editors/space_view3d/view3d_edit.c | 2 ++ source/blender/editors/space_view3d/view3d_view.c | 9 ++++++++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index bd85e93f1af..27204d89bc5 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -219,6 +219,7 @@ void ED_view3d_clipping_enable(void); void ED_view3d_clipping_disable(void); float ED_view3d_pixel_size(struct RegionView3D *rv3d, const float co[3]); +float ED_view3d_dist_from_radius(struct View3D *v3d, const float radius); void drawcircball(int mode, const float cent[3], float rad, float tmat[][4]); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 0d8567b256d..a37ce64b7c8 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2224,6 +2224,8 @@ static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar, /* fix up zoom distance if needed */ if (rv3d->is_persp) { + /* offset the view based on the lens */ + size = ED_view3d_dist_from_radius(v3d, size / 2.0f); if (size <= v3d->near * 1.5f) { /* do not zoom closer than the near clipping plane */ size = v3d->near * 1.5f; diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 714898fed21..ea09aca900f 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1511,7 +1511,7 @@ static void UNUSED_FUNCTION(view3d_align_axis_to_vector)(View3D *v3d, RegionView } } -float ED_view3d_pixel_size(struct RegionView3D *rv3d, const float co[3]) +float ED_view3d_pixel_size(RegionView3D *rv3d, const float co[3]) { return (rv3d->persmat[3][3] + ( rv3d->persmat[0][3] * co[0] + @@ -1520,6 +1520,13 @@ float ED_view3d_pixel_size(struct RegionView3D *rv3d, const float co[3]) ) * rv3d->pixsize; } +/* use for perspective view only */ +float ED_view3d_dist_from_radius(View3D *v3d, const float radius) +{ + const float angle = (((float)M_PI) - focallength_to_fov(v3d->lens, DEFAULT_SENSOR_WIDTH)); + return radius * fabsf(1.0f / cosf(angle / 2.0f)); +} + /* view matrix properties utilities */ /* unused */ -- cgit v1.2.3 From 8c3df03c5f3dc3246dc73111c3946757ee3e54ef Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 30 Nov 2012 04:40:32 +0000 Subject: make previous commit work when the camera is locked to the view (in that case use the camera lens, not the viewport lens value). --- source/blender/editors/include/ED_view3d.h | 2 +- source/blender/editors/space_view3d/view3d_edit.c | 16 +++++++++++++++- source/blender/editors/space_view3d/view3d_view.c | 5 ++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 27204d89bc5..01a9b4cf74a 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -219,7 +219,7 @@ void ED_view3d_clipping_enable(void); void ED_view3d_clipping_disable(void); float ED_view3d_pixel_size(struct RegionView3D *rv3d, const float co[3]); -float ED_view3d_dist_from_radius(struct View3D *v3d, const float radius); +float ED_view3d_dist_from_radius(const float angle, const float radius); void drawcircball(int mode, const float cent[3], float rad, float tmat[][4]); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index a37ce64b7c8..5daa404c572 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2224,8 +2224,22 @@ static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar, /* fix up zoom distance if needed */ if (rv3d->is_persp) { + float lens, sensor_size; /* offset the view based on the lens */ - size = ED_view3d_dist_from_radius(v3d, size / 2.0f); + if (rv3d->persp == RV3D_CAMOB && ED_view3d_camera_lock_check(v3d, rv3d)) { + CameraParams params; + BKE_camera_params_init(¶ms); + BKE_camera_params_from_object(¶ms, v3d->camera); + + lens = params.lens; + sensor_size = BKE_camera_sensor_size(params.sensor_fit, params.sensor_x, params.sensor_y); + } + else { + lens = v3d->lens; + sensor_size = DEFAULT_SENSOR_WIDTH; + } + size = ED_view3d_dist_from_radius(focallength_to_fov(lens, sensor_size), size / 2.0f); + if (size <= v3d->near * 1.5f) { /* do not zoom closer than the near clipping plane */ size = v3d->near * 1.5f; diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index ea09aca900f..e79f24eea09 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1521,10 +1521,9 @@ float ED_view3d_pixel_size(RegionView3D *rv3d, const float co[3]) } /* use for perspective view only */ -float ED_view3d_dist_from_radius(View3D *v3d, const float radius) +float ED_view3d_dist_from_radius(const float angle, const float radius) { - const float angle = (((float)M_PI) - focallength_to_fov(v3d->lens, DEFAULT_SENSOR_WIDTH)); - return radius * fabsf(1.0f / cosf(angle / 2.0f)); + return radius * fabsf(1.0f / cosf((((float)M_PI) - angle) / 2.0f)); } /* view matrix properties utilities */ -- cgit v1.2.3 From 7a1dfa298a384b262aa879de8aad648275d6a1ff Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 30 Nov 2012 05:29:34 +0000 Subject: make setting local view take the view lens int account. --- source/blender/editors/space_view3d/view3d_edit.c | 6 ++-- source/blender/editors/space_view3d/view3d_view.c | 34 +++++++++++++---------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 5daa404c572..1c34ff39339 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2240,10 +2240,8 @@ static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar, } size = ED_view3d_dist_from_radius(focallength_to_fov(lens, sensor_size), size / 2.0f); - if (size <= v3d->near * 1.5f) { - /* do not zoom closer than the near clipping plane */ - size = v3d->near * 1.5f; - } + /* do not zoom closer than the near clipping plane */ + size = max_ff(size, v3d->near * 1.5f); } else { /* ortho */ if (size < 0.0001f) { diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index e79f24eea09..eb065de98da 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1028,7 +1028,8 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL { View3D *v3d = sa->spacedata.first; Base *base; - float size = 0.0, min[3], max[3], box[3]; + float min[3], max[3], box[3]; + float size = 0.0, size_persp; unsigned int locallay; int ok = FALSE; @@ -1068,7 +1069,12 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL box[1] = (max[1] - min[1]); box[2] = (max[2] - min[2]); size = MAX3(box[0], box[1], box[2]); - if (size <= 0.01f) size = 0.01f; + + /* do not zoom closer than the near clipping plane */ + size = max_ff(size, v3d->near * 1.5f); + + /* perspective size (we always switch out of camera view so no need to use its lens size) */ + size_persp = ED_view3d_dist_from_radius(focallength_to_fov(v3d->lens, DEFAULT_SENSOR_WIDTH), size / 2.0f); } if (ok == TRUE) { @@ -1085,14 +1091,20 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL rv3d->localvd = MEM_mallocN(sizeof(RegionView3D), "localview region"); memcpy(rv3d->localvd, rv3d, sizeof(RegionView3D)); - rv3d->ofs[0] = -(min[0] + max[0]) / 2.0f; - rv3d->ofs[1] = -(min[1] + max[1]) / 2.0f; - rv3d->ofs[2] = -(min[2] + max[2]) / 2.0f; + mid_v3_v3v3(v3d->cursor, min, max); + negate_v3_v3(rv3d->ofs, v3d->cursor); + + if (rv3d->persp == RV3D_CAMOB) { + rv3d->persp = RV3D_PERSP; + } - rv3d->dist = size; /* perspective should be a bit farther away to look nice */ - if (rv3d->persp == RV3D_ORTHO) - rv3d->dist *= 0.7f; + if (rv3d->persp != RV3D_ORTHO) { + rv3d->dist = size_persp; + } + else { + rv3d->dist = size * 0.7f; + } /* correction for window aspect ratio */ if (ar->winy > 2 && ar->winx > 2) { @@ -1100,12 +1112,6 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL if (asp < 1.0f) asp = 1.0f / asp; rv3d->dist *= asp; } - - if (rv3d->persp == RV3D_CAMOB) rv3d->persp = RV3D_PERSP; - - v3d->cursor[0] = -rv3d->ofs[0]; - v3d->cursor[1] = -rv3d->ofs[1]; - v3d->cursor[2] = -rv3d->ofs[2]; } } -- cgit v1.2.3 From 6bb45495d11e6547c847aee59dc86ca28adf472b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 30 Nov 2012 06:10:01 +0000 Subject: fix for r51636 - making the lens work in ortho mode made view-all and local-view operators give bad zoom levels. --- source/blender/blenkernel/intern/camera.c | 1 + source/blender/editors/include/ED_view3d.h | 4 +++- source/blender/editors/space_view3d/view3d_edit.c | 4 ++-- source/blender/editors/space_view3d/view3d_view.c | 17 +++++++++++------ 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index 9118baeae6f..57c88919021 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -267,6 +267,7 @@ void BKE_camera_params_from_view3d(CameraParams *params, View3D *v3d, RegionView params->clipsta = -params->clipend; params->is_ortho = TRUE; + /* make sure any changes to this match ED_view3d_radius_to_ortho_dist() */ params->ortho_scale = rv3d->dist * sensor_size / v3d->lens; params->zoom = 2.0f; } diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 01a9b4cf74a..269a932dcf5 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -219,7 +219,9 @@ void ED_view3d_clipping_enable(void); void ED_view3d_clipping_disable(void); float ED_view3d_pixel_size(struct RegionView3D *rv3d, const float co[3]); -float ED_view3d_dist_from_radius(const float angle, const float radius); + +float ED_view3d_radius_to_persp_dist(const float angle, const float radius); +float ED_view3d_radius_to_ortho_dist(const float lens, const float radius); void drawcircball(int mode, const float cent[3], float rad, float tmat[][4]); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 1c34ff39339..434d8ee338b 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2238,7 +2238,7 @@ static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar, lens = v3d->lens; sensor_size = DEFAULT_SENSOR_WIDTH; } - size = ED_view3d_dist_from_radius(focallength_to_fov(lens, sensor_size), size / 2.0f); + size = ED_view3d_radius_to_persp_dist(focallength_to_fov(lens, sensor_size), size / 2.0f); /* do not zoom closer than the near clipping plane */ size = max_ff(size, v3d->near * 1.5f); @@ -2250,7 +2250,7 @@ static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar, } else { /* adjust zoom so it looks nicer */ - size *= 0.7f; + size = ED_view3d_radius_to_ortho_dist(v3d->lens, size / 2.0f); } } } diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index eb065de98da..15928204920 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1029,7 +1029,7 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL View3D *v3d = sa->spacedata.first; Base *base; float min[3], max[3], box[3]; - float size = 0.0, size_persp; + float size = 0.0f, size_persp = 0.0f, size_ortho = 0.0f; unsigned int locallay; int ok = FALSE; @@ -1074,7 +1074,8 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL size = max_ff(size, v3d->near * 1.5f); /* perspective size (we always switch out of camera view so no need to use its lens size) */ - size_persp = ED_view3d_dist_from_radius(focallength_to_fov(v3d->lens, DEFAULT_SENSOR_WIDTH), size / 2.0f); + size_persp = ED_view3d_radius_to_persp_dist(focallength_to_fov(v3d->lens, DEFAULT_SENSOR_WIDTH), size / 2.0f); + size_ortho = ED_view3d_radius_to_ortho_dist(v3d->lens, size / 2.0f); } if (ok == TRUE) { @@ -1103,7 +1104,7 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL rv3d->dist = size_persp; } else { - rv3d->dist = size * 0.7f; + rv3d->dist = size_ortho; } /* correction for window aspect ratio */ @@ -1526,10 +1527,14 @@ float ED_view3d_pixel_size(RegionView3D *rv3d, const float co[3]) ) * rv3d->pixsize; } -/* use for perspective view only */ -float ED_view3d_dist_from_radius(const float angle, const float radius) +float ED_view3d_radius_to_persp_dist(const float angle, const float radius) { - return radius * fabsf(1.0f / cosf((((float)M_PI) - angle) / 2.0f)); + return (radius / 2.0f) * fabsf(1.0f / cosf((((float)M_PI) - angle) / 2.0f)); +} + +float ED_view3d_radius_to_ortho_dist(const float lens, const float radius) +{ + return radius / (DEFAULT_SENSOR_WIDTH / lens); } /* view matrix properties utilities */ -- cgit v1.2.3 From e7f594b0df56c99b19ce2eda50d7ca8872ac21e6 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 30 Nov 2012 06:10:16 +0000 Subject: Fix #33347: cycles OSL crash connecting string to vector socket. --- .../kernel/shaders/node_convert_from_color.osl | 1 + .../kernel/shaders/node_convert_from_float.osl | 1 + .../kernel/shaders/node_convert_from_int.osl | 1 + .../kernel/shaders/node_convert_from_normal.osl | 1 + .../kernel/shaders/node_convert_from_point.osl | 1 + .../kernel/shaders/node_convert_from_string.osl | 31 ++++++++++++++++++++++ .../kernel/shaders/node_convert_from_vector.osl | 1 + intern/cycles/render/nodes.cpp | 4 +++ 8 files changed, 41 insertions(+) create mode 100644 intern/cycles/kernel/shaders/node_convert_from_string.osl diff --git a/intern/cycles/kernel/shaders/node_convert_from_color.osl b/intern/cycles/kernel/shaders/node_convert_from_color.osl index 2884c772414..e4982975c20 100644 --- a/intern/cycles/kernel/shaders/node_convert_from_color.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_color.osl @@ -20,6 +20,7 @@ shader node_convert_from_color( color Color = color(0.0, 0.0, 0.0), + output string String = "", output float Val = 0.0, output int ValInt = 0, output vector Vector = vector(0.0, 0.0, 0.0), diff --git a/intern/cycles/kernel/shaders/node_convert_from_float.osl b/intern/cycles/kernel/shaders/node_convert_from_float.osl index 4466fbae3a6..a20b491c91d 100644 --- a/intern/cycles/kernel/shaders/node_convert_from_float.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_float.osl @@ -20,6 +20,7 @@ shader node_convert_from_float( float Val = 0.0, + output string String = "", output int ValInt = 0, output color Color = color(0.0, 0.0, 0.0), output vector Vector = vector(0.0, 0.0, 0.0), diff --git a/intern/cycles/kernel/shaders/node_convert_from_int.osl b/intern/cycles/kernel/shaders/node_convert_from_int.osl index 060d4184fa6..911b4928db8 100644 --- a/intern/cycles/kernel/shaders/node_convert_from_int.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_int.osl @@ -20,6 +20,7 @@ shader node_convert_from_int( int ValInt = 0, + output string String = "", output float Val = 0.0, output color Color = color(0.0, 0.0, 0.0), output vector Vector = vector(0.0, 0.0, 0.0), diff --git a/intern/cycles/kernel/shaders/node_convert_from_normal.osl b/intern/cycles/kernel/shaders/node_convert_from_normal.osl index 32ef430d93b..1add7400a22 100644 --- a/intern/cycles/kernel/shaders/node_convert_from_normal.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_normal.osl @@ -20,6 +20,7 @@ shader node_convert_from_normal( normal Normal = normal(0.0, 0.0, 0.0), + output string String = "", output float Val = 0.0, output int ValInt = 0, output vector Vector = vector(0.0, 0.0, 0.0), diff --git a/intern/cycles/kernel/shaders/node_convert_from_point.osl b/intern/cycles/kernel/shaders/node_convert_from_point.osl index a9435c8abf4..8a315828c55 100644 --- a/intern/cycles/kernel/shaders/node_convert_from_point.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_point.osl @@ -20,6 +20,7 @@ shader node_convert_from_point( point Point = point(0.0, 0.0, 0.0), + output string String = "", output float Val = 0.0, output int ValInt = 0, output vector Vector = vector(0.0, 0.0, 0.0), diff --git a/intern/cycles/kernel/shaders/node_convert_from_string.osl b/intern/cycles/kernel/shaders/node_convert_from_string.osl new file mode 100644 index 00000000000..f40535ac7a3 --- /dev/null +++ b/intern/cycles/kernel/shaders/node_convert_from_string.osl @@ -0,0 +1,31 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "stdosl.h" + +shader node_convert_from_string( + string String = "", + output color Color = color(0.0, 0.0, 0.0), + output float Val = 0.0, + output int ValInt = 0, + output vector Vector = vector(0.0, 0.0, 0.0), + output point Point = point(0.0, 0.0, 0.0), + output normal Normal = normal(0.0, 0.0, 0.0)) +{ +} + diff --git a/intern/cycles/kernel/shaders/node_convert_from_vector.osl b/intern/cycles/kernel/shaders/node_convert_from_vector.osl index 4516f92c753..ae9f97414d5 100644 --- a/intern/cycles/kernel/shaders/node_convert_from_vector.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_vector.osl @@ -20,6 +20,7 @@ shader node_convert_from_vector( vector Vector = vector(0.0, 0.0, 0.0), + output string String = "", output float Val = 0.0, output int ValInt = 0, output color Color = color(0.0, 0.0, 0.0), diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 12bbc019644..48fe63670c7 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1124,6 +1124,8 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_) add_input("Point", SHADER_SOCKET_POINT); else if(from == SHADER_SOCKET_NORMAL) add_input("Normal", SHADER_SOCKET_NORMAL); + else if(from == SHADER_SOCKET_STRING) + add_input("String", SHADER_SOCKET_STRING); else assert(0); @@ -1139,6 +1141,8 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_) add_output("Point", SHADER_SOCKET_POINT); else if(to == SHADER_SOCKET_NORMAL) add_output("Normal", SHADER_SOCKET_NORMAL); + else if(to == SHADER_SOCKET_STRING) + add_output("String", SHADER_SOCKET_STRING); else assert(0); } -- cgit v1.2.3 From 1246ef714e13d7e72d42aed46c260f698160dfd8 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 30 Nov 2012 06:10:25 +0000 Subject: Fix #33351: cycles OSL not loading grayscale images as RGB correctly. --- intern/cycles/render/osl.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index c1d2eade5e5..2ec7e3d3775 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -138,6 +138,7 @@ void OSLShaderManager::texture_system_init() ts = TextureSystem::create(true); ts->attribute("automip", 1); ts->attribute("autotile", 64); + ts->attribute("gray_to_rgb", 1); /* effectively unlimited for now, until we support proper mipmap lookups */ ts->attribute("max_memory_MB", 16384); -- cgit v1.2.3 From ef08e311343495448498cc4d6e03b4d024cf203c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 30 Nov 2012 06:39:24 +0000 Subject: fix for another glitch caused by r51636, setting the camera view with quad-view enabled would zoom all non camera views. Theres no need to draw other views so skip that. --- source/blender/editors/space_view3d/view3d_view.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 15928204920..c241f77806e 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -323,8 +323,14 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent if (rv3d->viewlock & RV3D_BOXVIEW) view3d_boxview_copy(CTX_wm_area(C), CTX_wm_region(C)); - + + /* note: this doesn't work right because the v3d->lens is now used in ortho mode r51636, + * when switching camera in quad-view the other ortho views would zoom & reset. */ +#if 0 WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); +#else + ED_region_tag_redraw(CTX_wm_region(C)); +#endif return OPERATOR_FINISHED; } -- cgit v1.2.3 From ad2b41bc4bae3b0406ce6fcee69be581b0e96105 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 30 Nov 2012 06:55:36 +0000 Subject: add margin to view fitting view-all/local-view (wasn't obvious with the models I was testing with). --- release/scripts/templates/script_stub.py | 6 +++--- source/blender/editors/include/ED_view3d.h | 6 +----- source/blender/editors/space_view3d/view3d_edit.c | 4 ++-- source/blender/editors/space_view3d/view3d_view.c | 4 ++-- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/release/scripts/templates/script_stub.py b/release/scripts/templates/script_stub.py index 80eca9663df..44c7b802e2c 100644 --- a/release/scripts/templates/script_stub.py +++ b/release/scripts/templates/script_stub.py @@ -9,6 +9,6 @@ filename = "my_script.py" filepath = os.path.join(os.path.dirname(bpy.data.filepath), filename) global_namespace = {"__file__": filepath, "__name__": "__main__"} -file_handle = open(filepath, 'rb') -exec(compile(file_handle.read(), filepath, 'exec'), global_namespace) -file_handle.close() +file = open(filepath, 'rb') +exec(compile(file.read(), filepath, 'exec'), global_namespace) +file.close() diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 269a932dcf5..d5c9b9ef01a 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -100,11 +100,6 @@ void ED_view3d_depth_tag_update(struct RegionView3D *rv3d); /* Projection */ #define IS_CLIPPED 12000 -/* TODO, these functions work quite differently, we should make them behave in a uniform way - * otherwise we can't be sure bugs are not added when we need to move from short->float types for eg - * - Campbell */ - - /* return values for ED_view3d_project_...() */ typedef enum { V3D_PROJ_RET_OK = 0, @@ -298,6 +293,7 @@ struct BGpic *ED_view3D_background_image_new(struct View3D *v3d); void ED_view3D_background_image_remove(struct View3D *v3d, struct BGpic *bgpic); void ED_view3D_background_image_clear(struct View3D *v3d); +#define VIEW3D_MARGIN 1.4f float ED_view3d_offset_distance(float mat[4][4], float ofs[3]); float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 434d8ee338b..d45013c40d9 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2238,7 +2238,7 @@ static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar, lens = v3d->lens; sensor_size = DEFAULT_SENSOR_WIDTH; } - size = ED_view3d_radius_to_persp_dist(focallength_to_fov(lens, sensor_size), size / 2.0f); + size = ED_view3d_radius_to_persp_dist(focallength_to_fov(lens, sensor_size), size / 2.0f) * VIEW3D_MARGIN; /* do not zoom closer than the near clipping plane */ size = max_ff(size, v3d->near * 1.5f); @@ -2250,7 +2250,7 @@ static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar, } else { /* adjust zoom so it looks nicer */ - size = ED_view3d_radius_to_ortho_dist(v3d->lens, size / 2.0f); + size = ED_view3d_radius_to_ortho_dist(v3d->lens, size / 2.0f) * VIEW3D_MARGIN; } } } diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index c241f77806e..ef15c1e734e 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1080,8 +1080,8 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL size = max_ff(size, v3d->near * 1.5f); /* perspective size (we always switch out of camera view so no need to use its lens size) */ - size_persp = ED_view3d_radius_to_persp_dist(focallength_to_fov(v3d->lens, DEFAULT_SENSOR_WIDTH), size / 2.0f); - size_ortho = ED_view3d_radius_to_ortho_dist(v3d->lens, size / 2.0f); + size_persp = ED_view3d_radius_to_persp_dist(focallength_to_fov(v3d->lens, DEFAULT_SENSOR_WIDTH), size / 2.0f) * VIEW3D_MARGIN; + size_ortho = ED_view3d_radius_to_ortho_dist(v3d->lens, size / 2.0f) * VIEW3D_MARGIN; } if (ok == TRUE) { -- cgit v1.2.3 From ceedd5bd35273c27225f84cde2948e5b774e92fe Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 30 Nov 2012 07:27:17 +0000 Subject: Fix cycles CUDA sm 1.3 build with 32 bit compiler, tweaked voronoi and brick code so that it can be uninlined. --- .../buildbot/config/user-config-glibc211-i686.py | 3 +- .../buildbot/config/user-config-glibc27-i686.py | 3 +- intern/cycles/kernel/kernel_types.h | 1 + intern/cycles/kernel/svm/svm.h | 4 +++ intern/cycles/kernel/svm/svm_brick.h | 21 ++++++------ intern/cycles/kernel/svm/svm_texture.h | 37 ++++++++-------------- intern/cycles/kernel/svm/svm_voronoi.h | 9 ++---- 7 files changed, 35 insertions(+), 43 deletions(-) diff --git a/build_files/buildbot/config/user-config-glibc211-i686.py b/build_files/buildbot/config/user-config-glibc211-i686.py index fa9122f732e..e665657d91e 100644 --- a/build_files/buildbot/config/user-config-glibc211-i686.py +++ b/build_files/buildbot/config/user-config-glibc211-i686.py @@ -110,8 +110,7 @@ BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a' # Cycles WITH_BF_CYCLES = True WITH_BF_CYCLES_CUDA_BINARIES = True -#BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30'] -BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30'] +BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30'] WITH_BF_OIIO = True WITH_BF_STATICOIIO = True diff --git a/build_files/buildbot/config/user-config-glibc27-i686.py b/build_files/buildbot/config/user-config-glibc27-i686.py index f359c09c887..b36196fd835 100644 --- a/build_files/buildbot/config/user-config-glibc27-i686.py +++ b/build_files/buildbot/config/user-config-glibc27-i686.py @@ -97,8 +97,7 @@ WITH_BF_JACK = True # Cycles WITH_BF_CYCLES = True WITH_BF_CYCLES_CUDA_BINARIES = True -#BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30'] -BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30'] +BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30'] WITH_BF_OIIO = True WITH_BF_STATICOIIO = True diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index a7bf6b28e7e..f519fd989fa 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -102,6 +102,7 @@ CCL_NAMESPACE_BEGIN #define __IMAGE_TEXTURES__ #define __EXTRA_NODES__ #define __HOLDOUT__ +#define __NORMAL_MAP__ #endif #ifdef __KERNEL_ADV_SHADING__ diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 886fce63fd4..9c79886fdca 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -401,9 +401,13 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT case NODE_LIGHT_FALLOFF: svm_node_light_falloff(sd, stack, node); break; +#endif +#ifdef __ANISOTROPIC__ case NODE_TANGENT: svm_node_tangent(kg, sd, stack, node); break; +#endif +#ifdef __NORMAL_MAP__ case NODE_NORMAL_MAP: svm_node_normal_map(kg, sd, stack, node); break; diff --git a/intern/cycles/kernel/svm/svm_brick.h b/intern/cycles/kernel/svm/svm_brick.h index 7e38ac84bf1..49466c07a97 100644 --- a/intern/cycles/kernel/svm/svm_brick.h +++ b/intern/cycles/kernel/svm/svm_brick.h @@ -28,9 +28,9 @@ __device_noinline float brick_noise(int n) /* fast integer noise */ return 0.5f * ((float)nn / 1073741824.0f); } -__device_noinline float svm_brick(float3 p, float scale, float mortar_size, float bias, +__device_noinline float2 svm_brick(float3 p, float scale, float mortar_size, float bias, float brick_width, float row_height, float offset_amount, int offset_frequency, - float squash_amount, int squash_frequency, float *tint) + float squash_amount, int squash_frequency) { p *= scale; @@ -50,11 +50,12 @@ __device_noinline float svm_brick(float3 p, float scale, float mortar_size, floa x = (p.x+offset) - brick_width*bricknum; y = p.y - row_height*rownum; - *tint = clamp((brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias), 0.0f, 1.0f); + return make_float2( + clamp((brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias), 0.0f, 1.0f), - return (x < mortar_size || y < mortar_size || + (x < mortar_size || y < mortar_size || x > (brick_width - mortar_size) || - y > (row_height - mortar_size)) ? 1.0f : 0.0f; + y > (row_height - mortar_size)) ? 1.0f : 0.0f); } __device void svm_node_tex_brick(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) @@ -70,8 +71,6 @@ __device void svm_node_tex_brick(KernelGlobals *kg, ShaderData *sd, float *stack /* RNA properties */ uint offset_frequency, squash_frequency; - float tint = 0.0f; - decode_node_uchar4(node.y, &co_offset, &color1_offset, &color2_offset, &mortar_offset); decode_node_uchar4(node.z, &scale_offset, &mortar_size_offset, &bias_offset, &brick_width_offset); decode_node_uchar4(node.w, &row_height_offset, &color_offset, &fac_offset, NULL); @@ -92,9 +91,11 @@ __device void svm_node_tex_brick(KernelGlobals *kg, ShaderData *sd, float *stack float offset_amount = __int_as_float(node3.z); float squash_amount = __int_as_float(node3.w); - float f = svm_brick(co, scale, mortar_size, bias, brick_width, row_height, - offset_amount, offset_frequency, squash_amount, squash_frequency, - &tint); + float2 f2 = svm_brick(co, scale, mortar_size, bias, brick_width, row_height, + offset_amount, offset_frequency, squash_amount, squash_frequency); + + float tint = f2.x; + float f = f2.y; if(f != 1.0f) { float facm = 1.0f - tint; diff --git a/intern/cycles/kernel/svm/svm_texture.h b/intern/cycles/kernel/svm/svm_texture.h index 6c22d98e0df..a4f6691435c 100644 --- a/intern/cycles/kernel/svm/svm_texture.h +++ b/intern/cycles/kernel/svm/svm_texture.h @@ -42,8 +42,12 @@ __device float voronoi_distance(NodeDistanceMetric distance_metric, float3 d, fl /* Voronoi / Worley like */ -__device_noinline void voronoi(float3 p, NodeDistanceMetric distance_metric, float e, float da[4], float3 pa[4]) +__device_noinline float4 voronoi_Fn(float3 p, float e, int n1, int n2) { + float da[4]; + float3 pa[4]; + NodeDistanceMetric distance_metric = NODE_VORONOI_DISTANCE_SQUARED; + /* returns distances in da and point coords in pa */ int xx, yy, zz, xi, yi, zi; @@ -105,33 +109,20 @@ __device_noinline void voronoi(float3 p, NodeDistanceMetric distance_metric, flo } } } -} - -__device float voronoi_Fn(float3 p, int n) -{ - float da[4]; - float3 pa[4]; - - voronoi(p, NODE_VORONOI_DISTANCE_SQUARED, 0, da, pa); - - return da[n]; -} -__device float voronoi_FnFn(float3 p, int n1, int n2) -{ - float da[4]; - float3 pa[4]; + float4 result = make_float4(pa[n1].x, pa[n1].y, pa[n1].z, da[n1]); - voronoi(p, NODE_VORONOI_DISTANCE_SQUARED, 0, da, pa); + if(n2 != -1) + result = make_float4(pa[n2].x, pa[n2].y, pa[n2].z, da[n2]) - result; - return da[n2] - da[n1]; + return result; } -__device float voronoi_F1(float3 p) { return voronoi_Fn(p, 0); } -__device float voronoi_F2(float3 p) { return voronoi_Fn(p, 1); } -__device float voronoi_F3(float3 p) { return voronoi_Fn(p, 2); } -__device float voronoi_F4(float3 p) { return voronoi_Fn(p, 3); } -__device float voronoi_F1F2(float3 p) { return voronoi_FnFn(p, 0, 1); } +__device float voronoi_F1(float3 p) { return voronoi_Fn(p, 0.0f, 0, -1).w; } +__device float voronoi_F2(float3 p) { return voronoi_Fn(p, 0.0f, 1, -1).w; } +__device float voronoi_F3(float3 p) { return voronoi_Fn(p, 0.0f, 2, -1).w; } +__device float voronoi_F4(float3 p) { return voronoi_Fn(p, 0.0f, 3, -1).w; } +__device float voronoi_F1F2(float3 p) { return voronoi_Fn(p, 0.0f, 0, 1).w; } __device float voronoi_Cr(float3 p) { diff --git a/intern/cycles/kernel/svm/svm_voronoi.h b/intern/cycles/kernel/svm/svm_voronoi.h index 7e7bd970320..55110d06f22 100644 --- a/intern/cycles/kernel/svm/svm_voronoi.h +++ b/intern/cycles/kernel/svm/svm_voronoi.h @@ -23,21 +23,18 @@ CCL_NAMESPACE_BEGIN __device_noinline float4 svm_voronoi(NodeVoronoiColoring coloring, float scale, float3 p) { /* compute distance and point coordinate of 4 nearest neighbours */ - float da[4]; - float3 pa[4]; - - voronoi(p*scale, NODE_VORONOI_DISTANCE_SQUARED, 1.0f, da, pa); + float4 dpa0 = voronoi_Fn(p*scale, 1.0f, 0, -1); /* output */ float fac; float3 color; if(coloring == NODE_VORONOI_INTENSITY) { - fac = fabsf(da[0]); + fac = fabsf(dpa0.w); color = make_float3(fac, fac, fac); } else { - color = cellnoise_color(pa[0]); + color = cellnoise_color(float4_to_float3(dpa0)); fac = average(color); } -- cgit v1.2.3 From 323e86694efe2fe4a2a8b570977d59c735942f90 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 30 Nov 2012 09:12:10 +0000 Subject: Compositor should never add notifiers by himself, notifiers should be added from main thread using job update callback. Added new execution-time callback to bNodeTree which marks job to be updated. The code here could be a bit not so obvious because in some cases job update callback need to merge local tree, but it's only needed for old compositor system which is gonna to be removed soon, so decided not to bother with cleanup now. Removing old compositor system will also allow to drop stats_draw callback from bNodeTree. This should fix following bugs: --- .../compositor/intern/COM_ExecutionGroup.cpp | 2 +- .../blender/compositor/intern/COM_NodeOperation.h | 5 +++- .../operations/COM_ViewerBaseOperation.cpp | 2 +- source/blender/editors/space_node/node_edit.c | 29 ++++++++++++++++++---- source/blender/makesdna/DNA_node_types.h | 3 ++- 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp index 0553aebbba6..7095ccd57b7 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp @@ -352,7 +352,7 @@ void ExecutionGroup::execute(ExecutionSystem *graph) startEvaluated = true; numberEvaluated++; - WM_main_add_notifier(NC_WINDOW | ND_DRAW, NULL); + bTree->update_draw(bTree->udh); } else if (state == COM_ES_SCHEDULED) { finished = false; diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h index 42d90eca38f..b0cc24fc487 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.h +++ b/source/blender/compositor/intern/COM_NodeOperation.h @@ -77,7 +77,7 @@ private: ThreadMutex m_mutex; /** - * @brief reference to the editing bNodeTree only used for break callback + * @brief reference to the editing bNodeTree, used for break and update callback */ const bNodeTree *m_btree; @@ -247,6 +247,9 @@ public: return this->m_btree->test_break(this->m_btree->tbh); } + inline void updateDraw() { + this->m_btree->update_draw(this->m_btree->udh); + } protected: NodeOperation(); diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp index cc313512316..d5f2c283c72 100644 --- a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp @@ -103,7 +103,7 @@ void ViewerBaseOperation:: updateImage(rcti *rect) this->m_viewSettings, this->m_displaySettings, rect->xmin, rect->ymin, rect->xmax, rect->ymax, FALSE); - WM_main_add_notifier(NC_WINDOW | ND_DRAW, NULL); + this->updateDraw(); } void ViewerBaseOperation::deinitExecution() diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index fd6d9ba8023..f757345bdcb 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -86,6 +86,7 @@ typedef struct CompoJob { short *stop; short *do_update; float *progress; + short need_sync; } CompoJob; /* called by compo, only to check job 'stop' value */ @@ -102,8 +103,17 @@ static int compo_breakjob(void *cjv) ); } +/* called by compo, wmJob sends notifier, old compositor system only */ +static void compo_statsdrawjob(void *cjv, char *UNUSED(str)) +{ + CompoJob *cj = cjv; + + *(cj->do_update) = TRUE; + cj->need_sync = TRUE; +} + /* called by compo, wmJob sends notifier */ -static void compo_redrawjob(void *cjv, char *UNUSED(str)) +static void compo_redrawjob(void *cjv) { CompoJob *cj = cjv; @@ -133,8 +143,15 @@ static void compo_initjob(void *cjv) static void compo_updatejob(void *cjv) { CompoJob *cj = cjv; - - ntreeLocalSync(cj->localtree, cj->ntree); + + if (cj->need_sync) { + /* was used by old compositor system only */ + ntreeLocalSync(cj->localtree, cj->ntree); + + cj->need_sync = FALSE; + } + + WM_main_add_notifier(NC_WINDOW | ND_DRAW, NULL); } static void compo_progressjob(void *cjv, float progress) @@ -161,11 +178,13 @@ static void compo_startjob(void *cjv, short *stop, short *do_update, float *prog ntree->test_break = compo_breakjob; ntree->tbh = cj; - ntree->stats_draw = compo_redrawjob; + ntree->stats_draw = compo_statsdrawjob; ntree->sdh = cj; ntree->progress = compo_progressjob; ntree->prh = cj; - + ntree->update_draw = compo_redrawjob; + ntree->udh = cj; + // XXX BIF_store_spare(); ntreeCompositExecTree(ntree, &cj->scene->r, 0, 1, &scene->view_settings, &scene->display_settings); /* 1 is do_previews */ diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 1684cf28b3c..a05ff66e683 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -294,7 +294,8 @@ typedef struct bNodeTree { void (*progress)(void *, float progress); void (*stats_draw)(void *, char *str); int (*test_break)(void *); - void *tbh, *prh, *sdh; + void (*update_draw)(void *); + void *tbh, *prh, *sdh, *udh; } bNodeTree; -- cgit v1.2.3 From d2a741048a3eeda6009eb85347aef0169fd8be1b Mon Sep 17 00:00:00 2001 From: Miika Hamalainen Date: Fri, 30 Nov 2012 11:01:14 +0000 Subject: Fix #33353: Smoke color problems with adaptive domain High resolution cache didn't always read all written data fields which caused colors to get messed up. --- source/blender/blenkernel/intern/pointcache.c | 3 ++- source/blender/blenkernel/intern/smoke.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 3f2eb32f61c..965a1e2b4a6 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -686,7 +686,7 @@ static int ptcache_smoke_read(PTCacheFile *pf, void *smoke_v) /* reallocate fluid if needed*/ if (reallocate) { - sds->active_fields = active_fields; + sds->active_fields = active_fields | cache_fields; smoke_reallocate_fluid(sds, ch_dx, ch_res, 1); sds->dx = ch_dx; VECCOPY(sds->res, ch_res); @@ -755,6 +755,7 @@ static int ptcache_smoke_read(PTCacheFile *pf, void *smoke_v) if (cache_fields & SM_ACTIVE_FIRE) { ptcache_file_compressed_read(pf, (unsigned char *)flame, out_len_big); ptcache_file_compressed_read(pf, (unsigned char *)fuel, out_len_big); + ptcache_file_compressed_read(pf, (unsigned char *)react, out_len_big); } if (cache_fields & SM_ACTIVE_COLORS) { ptcache_file_compressed_read(pf, (unsigned char *)r, out_len_big); diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index d96bece2b11..53dfbdcfb85 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -165,7 +165,7 @@ void flame_get_spectrum(unsigned char *UNUSED(spec), int UNUSED(width), float UN void smoke_reallocate_fluid(SmokeDomainSettings *sds, float dx, int res[3], int free_old) { int use_heat = (sds->active_fields & SM_ACTIVE_HEAT); - int use_fire = (sds->active_fields & (SM_ACTIVE_HEAT | SM_ACTIVE_FIRE)); + int use_fire = (sds->active_fields & SM_ACTIVE_FIRE); int use_colors = (sds->active_fields & SM_ACTIVE_COLORS); if (free_old && sds->fluid) -- cgit v1.2.3 From 1db677a51cfb13a7f6df81a2799e2bb506145d3b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 30 Nov 2012 11:26:57 +0000 Subject: Final render wouldn't set compositor's update_draw callback, so added NULL check Seems no extra notifiers should be added here. --- source/blender/compositor/intern/COM_ExecutionGroup.cpp | 3 ++- source/blender/compositor/intern/COM_NodeOperation.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp index 7095ccd57b7..ffc36281874 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp @@ -352,7 +352,8 @@ void ExecutionGroup::execute(ExecutionSystem *graph) startEvaluated = true; numberEvaluated++; - bTree->update_draw(bTree->udh); + if (bTree->update_draw) + bTree->update_draw(bTree->udh); } else if (state == COM_ES_SCHEDULED) { finished = false; diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h index b0cc24fc487..f856d8e6a11 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.h +++ b/source/blender/compositor/intern/COM_NodeOperation.h @@ -248,7 +248,8 @@ public: } inline void updateDraw() { - this->m_btree->update_draw(this->m_btree->udh); + if (this->m_btree->update_draw) + this->m_btree->update_draw(this->m_btree->udh); } protected: NodeOperation(); -- cgit v1.2.3 From 4f8f5746a8f3a72d54dab44a2b30d2d144891b77 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 30 Nov 2012 12:48:30 +0000 Subject: Normalize node: clamp infinities to 0/1 (depending on sign) The same behavior was in old compositor system and it makes more sense when you're normalizing Z buffer. --- source/blender/compositor/operations/COM_NormalizeOperation.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.cpp b/source/blender/compositor/operations/COM_NormalizeOperation.cpp index 5f7ac6bb9ca..f81b50e6836 100644 --- a/source/blender/compositor/operations/COM_NormalizeOperation.cpp +++ b/source/blender/compositor/operations/COM_NormalizeOperation.cpp @@ -43,6 +43,12 @@ void NormalizeOperation::executePixel(float output[4], int x, int y, void *data) this->m_imageReader->read(output, x, y, NULL); output[0] = (output[0] - minmult->x) * minmult->y; + + /* clamp infinities */ + if (output[0] > 1.0f) + output[0] = 1.0f; + else if (output[0] < 0.0f) + output[0] = 0.0f; } void NormalizeOperation::deinitExecution() -- cgit v1.2.3 From 7fa7ce297edee80258938c5c82837dcd8ab8377a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 30 Nov 2012 13:17:19 +0000 Subject: Map Range: added the same infinity clamping for Z buffer as normalize node. Think should be pretty much harmless since if this node was used for buffers with infinities it already showed artifacts. Now it should be more useful for mapping Z buffers. --- .../compositor/operations/COM_MapRangeOperation.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/source/blender/compositor/operations/COM_MapRangeOperation.cpp b/source/blender/compositor/operations/COM_MapRangeOperation.cpp index a18f418e48e..1fe74ade0fc 100644 --- a/source/blender/compositor/operations/COM_MapRangeOperation.cpp +++ b/source/blender/compositor/operations/COM_MapRangeOperation.cpp @@ -43,6 +43,9 @@ void MapRangeOperation::initExecution() this->m_destMaxOperation = this->getInputSocketReader(4); } +/* The code below assumes all data is inside range +- this, and that input buffer is single channel */ +#define BLENDER_ZMAX 10000.0f + void MapRangeOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) { float inputs[8]; /* includes the 5 inputs + 3 pads */ @@ -61,9 +64,15 @@ void MapRangeOperation::executePixel(float output[4], float x, float y, PixelSam source_max = inputs[2]; dest_min = inputs[3]; dest_max = inputs[4]; - - value = (value - source_min) / (source_max - source_min); - value = dest_min + value * (dest_max - dest_min); + + if (value >= -BLENDER_ZMAX && value <= BLENDER_ZMAX) { + value = (value - source_min) / (source_max - source_min); + value = dest_min + value * (dest_max - dest_min); + } + else if (value > BLENDER_ZMAX) + value = dest_max; + else + value = dest_min; if (this->m_useClamp) { if (dest_max > dest_min) { -- cgit v1.2.3 From a02e51febabfd6469a6316c5e51d2aea56ee75da Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 30 Nov 2012 13:42:52 +0000 Subject: Fix #33357: Strip modificator Bright/Contrast doesn't work correct for byte images --- source/blender/blenkernel/intern/seqmodifier.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c index 609724e802f..5b2e9f2bf23 100644 --- a/source/blender/blenkernel/intern/seqmodifier.c +++ b/source/blender/blenkernel/intern/seqmodifier.c @@ -427,17 +427,17 @@ static void brightcontrast_apply_threaded(int width, int height, unsigned char * unsigned char *pixel = rect + pixel_index; for (c = 0; c < 3; c++) { - i = pixel[c]; + i = (float) pixel[c] / 255.0f; v = a * i + b; if (mask_rect) { unsigned char *m = mask_rect + pixel_index; float t = (float) m[c] / 255.0f; - pixel[c] = pixel[c] * (1.0f - t) + v * t; + v = (float) pixel[c] * (1.0f - t) + v * t; } - else - pixel[c] = v; + + pixel[c] = FTOCHAR(v); } } else if (rect_float) { -- cgit v1.2.3 From ca64979236919ba3cb3813dc61519c7dc368b5c5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 30 Nov 2012 14:27:25 +0000 Subject: fix own mistake in recent commit - entering editmode with a shape key crashed. --- source/blender/bmesh/intern/bmesh_mesh_conv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index c23fd85458c..388d148377a 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -220,11 +220,11 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) normal_short_to_float_v3(v->no, mvert->no); - BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mvert->bweight / 255.0f); - - /* Copy Custom Dat */ + /* Copy Custom Data */ CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data); + BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mvert->bweight / 255.0f); + /* set shapekey data */ if (me->key) { /* set shape key original index */ -- cgit v1.2.3 From 46636a601e03eec7d78bc31064065980609187e6 Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Fri, 30 Nov 2012 16:03:34 +0000 Subject: Removed unused register_ lines from for and while loop nodes. These nodes were already commented out and removed in r51576. --- source/blender/blenkernel/intern/node.c | 6 ------ source/blender/nodes/NOD_composite.h | 2 -- source/blender/nodes/NOD_shader.h | 2 -- source/blender/nodes/NOD_texture.h | 2 -- 4 files changed, 12 deletions(-) diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index e5500108f46..70867a45fd7 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -2154,8 +2154,6 @@ static void registerCompositNodes(bNodeTreeType *ttype) register_node_type_reroute(ttype); register_node_type_cmp_group(ttype); -// register_node_type_cmp_forloop(ttype); -// register_node_type_cmp_whileloop(ttype); register_node_type_cmp_rlayers(ttype); register_node_type_cmp_image(ttype); @@ -2256,8 +2254,6 @@ static void registerShaderNodes(bNodeTreeType *ttype) register_node_type_reroute(ttype); register_node_type_sh_group(ttype); - //register_node_type_sh_forloop(ttype); - //register_node_type_sh_whileloop(ttype); register_node_type_sh_output(ttype); register_node_type_sh_material(ttype); @@ -2338,8 +2334,6 @@ static void registerTextureNodes(bNodeTreeType *ttype) register_node_type_reroute(ttype); register_node_type_tex_group(ttype); -// register_node_type_tex_forloop(ttype); -// register_node_type_tex_whileloop(ttype); register_node_type_tex_math(ttype); register_node_type_tex_mix_rgb(ttype); diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h index eecc1e46827..6d60ac0bb58 100644 --- a/source/blender/nodes/NOD_composite.h +++ b/source/blender/nodes/NOD_composite.h @@ -40,8 +40,6 @@ extern bNodeTreeType ntreeType_Composite; /* ****************** types array for all composite nodes ****************** */ void register_node_type_cmp_group(struct bNodeTreeType *ttype); -void register_node_type_cmp_forloop(struct bNodeTreeType *ttype); -void register_node_type_cmp_whileloop(struct bNodeTreeType *ttype); void register_node_type_cmp_rlayers(struct bNodeTreeType *ttype); void register_node_type_cmp_image(struct bNodeTreeType *ttype); diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h index e402924c04f..74135776c9c 100644 --- a/source/blender/nodes/NOD_shader.h +++ b/source/blender/nodes/NOD_shader.h @@ -41,8 +41,6 @@ extern struct bNodeTreeType ntreeType_Shader; /* ****************** types array for all shaders ****************** */ void register_node_type_sh_group(struct bNodeTreeType *ttype); -void register_node_type_sh_forloop(struct bNodeTreeType *ttype); -void register_node_type_sh_whileloop(struct bNodeTreeType *ttype); void register_node_type_sh_output(struct bNodeTreeType *ttype); void register_node_type_sh_material(struct bNodeTreeType *ttype); diff --git a/source/blender/nodes/NOD_texture.h b/source/blender/nodes/NOD_texture.h index 7722580d136..a1be9963b8a 100644 --- a/source/blender/nodes/NOD_texture.h +++ b/source/blender/nodes/NOD_texture.h @@ -40,8 +40,6 @@ extern bNodeTreeType ntreeType_Texture; /* ****************** types array for all texture nodes ****************** */ void register_node_type_tex_group(struct bNodeTreeType *ttype); -void register_node_type_tex_forloop(struct bNodeTreeType *ttype); -void register_node_type_tex_whileloop(struct bNodeTreeType *ttype); void register_node_type_tex_math(struct bNodeTreeType *ttype); void register_node_type_tex_mix_rgb(struct bNodeTreeType *ttype); -- cgit v1.2.3 From d72a6c3018f754cc1628267edd45f6a83afbfa42 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 30 Nov 2012 16:15:49 +0000 Subject: fix for another error in my own recent commit, beauty fill crashed. --- source/blender/bmesh/intern/bmesh_core.c | 4 ++-- source/blender/bmesh/intern/bmesh_mods.c | 7 ++++--- source/tests/bl_run_operators.py | 5 ++++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 059f9de5a42..14fab7abdc9 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -1049,7 +1049,7 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del } /* create region face */ - newf = BM_face_create_ngon(bm, v1, v2, edges, tote, 0); + newf = tote ? BM_face_create_ngon(bm, v1, v2, edges, tote, 0) : NULL; if (UNLIKELY(!newf || BMO_error_occurred(bm))) { if (!BMO_error_occurred(bm)) err = N_("Invalid boundary region to join faces"); @@ -1239,7 +1239,7 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, } /* allocate new edge between v1 and v2 */ - e = BM_edge_create(bm, v1, v2, example, nodouble); + e = BM_edge_create(bm, v1, v2, example, nodouble ? BM_CREATE_NO_DOUBLE : 0); f2 = bm_face_create__sfme(bm, f); f1loop = bm_loop_create(bm, v2, e, f, v2loop, 0); diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index dc8b52423ab..89516061f91 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -142,9 +142,10 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) return FALSE; } #else - BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, TRUE); - - if (!BM_vert_collapse_faces(bm, v->e, v, 1.0, FALSE, TRUE)) { + if (UNLIKELY(!BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, TRUE))) { + return FALSE; + } + else if (UNLIKELY(!BM_vert_collapse_faces(bm, v->e, v, 1.0, FALSE, TRUE))) { return FALSE; } #endif diff --git a/source/tests/bl_run_operators.py b/source/tests/bl_run_operators.py index f792b83a8cd..5bb25537458 100644 --- a/source/tests/bl_run_operators.py +++ b/source/tests/bl_run_operators.py @@ -35,13 +35,16 @@ op_blacklist = ( "*.open_*", "*.link_append", "render.render", + "render.play_rendered_anim", "*.*_export", "*.*_import", "wm.blenderplayer_start", "wm.url_open", "wm.doc_view", "wm.path_open", - "help.operator_cheat_sheet", + "wm.theme_install", + "wm.context_*", + "wm.operator_cheat_sheet", "wm.keyconfig_test", # just annoying - but harmless "wm.memory_statistics", # another annoying one "console.*", # just annoying - but harmless -- cgit v1.2.3 From 5446dc0bf3386e52202ae7af83c562c247c743d7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 30 Nov 2012 16:41:43 +0000 Subject: fix for various asserts running operator tests - not likely any of these would cause real user bugs though. --- source/blender/bmesh/operators/bmo_smooth_laplacian.c | 1 + source/blender/editors/mesh/editmesh_select.c | 6 +++--- source/blender/editors/mesh/editmesh_tools.c | 2 +- source/blender/editors/uvedit/uvedit_smart_stitch.c | 12 +++++++++--- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/source/blender/bmesh/operators/bmo_smooth_laplacian.c b/source/blender/bmesh/operators/bmo_smooth_laplacian.c index 4137c31961c..4a367a8fd6f 100644 --- a/source/blender/bmesh/operators/bmo_smooth_laplacian.c +++ b/source/blender/bmesh/operators/bmo_smooth_laplacian.c @@ -544,6 +544,7 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op) BMVert *v; LaplacianSystem *sys; + if (bm->totface == 0) return; sys = init_laplacian_system(bm->totedge, bm->totface, bm->totvert); if (!sys) return; sys->bm = bm; diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index c658272f23f..c159b50b077 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -732,7 +732,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op) EDBM_flag_disable_all(em, BM_ELEM_SELECT); /* select the output */ - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, TRUE); /* finish the operator */ if (!EDBM_op_finish(em, &bmop, op, TRUE)) { @@ -773,7 +773,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) EDBM_flag_disable_all(em, BM_ELEM_SELECT); /* select the output */ - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, TRUE); EDBM_selectmode_flush(em); /* finish the operator */ @@ -817,7 +817,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op) EDBM_flag_disable_all(em, BM_ELEM_SELECT); /* select the output */ - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_VERT, BM_ELEM_SELECT, TRUE); /* finish the operator */ if (!EDBM_op_finish(em, &bmop, op, TRUE)) { diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index c1401ea430a..ad1077156ba 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -2319,7 +2319,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op) /* EDBM_flag_disable_all(em, BM_ELEM_SELECT); */ /* select the output */ - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_VERT, BM_ELEM_SELECT, TRUE); /* finish the operator */ if (!EDBM_op_finish(em, &bmop, op, TRUE)) { diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index e10d70d48d1..4ca642690c4 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -1072,17 +1072,23 @@ static int stitch_init(bContext *C, wmOperator *op) BMEditMesh *em; GHashIterator *ghi; UvEdge *all_edges; - StitchState *state = MEM_mallocN(sizeof(StitchState), "stitch state"); + StitchState *state; Scene *scene = CTX_data_scene(C); ToolSettings *ts = scene->toolsettings; + ARegion *ar = CTX_wm_region(C); Object *obedit = CTX_data_edit_object(C); - op->customdata = state; + if (!ar) + return 0; + + state = MEM_mallocN(sizeof(StitchState), "stitch state"); if (!state) return 0; + op->customdata = state; + /* initialize state */ state->use_limit = RNA_boolean_get(op->ptr, "use_limit"); state->limit_dist = RNA_float_get(op->ptr, "limit"); @@ -1091,7 +1097,7 @@ static int stitch_init(bContext *C, wmOperator *op) 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"); - state->draw_handle = ED_region_draw_cb_activate(CTX_wm_region(C)->type, stitch_draw, NULL, REGION_DRAW_POST_VIEW); + state->draw_handle = ED_region_draw_cb_activate(ar->type, stitch_draw, NULL, REGION_DRAW_POST_VIEW); /* in uv synch selection, all uv's are visible */ if (ts->uv_flag & UV_SYNC_SELECTION) { state->element_map = EDBM_uv_element_map_create(state->em, 0, 1); -- cgit v1.2.3 From a2bf2ba7df80dd41d116ec00ff8a3efe2d50b123 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 30 Nov 2012 18:54:56 +0000 Subject: Fix transfer weight tool enum properties all showing question mark icons, these should have no icons. --- source/blender/editors/object/object_vgroup.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index d7c7d4c04ef..1b135c0686e 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -400,22 +400,22 @@ typedef enum WT_ReplaceMode { } WT_ReplaceMode; static EnumPropertyItem WT_vertex_group_mode_item[] = { - {WT_REPLACE_ACTIVE_VERTEX_GROUP, "WT_REPLACE_ACTIVE_VERTEX_GROUP", 1, "Active", "Transfer active vertex group from selected to active mesh"}, - {WT_REPLACE_ALL_VERTEX_GROUPS, "WT_REPLACE_ALL_VERTEX_GROUPS", 1, "All", "Transfer all vertex groups from selected to active mesh"}, + {WT_REPLACE_ACTIVE_VERTEX_GROUP, "WT_REPLACE_ACTIVE_VERTEX_GROUP", 0, "Active", "Transfer active vertex group from selected to active mesh"}, + {WT_REPLACE_ALL_VERTEX_GROUPS, "WT_REPLACE_ALL_VERTEX_GROUPS", 0, "All", "Transfer all vertex groups from selected to active mesh"}, {0, NULL, 0, NULL, NULL} }; static EnumPropertyItem WT_method_item[] = { - {WT_BY_INDEX, "WT_BY_INDEX", 1, "Vertex index", "Copy for identical meshes"}, - {WT_BY_NEAREST_VERTEX, "WT_BY_NEAREST_VERTEX", 1, "Nearest vertex", "Copy weight from closest vertex"}, - {WT_BY_NEAREST_FACE, "WT_BY_NEAREST_FACE", 1, "Nearest face", "Barycentric interpolation from nearest face"}, - {WT_BY_NEAREST_VERTEX_IN_FACE, "WT_BY_NEAREST_VERTEX_IN_FACE", 1, "Nearest vertex in face", "Copy weight from closest vertex in nearest face"}, + {WT_BY_INDEX, "WT_BY_INDEX", 0, "Vertex index", "Copy for identical meshes"}, + {WT_BY_NEAREST_VERTEX, "WT_BY_NEAREST_VERTEX", 0, "Nearest vertex", "Copy weight from closest vertex"}, + {WT_BY_NEAREST_FACE, "WT_BY_NEAREST_FACE", 0, "Nearest face", "Barycentric interpolation from nearest face"}, + {WT_BY_NEAREST_VERTEX_IN_FACE, "WT_BY_NEAREST_VERTEX_IN_FACE", 0, "Nearest vertex in face", "Copy weight from closest vertex in nearest face"}, {0, NULL, 0, NULL, NULL} }; static EnumPropertyItem WT_replace_mode_item[] = { - {WT_REPLACE_ALL_WEIGHTS, "WT_REPLACE_ALL_WEIGHTS", 1, "All", "Overwrite all weights"}, - {WT_REPLACE_EMPTY_WEIGHTS, "WT_REPLACE_EMPTY_WEIGHTS", 1, "Empty", "Add weights to vertices with no weight"}, + {WT_REPLACE_ALL_WEIGHTS, "WT_REPLACE_ALL_WEIGHTS", 0, "All", "Overwrite all weights"}, + {WT_REPLACE_EMPTY_WEIGHTS, "WT_REPLACE_EMPTY_WEIGHTS", 0, "Empty", "Add weights to vertices with no weight"}, {0, NULL, 0, NULL, NULL} }; -- cgit v1.2.3 From 75cce01a614e686530e26dbd186a88d75dc4e7b5 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 30 Nov 2012 18:55:04 +0000 Subject: Fix #33364: cycles tile rendering artifacts. --- intern/cycles/kernel/svm/svm_closure.h | 92 ++++++++++++++-------------------- intern/cycles/render/nodes.cpp | 3 ++ 2 files changed, 42 insertions(+), 53 deletions(-) diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index 7140b4971ea..564c0957c68 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -50,29 +50,34 @@ __device void svm_node_glass_setup(ShaderData *sd, ShaderClosure *sc, int type, } } -__device_inline ShaderClosure *svm_node_closure_get(ShaderData *sd) +__device_inline ShaderClosure *svm_node_closure_get_non_bsdf(ShaderData *sd, ClosureType type, float mix_weight) { #ifdef __MULTI_CLOSURE__ ShaderClosure *sc = &sd->closure[sd->num_closure]; - if(sd->num_closure < MAX_CLOSURE) + if(sd->num_closure < MAX_CLOSURE) { + sc->weight *= mix_weight; + sc->type = type; sd->num_closure++; + return sc; + } - return sc; + return NULL; #else return &sd->closure; #endif } -__device_inline ShaderClosure *svm_node_closure_get_weight(ShaderData *sd, float mix_weight) +__device_inline ShaderClosure *svm_node_closure_get_bsdf(ShaderData *sd, float mix_weight) { #ifdef __MULTI_CLOSURE__ ShaderClosure *sc = &sd->closure[sd->num_closure]; + float3 weight = sc->weight * mix_weight; + float sample_weight = fabsf(average(sc->weight)); - sc->weight *= mix_weight; - sc->sample_weight = fabsf(average(sc->weight)); - - if(sc->sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE) { + if(sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE) { + sc->weight = weight; + sc->sample_weight = sample_weight; sd->num_closure++; return sc; } @@ -112,7 +117,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st switch(type) { case CLOSURE_BSDF_DIFFUSE_ID: { - ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); + ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { sc->N = N; @@ -130,7 +135,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st break; } case CLOSURE_BSDF_TRANSLUCENT_ID: { - ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); + ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { sc->N = N; @@ -139,7 +144,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st break; } case CLOSURE_BSDF_TRANSPARENT_ID: { - ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); + ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { sc->N = N; @@ -154,7 +159,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE)) break; #endif - ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); + ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { sc->N = N; @@ -178,7 +183,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE)) break; #endif - ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); + ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { sc->N = N; @@ -220,7 +225,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st float3 weight = sc->weight; float sample_weight = sc->sample_weight; - sc = svm_node_closure_get_weight(sd, mix_weight*fresnel); + sc = svm_node_closure_get_bsdf(sd, mix_weight*fresnel); if(sc) { sc->N = N; @@ -232,14 +237,14 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st sc->weight = weight; sc->sample_weight = sample_weight; - sc = svm_node_closure_get_weight(sd, mix_weight*(1.0f - fresnel)); + sc = svm_node_closure_get_bsdf(sd, mix_weight*(1.0f - fresnel)); if(sc) { sc->N = N; svm_node_glass_setup(sd, sc, type, eta, roughness, true); } #else - ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); + ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { sc->N = N; @@ -255,7 +260,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE)) break; #endif - ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); + ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { sc->N = N; @@ -290,7 +295,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st break; } case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: { - ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); + ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { sc->N = N; @@ -327,7 +332,7 @@ __device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float * switch(type) { case CLOSURE_VOLUME_TRANSPARENT_ID: { - ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); + ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { float density = param1; @@ -336,7 +341,7 @@ __device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float * break; } case CLOSURE_VOLUME_ISOTROPIC_ID: { - ShaderClosure *sc = svm_node_closure_get_weight(sd, mix_weight); + ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { float density = param1; @@ -360,15 +365,10 @@ __device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 node if(mix_weight == 0.0f) return; - ShaderClosure *sc = svm_node_closure_get(sd); - sc->weight *= mix_weight; - sc->type = CLOSURE_EMISSION_ID; + svm_node_closure_get_non_bsdf(sd, CLOSURE_EMISSION_ID, mix_weight); } - else { - ShaderClosure *sc = svm_node_closure_get(sd); - sc->type = CLOSURE_EMISSION_ID; - } - + else + svm_node_closure_get_non_bsdf(sd, CLOSURE_EMISSION_ID, 1.0f); #else ShaderClosure *sc = &sd->closure; sc->type = CLOSURE_EMISSION_ID; @@ -388,15 +388,10 @@ __device void svm_node_closure_background(ShaderData *sd, float *stack, uint4 no if(mix_weight == 0.0f) return; - ShaderClosure *sc = svm_node_closure_get(sd); - sc->weight *= mix_weight; - sc->type = CLOSURE_BACKGROUND_ID; + svm_node_closure_get_non_bsdf(sd, CLOSURE_BACKGROUND_ID, mix_weight); } - else { - ShaderClosure *sc = svm_node_closure_get(sd); - sc->type = CLOSURE_BACKGROUND_ID; - } - + else + svm_node_closure_get_non_bsdf(sd, CLOSURE_BACKGROUND_ID, 1.0f); #else ShaderClosure *sc = &sd->closure; sc->type = CLOSURE_BACKGROUND_ID; @@ -414,15 +409,10 @@ __device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node) if(mix_weight == 0.0f) return; - ShaderClosure *sc = svm_node_closure_get(sd); - sc->weight = make_float3(mix_weight, mix_weight, mix_weight); - sc->type = CLOSURE_HOLDOUT_ID; - } - else { - ShaderClosure *sc = svm_node_closure_get(sd); - sc->weight = make_float3(1.0f, 1.0f, 1.0f); - sc->type = CLOSURE_HOLDOUT_ID; + svm_node_closure_get_non_bsdf(sd, CLOSURE_HOLDOUT_ID, mix_weight); } + else + svm_node_closure_get_non_bsdf(sd, CLOSURE_HOLDOUT_ID, 1.0f); #else ShaderClosure *sc = &sd->closure; sc->type = CLOSURE_HOLDOUT_ID; @@ -442,15 +432,10 @@ __device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack, u if(mix_weight == 0.0f) return; - ShaderClosure *sc = svm_node_closure_get(sd); - sc->weight *= mix_weight; - sc->type = CLOSURE_AMBIENT_OCCLUSION_ID; - } - else { - ShaderClosure *sc = svm_node_closure_get(sd); - sc->type = CLOSURE_AMBIENT_OCCLUSION_ID; + svm_node_closure_get_non_bsdf(sd, CLOSURE_AMBIENT_OCCLUSION_ID, mix_weight); } - + else + svm_node_closure_get_non_bsdf(sd, CLOSURE_AMBIENT_OCCLUSION_ID, 1.0f); #else ShaderClosure *sc = &sd->closure; sc->type = CLOSURE_AMBIENT_OCCLUSION_ID; @@ -464,7 +449,8 @@ __device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack, u __device_inline void svm_node_closure_store_weight(ShaderData *sd, float3 weight) { #ifdef __MULTI_CLOSURE__ - sd->closure[sd->num_closure].weight = weight; + if(sd->num_closure < MAX_CLOSURE) + sd->closure[sd->num_closure].weight = weight; #else sd->closure.weight = weight; #endif diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 48fe63670c7..55fb9bf8a7e 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1624,6 +1624,9 @@ HoldoutNode::HoldoutNode() void HoldoutNode::compile(SVMCompiler& compiler) { + float3 value = make_float3(1.0f, 1.0f, 1.0f); + + compiler.add_node(NODE_CLOSURE_SET_WEIGHT, value); compiler.add_node(NODE_CLOSURE_HOLDOUT, compiler.closure_mix_weight_offset()); } -- cgit v1.2.3