diff options
author | Alexander Pinzon <apinzonf@gmail.com> | 2013-08-14 23:49:37 +0400 |
---|---|---|
committer | Alexander Pinzon <apinzonf@gmail.com> | 2013-08-14 23:49:37 +0400 |
commit | 54741c2311f0c01885f8b4a818b11cea38f7085d (patch) | |
tree | 6326ea3ef022e11a2592423257f59a892aaa7174 /source | |
parent | 0b09beb16702af4acfd7d591dc6d3b2b8f8098b3 (diff) | |
parent | 503b7d5b9a385fdcd220df3142857300d912d80c (diff) |
svn merge ^/trunk/blender 58498:59138
Diffstat (limited to 'source')
528 files changed, 7131 insertions, 5890 deletions
diff --git a/source/blender/avi/intern/avi.c b/source/blender/avi/intern/avi.c index 48e64695822..dd52a27c022 100644 --- a/source/blender/avi/intern/avi.c +++ b/source/blender/avi/intern/avi.c @@ -811,12 +811,16 @@ AviError AVI_open_compress(char *name, AviMovie *movie, int streams, ...) movie->streams[i].sh.fcc = FCC("strh"); movie->streams[i].sh.size = 56; movie->streams[i].sh.Type = avi_get_format_type(movie->streams[i].format); - if (movie->streams[i].sh.Type == 0) + if (movie->streams[i].sh.Type == 0) { + va_end(ap); return AVI_ERROR_FORMAT; + } movie->streams[i].sh.Handler = avi_get_format_fcc(movie->streams[i].format); - if (movie->streams[i].sh.Handler == 0) + if (movie->streams[i].sh.Handler == 0) { + va_end(ap); return AVI_ERROR_FORMAT; + } movie->streams[i].sh.Flags = 0; movie->streams[i].sh.Priority = 0; @@ -950,6 +954,8 @@ AviError AVI_open_compress(char *name, AviMovie *movie, int streams, ...) PUT_FCCN((header_pos2 - header_pos1 + 4L), movie->fp); + va_end(ap); + return AVI_ERROR_NONE; } @@ -969,7 +975,7 @@ AviError AVI_write_frame(AviMovie *movie, int frame_num, ...) /* Allocate the new memory for the index entry */ - if (frame_num + 1 > movie->index_entries) { + if (frame_num >= movie->index_entries) { const size_t entry_size = (movie->header->Streams + 1) * sizeof(AviIndexEntry); movie->entries = (AviIndexEntry *)MEM_recallocN(movie->entries, (frame_num + 1) * entry_size); movie->index_entries = frame_num + 1; diff --git a/source/blender/avi/intern/avi_mjpeg.c b/source/blender/avi/intern/avi_mjpeg.c index 91b8fa5a060..a2d48c724de 100644 --- a/source/blender/avi/intern/avi_mjpeg.c +++ b/source/blender/avi/intern/avi_mjpeg.c @@ -44,8 +44,6 @@ #include "avi_mjpeg.h" -#define PADUP(num, amt) ((num + (amt - 1)) & ~(amt - 1)) - static void jpegmemdestmgr_build(j_compress_ptr cinfo, unsigned char *buffer, int bufsize); static void jpegmemsrcmgr_build(j_decompress_ptr dinfo, unsigned char *buffer, int bufsize); @@ -294,56 +292,13 @@ static void deinterlace(int odd, unsigned char *to, unsigned char *from, int wid static int check_and_decode_jpeg(unsigned char *inbuf, unsigned char *outbuf, int width, int height, int bufsize) { - /* JPEG's are always multiples of 16, extra is cropped out AVI's */ - if ((width & 0xF) || (height & 0xF)) { - int i, rrowstride, jrowstride; - int jwidth = PADUP(width, 16); - int jheight = PADUP(height, 16); - unsigned char *tmpbuf = MEM_mallocN(jwidth * jheight * 3, "avi.check_and_decode_jpeg"); - int ret = Decode_JPEG(inbuf, tmpbuf, jwidth, jheight, bufsize); - - /* crop the tmpbuf into the real buffer */ - rrowstride = width * 3; - jrowstride = jwidth * 3; - for (i = 0; i < height; i++) - memcpy(&outbuf[i * rrowstride], &tmpbuf[i * jrowstride], rrowstride); - MEM_freeN(tmpbuf); - - return ret; - } - else { - return Decode_JPEG(inbuf, outbuf, width, height, bufsize); - } + return Decode_JPEG(inbuf, outbuf, width, height, bufsize); } static void check_and_compress_jpeg(int quality, unsigned char *outbuf, const unsigned char *inbuf, int width, int height, int bufsize) { - /* JPEG's are always multiples of 16, extra is ignored in AVI's */ - if ((width & 0xF) || (height & 0xF)) { - int i, rrowstride, jrowstride; - int jwidth = PADUP(width, 16); - int jheight = PADUP(height, 16); - unsigned char *tmpbuf = MEM_mallocN(jwidth * jheight * 3, "avi.check_and_compress_jpeg"); - - /* resize the realbuf into the tmpbuf */ - rrowstride = width * 3; - jrowstride = jwidth * 3; - for (i = 0; i < jheight; i++) { - if (i < height) - memcpy(&tmpbuf[i * jrowstride], &inbuf[i * rrowstride], rrowstride); - else - memset(&tmpbuf[i * jrowstride], 0, rrowstride); - memset(&tmpbuf[i * jrowstride + rrowstride], 0, jrowstride - rrowstride); - } - - Compress_JPEG(quality, outbuf, tmpbuf, jwidth, jheight, bufsize); - - MEM_freeN(tmpbuf); - } - else { - Compress_JPEG(quality, outbuf, inbuf, width, height, bufsize); - } + Compress_JPEG(quality, outbuf, inbuf, width, height, bufsize); } void *avi_converter_from_mjpeg(AviMovie *movie, int stream, unsigned char *buffer, int *size) diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index fd8bd196717..8f77f8c984d 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -149,11 +149,11 @@ void BLF_shadow_offset(int fontid, int x, int y); /* Set the buffer, size and number of channels to draw, one thing to take care is call * this function with NULL pointer when we finish, for example: * - * BLF_buffer(my_fbuf, my_cbuf, 100, 100, 4, TRUE); + * BLF_buffer(my_fbuf, my_cbuf, 100, 100, 4, TRUE, NULL); * * ... set color, position and draw ... * - * BLF_buffer(NULL, NULL, 0, 0, 0, FALSE); + * BLF_buffer(NULL, NULL, NULL, 0, 0, FALSE, NULL); */ void BLF_buffer(int fontid, float *fbuf, unsigned char *cbuf, int w, int h, int nch, struct ColorManagedDisplay *display); diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index 55424145b43..37e874fa396 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -152,7 +152,7 @@ void blf_glyph_cache_free(GlyphCacheBLF *gc) } } - if (gc->cur_tex + 1 > 0) + if (gc->cur_tex > -1) glDeleteTextures(gc->cur_tex + 1, gc->textures); MEM_freeN((void *)gc->textures); MEM_freeN(gc); diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 40fc71e82ca..8396380fd06 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -152,6 +152,11 @@ typedef enum DMDrawFlag { DM_DRAW_ALWAYS_SMOOTH = 2 } DMDrawFlag; +typedef enum DMForeachFlag { + DM_FOREACH_NOP = 0, + DM_FOREACH_USE_NORMAL = (1 << 0), /* foreachMappedVert, foreachMappedFaceCenter */ +} DMForeachFlag; + typedef enum DMDirtyFlag { /* dm has valid tessellated faces, but tessellated CDDATA need to be updated. */ DM_DIRTY_TESS_CDLAYERS = 1 << 0, @@ -285,7 +290,8 @@ struct DerivedMesh { void (*foreachMappedVert)(DerivedMesh *dm, void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]), - void *userData); + void *userData, + DMForeachFlag flag); /** Iterate over each mapped edge in the derived mesh, calling the * given function with the original edge and the mapped edge's new @@ -303,7 +309,8 @@ struct DerivedMesh { void (*foreachMappedFaceCenter)(DerivedMesh *dm, void (*func)(void *userData, int index, const float cent[3], const float no[3]), - void *userData); + void *userData, + DMForeachFlag flag); /** Iterate over all vertex points, calling DO_MINMAX with given args. * diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 8c556e00aaa..84e24df43e5 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,15 +42,14 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 268 -#define BLENDER_SUBVERSION 0 - +#define BLENDER_SUBVERSION 2 /* 262 was the last editmesh release but it has compatibility code for bmesh data */ #define BLENDER_MINVERSION 262 #define BLENDER_MINSUBVERSION 0 /* used by packaging tools */ /* can be left blank, otherwise a,b,c... etc with no quotes */ -#define BLENDER_VERSION_CHAR +#define BLENDER_VERSION_CHAR a /* alpha/beta/rc/release, docs use this */ #define BLENDER_VERSION_CYCLE alpha diff --git a/source/blender/blenkernel/BKE_bmesh.h b/source/blender/blenkernel/BKE_bmesh.h deleted file mode 100644 index 0dfab26e9f0..00000000000 --- a/source/blender/blenkernel/BKE_bmesh.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2004 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Geoffrey Bantle. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __BKE_BMESH_H__ -#define __BKE_BMESH_H__ - -/** \file BKE_bmesh.h - * \ingroup bke - * \since January 2007 - * \brief BMesh modeler structure and functions. - * - */ - -/*NOTE: this is the bmesh 1.0 code. it's completely outdated.*/ - -/* uncomment to use the new bevel operator as a modifier */ -#define USE_BM_BEVEL_OP_AS_MOD - -/* bevel tool defines */ -/* element flags */ -#define BME_BEVEL_ORIG 1 -#define BME_BEVEL_BEVEL (1 << 1) -#define BME_BEVEL_NONMAN (1 << 2) -#define BME_BEVEL_WIRE (1 << 3) - -/* tool options */ -#define BME_BEVEL_SELECT 1 -#define BME_BEVEL_VERT (1 << 1) -#define BME_BEVEL_RADIUS (1 << 2) -#define BME_BEVEL_ANGLE (1 << 3) -#define BME_BEVEL_WEIGHT (1 << 4) -#define BME_BEVEL_VGROUP (1 << 5) -//~ #define BME_BEVEL_EWEIGHT (1<<4) -//~ #define BME_BEVEL_VWEIGHT (1<<5) -#define BME_BEVEL_PERCENT (1 << 6) -#define BME_BEVEL_EMIN (1 << 7) -#define BME_BEVEL_EMAX (1 << 8) -#define BME_BEVEL_RUNNING (1 << 9) -#define BME_BEVEL_RES (1 << 10) - -#define BME_BEVEL_EVEN (1 << 11) /* this is a new setting not related to old (trunk bmesh bevel code) but adding - * here because they are mixed - campbell */ -#define BME_BEVEL_DIST (1 << 12) /* same as above */ - -#define BME_BEVEL_OVERLAP_OK (1 << 13) - -typedef struct BME_TransData { - struct BMesh *bm; /* the bmesh the vert belongs to */ - struct BMVert *v; /* pointer to the vert this tdata applies to */ - float co[3]; /* the original coordinate */ - float org[3]; /* the origin */ - float vec[3]; /* a directional vector; always, always normalize! */ - void *loc; /* a pointer to the data to transform (likely the vert's cos) */ - float factor; /* primary scaling factor; also accumulates number of weighted edges for beveling tool */ - float weight; /* another scaling factor; used primarily for propogating vertex weights to transforms; */ - /* weight is also used across recursive bevels to help with the math */ - float maxfactor; /* the unscaled, original factor (used only by "edge verts" in recursive beveling) */ - float *max; /* the maximum distance this vert can be transformed; negative is infinite - * it points to the "parent" maxfactor (where maxfactor makes little sense) - * where the max limit is stored (limits are stored per-corner) */ -} BME_TransData; - -typedef struct BME_TransData_Head { - struct GHash *gh; /* the hash structure for element lookup */ - struct MemArena *ma; /* the memory "pool" we will be drawing individual elements from */ - int len; -} BME_TransData_Head; - -struct BME_TransData *BME_get_transdata(struct BME_TransData_Head *td, struct BMVert *v); -void BME_free_transdata(struct BME_TransData_Head *td); -struct BMesh *BME_bevel(struct BMesh *bm, float value, int res, int options, int defgrp_index, float angle, - BME_TransData_Head **rtd); - -#endif diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index 285077f258c..c6a6b0672d1 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -200,8 +200,8 @@ void CTX_data_dir_set(bContextDataResult *result, const char **member); void CTX_data_type_set(struct bContextDataResult *result, short type); short CTX_data_type_get(struct bContextDataResult *result); -int CTX_data_equals(const char *member, const char *str); -int CTX_data_dir(const char *member); +bool CTX_data_equals(const char *member, const char *str); +bool CTX_data_dir(const char *member); #if 0 void CTX_data_pointer_set(bContextDataResult *result, void *data); diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 3be77086336..baa90e7a856 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -69,7 +69,8 @@ bool BKE_curve_minmax(struct Curve *cu, float min[3], float max[3]); bool BKE_curve_center_median(struct Curve *cu, float cent[3]); bool BKE_curve_center_bounds(struct Curve *cu, float cent[3]); void BKE_curve_translate(struct Curve *cu, float offset[3], int do_keys); -void BKE_curve_delete_material_index(struct Curve *cu, int index); +void BKE_curve_material_index_remove(struct Curve *cu, int index); +void BKE_curve_material_index_clear(struct Curve *cu); ListBase *BKE_curve_nurbs_get(struct Curve *cu); @@ -129,6 +130,14 @@ bool BKE_nurb_type_convert(struct Nurb *nu, const short type, const bool use_han void BKE_nurb_points_add(struct Nurb *nu, int number); void BKE_nurb_bezierPoints_add(struct Nurb *nu, int number); +struct BezTriple *BKE_nurb_bezt_get_next(struct Nurb *nu, struct BezTriple *bezt); +struct BezTriple *BKE_nurb_bezt_get_prev(struct Nurb *nu, struct BezTriple *bezt); +struct BPoint *BKE_nurb_bpoint_get_next(struct Nurb *nu, struct BPoint *bp); +struct BPoint *BKE_nurb_bpoint_get_prev(struct Nurb *nu, struct BPoint *bp); + +void BKE_nurb_bezt_calc_normal(struct Nurb *nu, struct BezTriple *bezt, float r_normal[3]); +void BKE_nurb_bezt_calc_plane(struct Nurb *nu, struct BezTriple *bezt, float r_plane[3]); + void BKE_nurb_handle_calc(struct BezTriple *bezt, struct BezTriple *prev, struct BezTriple *next, int mode); void BKE_nurb_handles_calc(struct Nurb *nu); diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index 0699344a887..9d33af1a0f4 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -46,7 +46,6 @@ extern "C" { /* forwards */ struct Main; struct Object; -struct BME_Glob; typedef struct Global { diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index eefaac07b12..7b5abbba7f8 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -161,7 +161,7 @@ struct Image *BKE_image_load(struct Main *bmain, const char *filepath); struct Image *BKE_image_load_exists(const char *filepath); /* adds image, adds ibuf, generates color or pattern */ -struct Image *BKE_image_add_generated(struct Main *bmain, unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, float color[4]); +struct Image *BKE_image_add_generated(struct Main *bmain, unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, const float color[4]); /* adds image from imbuf, owns imbuf */ struct Image *BKE_image_add_from_imbuf(struct ImBuf *ibuf); diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index 7c47380f838..f52dc030873 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -87,9 +87,9 @@ int object_add_material_slot(struct Object *ob); int object_remove_material_slot(struct Object *ob); /* rna api */ -void material_append_id(struct ID *id, struct Material *ma); -struct Material *material_pop_id(struct ID *id, int index, int remove_material_slot); /* index is an int because of RNA */ - +void BKE_material_append_id(struct ID *id, struct Material *ma); +struct Material *BKE_material_pop_id(struct ID *id, int index, bool update_data); /* index is an int because of RNA */ +void BKE_material_clear_id(struct ID *id, bool update_data); /* rendering */ void init_render_material(struct Material *, int, float *); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 1c88a5c45dd..e582af77d61 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -188,7 +188,8 @@ void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase, void BKE_mesh_from_nurbs(struct Object *ob); void BKE_mesh_to_curve_nurblist(struct DerivedMesh *dm, struct ListBase *nurblist, const int edge_users_test); void BKE_mesh_to_curve(struct Scene *scene, struct Object *ob); -void BKE_mesh_delete_material_index(struct Mesh *me, short index); +void BKE_mesh_material_index_remove(struct Mesh *me, short index); +void BKE_mesh_material_index_clear(struct Mesh *me); void BKE_mesh_smooth_flag_set(struct Object *meshOb, int enableSmooth); void BKE_mesh_convert_mfaces_to_mpolys(struct Mesh *mesh); void BKE_mesh_do_versions_convert_mfaces_to_mpolys(struct Mesh *mesh); diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index b43747ab33a..4e9e18d43e3 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -742,6 +742,10 @@ struct ShadeResult; #define SH_NODE_WIREFRAME 178 #define SH_NODE_BSDF_TOON 179 #define SH_NODE_WAVELENGTH 180 +#define SH_NODE_BLACKBODY 181 +#define SH_NODE_VECT_TRANSFORM 182 +#define SH_NODE_SEPHSV 183 +#define SH_NODE_COMBHSV 184 /* custom defines options for Material node */ #define SH_NODE_MAT_DIFF 1 @@ -774,34 +778,37 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMateria /* ************** COMPOSITE NODES *************** */ /* output socket defines */ -#define RRES_OUT_IMAGE 0 -#define RRES_OUT_ALPHA 1 -#define RRES_OUT_Z 2 -#define RRES_OUT_NORMAL 3 -#define RRES_OUT_UV 4 -#define RRES_OUT_VEC 5 -#define RRES_OUT_RGBA 6 -#define RRES_OUT_DIFF 7 -#define RRES_OUT_SPEC 8 -#define RRES_OUT_SHADOW 9 -#define RRES_OUT_AO 10 -#define RRES_OUT_REFLECT 11 -#define RRES_OUT_REFRACT 12 -#define RRES_OUT_INDIRECT 13 -#define RRES_OUT_INDEXOB 14 -#define RRES_OUT_INDEXMA 15 -#define RRES_OUT_MIST 16 -#define RRES_OUT_EMIT 17 -#define RRES_OUT_ENV 18 -#define RRES_OUT_DIFF_DIRECT 19 -#define RRES_OUT_DIFF_INDIRECT 20 -#define RRES_OUT_DIFF_COLOR 21 -#define RRES_OUT_GLOSSY_DIRECT 22 -#define RRES_OUT_GLOSSY_INDIRECT 23 -#define RRES_OUT_GLOSSY_COLOR 24 -#define RRES_OUT_TRANSM_DIRECT 25 -#define RRES_OUT_TRANSM_INDIRECT 26 -#define RRES_OUT_TRANSM_COLOR 27 +#define RRES_OUT_IMAGE 0 +#define RRES_OUT_ALPHA 1 +#define RRES_OUT_Z 2 +#define RRES_OUT_NORMAL 3 +#define RRES_OUT_UV 4 +#define RRES_OUT_VEC 5 +#define RRES_OUT_RGBA 6 +#define RRES_OUT_DIFF 7 +#define RRES_OUT_SPEC 8 +#define RRES_OUT_SHADOW 9 +#define RRES_OUT_AO 10 +#define RRES_OUT_REFLECT 11 +#define RRES_OUT_REFRACT 12 +#define RRES_OUT_INDIRECT 13 +#define RRES_OUT_INDEXOB 14 +#define RRES_OUT_INDEXMA 15 +#define RRES_OUT_MIST 16 +#define RRES_OUT_EMIT 17 +#define RRES_OUT_ENV 18 +#define RRES_OUT_DIFF_DIRECT 19 +#define RRES_OUT_DIFF_INDIRECT 20 +#define RRES_OUT_DIFF_COLOR 21 +#define RRES_OUT_GLOSSY_DIRECT 22 +#define RRES_OUT_GLOSSY_INDIRECT 23 +#define RRES_OUT_GLOSSY_COLOR 24 +#define RRES_OUT_TRANSM_DIRECT 25 +#define RRES_OUT_TRANSM_INDIRECT 26 +#define RRES_OUT_TRANSM_COLOR 27 +#define RRES_OUT_SUBSURFACE_DIRECT 28 +#define RRES_OUT_SUBSURFACE_INDIRECT 29 +#define RRES_OUT_SUBSURFACE_COLOR 30 /* note: types are needed to restore callbacks, don't change values */ #define CMP_NODE_VIEWER 201 diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 48c16f8db38..7d3d8d7dcbd 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -223,7 +223,7 @@ typedef struct PBVHVertexIter { struct CCGElem **grids; struct CCGElem *grid; struct CCGKey *key; - BLI_bitmap *grid_hidden, gh; + BLI_bitmap **grid_hidden, *gh; int *grid_indices; int totgrid; int gridsize; diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index b5a6c6fb821..c883bdf74e0 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -254,6 +254,7 @@ struct SpaceType *BKE_spacetype_from_id(int spaceid); struct ARegionType *BKE_regiontype_from_id(struct SpaceType *st, int regionid); const struct ListBase *BKE_spacetypes_list(void); void BKE_spacetype_register(struct SpaceType *st); +int BKE_spacetype_exists(int spaceid); void BKE_spacetypes_free(void); /* only for quitting blender */ /* spacedata */ diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 4494d127082..78018f04458 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -208,6 +208,10 @@ int BKE_sequencer_recursive_apply(struct Sequence *seq, int (*apply_func)(struct void BKE_sequencer_free_clipboard(void); +void BKE_sequence_clipboard_pointers_free(struct Sequence *seq); +void BKE_sequence_clipboard_pointers_store(struct Sequence *seq); +void BKE_sequence_clipboard_pointers_restore(struct Sequence *seq, struct Main *bmain); + void BKE_sequence_free(struct Scene *scene, struct Sequence *seq); const char *BKE_sequence_give_name(struct Sequence *seq); void BKE_sequence_calc(struct Scene *scene, struct Sequence *seq); @@ -261,7 +265,7 @@ void BKE_sequencer_preprocessed_cache_cleanup_sequence(struct Sequence *seq); /* ********************************************************************** * seqeffects.c * - * Sequencer effect strip managment functions + * Sequencer effect strip management functions * ********************************************************************** */ @@ -319,8 +323,6 @@ void BKE_sequence_base_dupli_recursive(struct Scene *scene, struct Scene *scene_ bool BKE_sequence_is_valid_check(struct Sequence *seq); void BKE_sequencer_clear_scene_in_allseqs(struct Main *bmain, struct Scene *sce); -void BKE_sequencer_clear_movieclip_in_clipboard(struct MovieClip *clip); -void BKE_sequencer_clear_mask_in_clipboard(struct Mask *mask); struct Sequence *BKE_sequence_get_by_name(struct ListBase *seqbase, const char *name, int recursive); diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 2f51f9f17fe..655e0d65133 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -165,7 +165,6 @@ set(SRC BKE_armature.h BKE_autoexec.h BKE_blender.h - BKE_bmesh.h BKE_bmfont.h BKE_bmfont_types.h BKE_boids.h diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 7a7d4c7d24a..2ece90183bd 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -46,7 +46,6 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_memarena.h" -#include "BLI_array.h" #include "BLI_utildefines.h" #include "BLI_linklist.h" @@ -531,7 +530,9 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask) } /* copy texture space */ - BKE_mesh_texspace_copy_from_object(&tmp, ob); + if (ob) { + BKE_mesh_texspace_copy_from_object(&tmp, ob); + } /* not all DerivedMeshes store their verts/edges/faces in CustomData, so * we set them here in case they are missing */ @@ -2634,9 +2635,9 @@ void DM_add_tangent_layer(DerivedMesh *dm) /* new computation method */ { - SGLSLMeshToTangent mesh2tangent = {0}; - SMikkTSpaceContext sContext = {0}; - SMikkTSpaceInterface sInterface = {0}; + SGLSLMeshToTangent mesh2tangent = {NULL}; + SMikkTSpaceContext sContext = {NULL}; + SMikkTSpaceInterface sInterface = {NULL}; mesh2tangent.precomputedFaceNormals = nors; mesh2tangent.mtface = mtface; diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 70fbf2d39e8..bfef3542c45 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -613,9 +613,12 @@ void BKE_pose_channels_hash_free(bPose *pose) } } - void BKE_pose_channel_free(bPoseChannel *pchan) { + if (pchan->custom) { + id_us_min(&pchan->custom->id); + pchan->custom = NULL; + } if (pchan->mpath) { animviz_free_motionpath(pchan->mpath); @@ -727,6 +730,9 @@ void BKE_pose_channel_copy_data(bPoseChannel *pchan, const bPoseChannel *pchan_f /* custom shape */ pchan->custom = pchan_from->custom; + if (pchan->custom) { + id_us_plus(&pchan->custom->id); + } } diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 9fea3d2e13f..ba680147201 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -1036,7 +1036,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl if (ob->type != OB_MBALL) ob->flag |= OB_DONE; /* doesnt render */ if (me->edit_btmesh) { - dm->foreachMappedVert(dm, vertex_dupli__mapFunc, (void *) &vdd); + dm->foreachMappedVert(dm, vertex_dupli__mapFunc, (void *) &vdd, DM_FOREACH_USE_NORMAL); } else { for (a = 0; a < totvert; a++) { diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 001964087b8..4b05b0800a5 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -39,8 +39,8 @@ #include "MEM_guardedalloc.h" #include "BLI_utildefines.h" -#include "BLI_array.h" #include "BLI_blenlib.h" +#include "BLI_alloca.h" #include "BLI_dynstr.h" #include "BLF_translation.h" diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index d37ccae3089..f006710dc21 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1605,7 +1605,10 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected pchanw.next = pchan->next; pchanw.parent = pchan->parent; pchanw.child = pchan->child; - + + pchanw.mpath = pchan->mpath; + pchan->mpath = NULL; + /* this is freed so copy a copy, else undo crashes */ if (pchanw.prop) { pchanw.prop = IDP_CopyProperty(pchanw.prop); @@ -1652,10 +1655,16 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected /* copy data in temp back over to the cleaned-out (but still allocated) original channel */ *pchan = pchanw; + if (pchan->custom) { + id_us_plus(&pchan->custom->id); + } } else { /* always copy custom shape */ pchan->custom = pchanp->custom; + if (pchan->custom) { + id_us_plus(&pchan->custom->id); + } if (pchanp->custom_tx) pchan->custom_tx = BKE_pose_channel_find_name(pose, pchanp->custom_tx->name); diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 29a8a615601..26f481e5341 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -816,7 +816,7 @@ int BKE_undo_save_file(const char *filename) * to avoid writing to a symlink - use 'O_EXCL' (CVE-2008-1103) */ errno = 0; file = BLI_open(filename, flag, 0666); - if (file == -1) { + if (file < 0) { if (errno == EEXIST) { errno = 0; file = BLI_open(filename, flag & ~O_CREAT, 0666); diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index a47cab7f236..f9444ca2cf9 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -408,26 +408,33 @@ void BKE_camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, cons } else { /* that way it's always visible - clipsta+0.1 */ - float fac; - float half_sensor = 0.5f * ((camera->sensor_fit == CAMERA_SENSOR_FIT_VERT) ? (camera->sensor_y) : (camera->sensor_x)); + float fac, scale_x, scale_y; + float half_sensor = 0.5f * ((camera->sensor_fit == CAMERA_SENSOR_FIT_VERT) ? + (camera->sensor_y) : (camera->sensor_x)); - *r_drawsize = drawsize / ((scale[0] + scale[1] + scale[2]) / 3.0f); if (do_clip) { /* fixed depth, variable size (avoids exceeding clipping range) */ - depth = -(camera->clipsta + 0.1f); - fac = depth / (camera->lens / (-half_sensor) * scale[2]); + /* r_drawsize shouldn't be used in this case, set to dummy value */ + *r_drawsize = 1.0f; + depth = -(camera->clipsta + 0.1f) * scale[2]; + fac = depth / (camera->lens / (-half_sensor)); + scale_x = 1.0f; + scale_y = 1.0f; } else { /* fixed size, variable depth (stays a reasonable size in the 3D view) */ + *r_drawsize = drawsize / ((scale[0] + scale[1] + scale[2]) / 3.0f); depth = *r_drawsize * camera->lens / (-half_sensor) * scale[2]; fac = *r_drawsize; + scale_x = scale[0]; + scale_y = scale[1]; } - facx = fac * r_asp[0] * scale[0]; - facy = fac * r_asp[1] * scale[1]; - r_shift[0] = camera->shiftx * fac * 2 * scale[0]; - r_shift[1] = camera->shifty * fac * 2 * scale[1]; + facx = fac * r_asp[0] * scale_x; + facy = fac * r_asp[1] * scale_y; + r_shift[0] = camera->shiftx * fac * 2.0f * scale_x; + r_shift[1] = camera->shifty * fac * 2.0f * scale_y; } r_vec[0][0] = r_shift[0] + facx; r_vec[0][1] = r_shift[1] + facy; r_vec[0][2] = depth; @@ -455,7 +462,7 @@ typedef struct CameraViewFrameData { unsigned int tot; } CameraViewFrameData; -static void BKE_camera_to_frame_view_cb(const float co[3], void *user_data) +static void camera_to_frame_view_cb(const float co[3], void *user_data) { CameraViewFrameData *data = (CameraViewFrameData *)user_data; unsigned int i; @@ -519,7 +526,7 @@ int BKE_camera_view_frame_fit_to_scene(Scene *scene, struct View3D *v3d, Object data_cb.tot = 0; /* run callback on all visible points */ BKE_scene_foreach_display_point(scene, v3d, BA_SELECT, - BKE_camera_to_frame_view_cb, &data_cb); + camera_to_frame_view_cb, &data_cb); if (data_cb.tot <= 1) { return FALSE; diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index faa4d8d3071..6205c8016b6 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -40,7 +40,6 @@ #include "BLI_blenlib.h" #include "BLI_edgehash.h" #include "BLI_math.h" -#include "BLI_array.h" #include "BLI_smallhash.h" #include "BLI_utildefines.h" #include "BLI_scanfill.h" @@ -1548,19 +1547,26 @@ static void cdDM_drawMappedEdges(DerivedMesh *dm, DMSetDrawOptions setDrawOption static void cdDM_foreachMappedVert( DerivedMesh *dm, void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]), - void *userData) + void *userData, + DMForeachFlag flag) { MVert *mv = CDDM_get_verts(dm); - int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX); + int *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX); + int i; - for (i = 0; i < dm->numVertData; i++, mv++) { - if (index) { - orig = *index++; + if (index) { + for (i = 0; i < dm->numVertData; i++, mv++) { + const short *no = (flag & DM_FOREACH_USE_NORMAL) ? mv->no : NULL; + const int orig = *index++; if (orig == ORIGINDEX_NONE) continue; - func(userData, orig, mv->co, NULL, mv->no); + func(userData, orig, mv->co, NULL, no); + } + } + else { + for (i = 0; i < dm->numVertData; i++, mv++) { + const short *no = (flag & DM_FOREACH_USE_NORMAL) ? mv->no : NULL; + func(userData, i, mv->co, NULL, no); } - else - func(userData, i, mv->co, NULL, mv->no); } } @@ -1588,47 +1594,37 @@ static void cdDM_foreachMappedEdge( static void cdDM_foreachMappedFaceCenter( DerivedMesh *dm, void (*func)(void *userData, int index, const float cent[3], const float no[3]), - void *userData) + void *userData, + DMForeachFlag flag) { CDDerivedMesh *cddm = (CDDerivedMesh *)dm; MVert *mvert = cddm->mvert; MPoly *mp; MLoop *ml; - int i, j, orig, *index; + int i, orig, *index; index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX); mp = cddm->mpoly; for (i = 0; i < dm->numPolyData; i++, mp++) { float cent[3]; - float no[3]; + float *no, _no[3]; if (index) { orig = *index++; if (orig == ORIGINDEX_NONE) continue; } - else + else { orig = i; + } ml = &cddm->mloop[mp->loopstart]; - cent[0] = cent[1] = cent[2] = 0.0f; - for (j = 0; j < mp->totloop; j++, ml++) { - add_v3_v3v3(cent, cent, mvert[ml->v].co); - } - mul_v3_fl(cent, 1.0f / (float)j); + BKE_mesh_calc_poly_center(mp, ml, mvert, cent); - ml = &cddm->mloop[mp->loopstart]; - if (j > 3) { - normal_quad_v3(no, - mvert[(ml + 0)->v].co, - mvert[(ml + 1)->v].co, - mvert[(ml + 2)->v].co, - mvert[(ml + 3)->v].co); + if (flag & DM_FOREACH_USE_NORMAL) { + BKE_mesh_calc_poly_normal(mp, ml, mvert, (no = _no)); } else { - normal_tri_v3(no, - mvert[(ml + 0)->v].co, - mvert[(ml + 1)->v].co, - mvert[(ml + 2)->v].co); + no = NULL; } func(userData, orig, cent, no); @@ -1973,8 +1969,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, index = dm->getVertDataArray(dm, CD_ORIGINDEX); - eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); - for (i = 0; eve; eve = BM_iter_step(&iter), i++, index++) { + BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { MVert *mv = &mvert[i]; copy_v3_v3(mv->co, eve->co); @@ -1987,15 +1982,14 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, if (cd_vert_bweight_offset != -1) mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset); - if (add_orig) *index = i; + if (add_orig) *index++ = i; CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i); } bm->elem_index_dirty &= ~BM_VERT; index = dm->getEdgeDataArray(dm, CD_ORIGINDEX); - eed = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL); - for (i = 0; eed; eed = BM_iter_step(&iter), i++, index++) { + BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) { MEdge *med = &medge[i]; BM_elem_index_set(eed, i); /* set_inline */ @@ -2017,7 +2011,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, if (cd_edge_bweight_offset != -1) med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset); CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i); - if (add_orig) *index = i; + if (add_orig) *index++ = i; } bm->elem_index_dirty &= ~BM_EDGE; @@ -2027,7 +2021,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, BM_mesh_elem_index_ensure(bm, BM_FACE); index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); - for (i = 0; i < dm->numTessFaceData; i++, index++) { + for (i = 0; i < dm->numTessFaceData; i++) { MFace *mf = &mface[i]; const BMLoop **l = em_looptris[i]; efa = l[0]->f; @@ -2040,7 +2034,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, mf->flag = BM_face_flag_to_mflag(efa); /* map mfaces to polygons in the same cddm intentionally */ - *index = BM_elem_index_get(efa); + *index++ = BM_elem_index_get(efa); loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex); test_index_face(mf, &dm->faceData, i, 3); @@ -2049,8 +2043,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX); j = 0; - efa = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL); - for (i = 0; efa; i++, efa = BM_iter_step(&iter), index++) { + BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { BMLoop *l_iter; BMLoop *l_first; MPoly *mp = &mpoly[i]; @@ -2074,7 +2067,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i); - if (add_orig) *index = i; + if (add_orig) *index++ = i; } bm->elem_index_dirty &= ~BM_FACE; diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index a7311d5efc7..05ffd4a6265 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -476,7 +476,6 @@ void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, Derived BKE_ptcache_validate(cache, 0); cache->last_exact= 0; cache->flag &= ~PTCACHE_REDO_NEEDED; - return; } // unused in the moment, calculated separately in implicit.c diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index b8d851d082a..eda770ddf30 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1227,7 +1227,7 @@ static void followpath_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra copy_v3_v3(totmat[3], vec); - mul_serie_m4(ct->matrix, ct->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL); + mul_m4_m4m4(ct->matrix, ct->tar->obmat, totmat); } } } @@ -1253,7 +1253,7 @@ static void followpath_evaluate(bConstraint *con, bConstraintOb *cob, ListBase * mat4_to_size(size, cob->matrix); /* apply targetmat - containing location on path, and rotation */ - mul_serie_m4(cob->matrix, ct->matrix, obmat, NULL, NULL, NULL, NULL, NULL, NULL); + mul_m4_m4m4(cob->matrix, ct->matrix, obmat); /* un-apply scaling caused by path */ if ((data->followflag & FOLLOWPATH_RADIUS) == 0) { /* XXX - assume that scale correction means that radius will have some scale error in it - Campbell */ @@ -2080,6 +2080,8 @@ static void actcon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintT axis = data->type - 20; } + BLI_assert((unsigned int)axis < 3); + /* Target defines the animation */ s = (vec[axis] - data->min) / (data->max - data->min); CLAMP(s, 0, 1); @@ -3120,7 +3122,7 @@ static void clampto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar unit_m4(totmat); copy_v3_v3(totmat[3], vec); - mul_serie_m4(targetMatrix, ct->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL); + mul_m4_m4m4(targetMatrix, ct->tar->obmat, totmat); } } diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index bbf254cd7d1..622b4f6df5a 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -531,12 +531,12 @@ ListBase CTX_data_dir_get(const bContext *C) return CTX_data_dir_get_ex(C, TRUE, FALSE, FALSE); } -int CTX_data_equals(const char *member, const char *str) +bool CTX_data_equals(const char *member, const char *str) { return (strcmp(member, str) == 0); } -int CTX_data_dir(const char *member) +bool CTX_data_dir(const char *member) { return member[0] == '\0'; } diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index b6c4505bd78..2285d7d8dc0 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -681,6 +681,143 @@ void BKE_nurb_bezierPoints_add(Nurb *nu, int number) nu->pntsu += number; } + +BezTriple *BKE_nurb_bezt_get_next(Nurb *nu, BezTriple *bezt) +{ + BezTriple *bezt_next; + + BLI_assert(ARRAY_HAS_ITEM(bezt, nu->bezt, nu->pntsu)); + + if (bezt == &nu->bezt[nu->pntsu - 1]) { + if (nu->flagu & CU_NURB_CYCLIC) { + bezt_next = nu->bezt; + } + else { + bezt_next = NULL; + } + } + else { + bezt_next = bezt + 1; + } + + return bezt_next; +} + +BPoint *BKE_nurb_bpoint_get_next(Nurb *nu, BPoint *bp) +{ + BPoint *bp_next; + + BLI_assert(ARRAY_HAS_ITEM(bp, nu->bp, nu->pntsu)); + + if (bp == &nu->bp[nu->pntsu - 1]) { + if (nu->flagu & CU_NURB_CYCLIC) { + bp_next = nu->bp; + } + else { + bp_next = NULL; + } + } + else { + bp_next = bp + 1; + } + + return bp_next; +} + +BezTriple *BKE_nurb_bezt_get_prev(Nurb *nu, BezTriple *bezt) +{ + BezTriple *bezt_prev; + + BLI_assert(ARRAY_HAS_ITEM(bezt, nu->bezt, nu->pntsu)); + + if (bezt == nu->bezt) { + if (nu->flagu & CU_NURB_CYCLIC) { + bezt_prev = &nu->bezt[nu->pntsu - 1]; + } + else { + bezt_prev = NULL; + } + } + else { + bezt_prev = bezt - 1; + } + + return bezt_prev; +} + +BPoint *BKE_nurb_bpoint_get_prev(Nurb *nu, BPoint *bp) +{ + BPoint *bp_prev; + + BLI_assert(ARRAY_HAS_ITEM(bp, nu->bp, nu->pntsu)); + + if (bp == nu->bp) { + if (nu->flagu & CU_NURB_CYCLIC) { + bp_prev = &nu->bp[nu->pntsu - 1]; + } + else { + bp_prev = NULL; + } + } + else { + bp_prev = bp - 1; + } + + return bp_prev; +} + +void BKE_nurb_bezt_calc_normal(struct Nurb *UNUSED(nu), struct BezTriple *bezt, float r_normal[3]) +{ + /* calculate the axis matrix from the spline */ + float dir_prev[3], dir_next[3]; + + sub_v3_v3v3(dir_prev, bezt->vec[0], bezt->vec[1]); + sub_v3_v3v3(dir_next, bezt->vec[1], bezt->vec[2]); + + normalize_v3(dir_prev); + normalize_v3(dir_next); + + add_v3_v3v3(r_normal, dir_prev, dir_next); + normalize_v3(r_normal); +} + +void BKE_nurb_bezt_calc_plane(struct Nurb *nu, struct BezTriple *bezt, float r_plane[3]) +{ + float dir_prev[3], dir_next[3]; + + sub_v3_v3v3(dir_prev, bezt->vec[0], bezt->vec[1]); + sub_v3_v3v3(dir_next, bezt->vec[1], bezt->vec[2]); + + normalize_v3(dir_prev); + normalize_v3(dir_next); + + cross_v3_v3v3(r_plane, dir_prev, dir_next); + if (normalize_v3(r_plane) < FLT_EPSILON) { + BezTriple *bezt_prev = BKE_nurb_bezt_get_prev(nu, bezt); + BezTriple *bezt_next = BKE_nurb_bezt_get_next(nu, bezt); + + if (bezt_prev) { + sub_v3_v3v3(dir_prev, bezt_prev->vec[1], bezt->vec[1]); + normalize_v3(dir_prev); + } + if (bezt_next) { + sub_v3_v3v3(dir_next, bezt->vec[1], bezt_next->vec[1]); + normalize_v3(dir_next); + } + cross_v3_v3v3(r_plane, dir_prev, dir_next); + } + + /* matches with bones more closely */ + { + float dir_mid[3], tvec[3]; + add_v3_v3v3(dir_mid, dir_prev, dir_next); + cross_v3_v3v3(tvec, r_plane, dir_mid); + copy_v3_v3(r_plane, tvec); + } + + normalize_v3(r_plane); +} + /* ~~~~~~~~~~~~~~~~~~~~Non Uniform Rational B Spline calculations ~~~~~~~~~~~ */ @@ -1853,36 +1990,35 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float * /* make_bevel_list_3D_* funcs, at a minimum these must * fill in the bezp->quat and bezp->dir values */ -/* correct non-cyclic cases by copying direction and rotation - * values onto the first & last end-points */ -static void bevel_list_cyclic_fix_3D(BevList *bl) -{ - BevPoint *bevp, *bevp1; - - bevp = (BevPoint *)(bl + 1); - bevp1 = bevp + 1; - copy_qt_qt(bevp->quat, bevp1->quat); - copy_v3_v3(bevp->dir, bevp1->dir); - copy_v3_v3(bevp->tan, bevp1->tan); - bevp = (BevPoint *)(bl + 1); - bevp += (bl->nr - 1); - bevp1 = bevp - 1; - copy_qt_qt(bevp->quat, bevp1->quat); - copy_v3_v3(bevp->dir, bevp1->dir); - copy_v3_v3(bevp->tan, bevp1->tan); -} - /* utility for make_bevel_list_3D_* funcs */ static void bevel_list_calc_bisect(BevList *bl) { BevPoint *bevp2, *bevp1, *bevp0; int nr; + bool is_cyclic = bl->poly != -1; - bevp2 = (BevPoint *)(bl + 1); - bevp1 = bevp2 + (bl->nr - 1); - bevp0 = bevp1 - 1; + if (is_cyclic) { + bevp2 = (BevPoint *)(bl + 1); + bevp1 = bevp2 + (bl->nr - 1); + bevp0 = bevp1 - 1; + nr = bl->nr; + } + else { + /* If spline is not cyclic, direction of first and + * last bevel points matches direction of CV handle. + * + * This is getting calculated earlier when we know + * CV's handles and here we might simply skip evaluation + * of direction for this guys. + */ + + bevp0 = (BevPoint *)(bl + 1); + bevp1 = bevp0 + 1; + bevp2 = bevp1 + 1; + + nr = bl->nr - 2; + } - nr = bl->nr; while (nr--) { /* totally simple */ bisect_v3_v3v3v3(bevp1->dir, bevp0->vec, bevp1->vec, bevp2->vec); @@ -1988,22 +2124,30 @@ static void bevel_list_smooth(BevList *bl, int smooth_iter) static void make_bevel_list_3D_zup(BevList *bl) { - BevPoint *bevp2, *bevp1, *bevp0; /* standard for all make_bevel_list_3D_* funcs */ - int nr; + BevPoint *bevp = (BevPoint *)(bl + 1); + int nr = bl->nr; - bevp2 = (BevPoint *)(bl + 1); - bevp1 = bevp2 + (bl->nr - 1); - bevp0 = bevp1 - 1; + bevel_list_calc_bisect(bl); - nr = bl->nr; while (nr--) { - /* totally simple */ - bisect_v3_v3v3v3(bevp1->dir, bevp0->vec, bevp1->vec, bevp2->vec); - vec_to_quat(bevp1->quat, bevp1->dir, 5, 1); + vec_to_quat(bevp->quat, bevp->dir, 5, 1); + bevp++; + } +} - bevp0 = bevp1; - bevp1 = bevp2; - bevp2++; +static void minimum_twist_between_two_points(BevPoint *current_point, BevPoint *previous_point) +{ + float angle = angle_normalized_v3v3(previous_point->dir, current_point->dir); + float q[4]; + + if (angle > 0.0f) { /* otherwise we can keep as is */ + float cross_tmp[3]; + cross_v3_v3v3(cross_tmp, previous_point->dir, current_point->dir); + axis_angle_to_quat(q, cross_tmp, angle); + mul_qt_qtqt(current_point->quat, q, previous_point->quat); + } + else { + copy_qt_qt(current_point->quat, previous_point->quat); } } @@ -2026,17 +2170,7 @@ static void make_bevel_list_3D_minimum_twist(BevList *bl) vec_to_quat(bevp1->quat, bevp1->dir, 5, 1); } else { - float angle = angle_normalized_v3v3(bevp0->dir, bevp1->dir); - - if (angle > 0.0f) { /* otherwise we can keep as is */ - float cross_tmp[3]; - cross_v3_v3v3(cross_tmp, bevp0->dir, bevp1->dir); - axis_angle_to_quat(q, cross_tmp, angle); - mul_qt_qtqt(bevp1->quat, q, bevp0->quat); - } - else { - copy_qt_qt(bevp1->quat, bevp0->quat); - } + minimum_twist_between_two_points(bevp1, bevp0); } bevp0 = bevp1; @@ -2107,6 +2241,21 @@ static void make_bevel_list_3D_minimum_twist(BevList *bl) bevp2++; } } + else { + /* Need to correct quat for the first/last point, + * this is so because previously it was only calculated + * using it's own direction, which might not correspond + * the twist of neighbor point. + */ + bevp1 = (BevPoint *)(bl + 1); + bevp0 = bevp1 + 1; + minimum_twist_between_two_points(bevp1, bevp0); + + bevp2 = (BevPoint *)(bl + 1); + bevp1 = bevp2 + (bl->nr - 1); + bevp0 = bevp1 - 1; + minimum_twist_between_two_points(bevp1, bevp0); + } } static void make_bevel_list_3D_tangent(BevList *bl) @@ -2117,8 +2266,6 @@ static void make_bevel_list_3D_tangent(BevList *bl) float bevp0_tan[3]; bevel_list_calc_bisect(bl); - if (bl->poly == -1) /* check its not cyclic */ - bevel_list_cyclic_fix_3D(bl); // XXX - run this now so tangents will be right before doing the flipping bevel_list_flip_tangents(bl); /* correct the tangents */ @@ -2176,9 +2323,6 @@ static void make_bevel_list_3D(BevList *bl, int smooth_iter, int twist_mode) break; } - if (bl->poly == -1) /* check its not cyclic */ - bevel_list_cyclic_fix_3D(bl); - if (smooth_iter) bevel_list_smooth(bl, smooth_iter); @@ -2264,9 +2408,23 @@ static void make_bevel_list_2D(BevList *bl) bevp1 = bevp - 1; bevp->sina = bevp1->sina; bevp->cosa = bevp1->cosa; + } +} + +static void bevlist_firstlast_direction_calc_from_bpoint(Nurb *nu, BevList *bl) +{ + if (nu->pntsu > 1) { + BPoint *first_bp = nu->bp, *last_bp = nu->bp + (nu->pntsu - 1); + BevPoint *first_bevp, *last_bevp; - /* correct for the dir/quat, see above why its needed */ - bevel_list_cyclic_fix_3D(bl); + first_bevp = (BevPoint *)(bl + 1); + last_bevp = first_bevp + (bl->nr - 1); + + sub_v3_v3v3(first_bevp->dir, (first_bp + 1)->vec, first_bp->vec); + normalize_v3(first_bevp->dir); + + sub_v3_v3v3(last_bevp->dir, last_bp->vec, (last_bp - 1)->vec); + normalize_v3(last_bevp->dir); } } @@ -2353,6 +2511,10 @@ void BKE_curve_bevelList_make(Object *ob) bevp++; bp++; } + + if ((nu->flagu & CU_NURB_CYCLIC) == 0) { + bevlist_firstlast_direction_calc_from_bpoint(nu, bl); + } } else if (nu->type == CU_BEZIER) { /* in case last point is not cyclic */ @@ -2375,6 +2537,9 @@ void BKE_curve_bevelList_make(Object *ob) bezt++; } + sub_v3_v3v3(bevp->dir, prevbezt->vec[2], prevbezt->vec[1]); + normalize_v3(bevp->dir); + while (a--) { if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) { @@ -2436,6 +2601,10 @@ void BKE_curve_bevelList_make(Object *ob) bevp->alfa = prevbezt->alfa; bevp->radius = prevbezt->radius; bevp->weight = prevbezt->weight; + + sub_v3_v3v3(bevp->dir, prevbezt->vec[1], prevbezt->vec[0]); + normalize_v3(bevp->dir); + bl->nr++; } } @@ -2456,6 +2625,10 @@ void BKE_curve_bevelList_make(Object *ob) do_radius ? &bevp->radius : NULL, do_weight ? &bevp->weight : NULL, resolu, sizeof(BevPoint)); + + if ((nu->flagu & CU_NURB_CYCLIC) == 0) { + bevlist_firstlast_direction_calc_from_bpoint(nu, bl); + } } } } @@ -3646,7 +3819,7 @@ void BKE_curve_translate(Curve *cu, float offset[3], int do_keys) } } -void BKE_curve_delete_material_index(Curve *cu, int index) +void BKE_curve_material_index_remove(Curve *cu, int index) { const int curvetype = BKE_curve_type_get(cu); @@ -3665,8 +3838,32 @@ void BKE_curve_delete_material_index(Curve *cu, int index) for (nu = cu->nurb.first; nu; nu = nu->next) { if (nu->mat_nr && nu->mat_nr >= index) { nu->mat_nr--; - if (curvetype == OB_CURVE) + if (curvetype == OB_CURVE) { nu->charidx--; + } + } + } + } +} + +void BKE_curve_material_index_clear(Curve *cu) +{ + const int curvetype = BKE_curve_type_get(cu); + + if (curvetype == OB_FONT) { + struct CharInfo *info = cu->strinfo; + int i; + for (i = cu->len - 1; i >= 0; i--, info++) { + info->mat_nr = 0; + } + } + else { + Nurb *nu; + + for (nu = cu->nurb.first; nu; nu = nu->next) { + nu->mat_nr = 0; + if (curvetype == OB_CURVE) { + nu->charidx = 0; } } } diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 92b3c26c91a..d69ec6a9597 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -218,9 +218,16 @@ static void layerFree_bmesh_elem_py_ptr(void *data, int count, int size) static void layerInterp_mdeformvert(void **sources, const float *weights, const float *UNUSED(sub_weights), int count, void *dest) { + /* a single linked list of MDeformWeight's + * use this to avoid double allocs (which LinkNode would do) */ + struct MDeformWeight_Link { + struct MDeformWeight_Link *next; + MDeformWeight dw; + }; + MDeformVert *dvert = dest; - LinkNode *dest_dw = NULL; /* a list of lists of MDeformWeight pointers */ - LinkNode *node; + struct MDeformWeight_Link *dest_dwlink = NULL; + struct MDeformWeight_Link *node; int i, j, totweight; if (count <= 0) return; @@ -238,8 +245,8 @@ static void layerInterp_mdeformvert(void **sources, const float *weights, if (weight == 0.0f) continue; - for (node = dest_dw; node; node = node->next) { - MDeformWeight *tmp_dw = (MDeformWeight *)node->link; + for (node = dest_dwlink; node; node = node->next) { + MDeformWeight *tmp_dw = &node->dw; if (tmp_dw->def_nr == dw->def_nr) { tmp_dw->weight += weight; @@ -249,11 +256,14 @@ static void layerInterp_mdeformvert(void **sources, const float *weights, /* if this def_nr is not in the list, add it */ if (!node) { - MDeformWeight *tmp_dw = MEM_callocN(sizeof(*tmp_dw), - "layerInterp_mdeformvert tmp_dw"); - tmp_dw->def_nr = dw->def_nr; - tmp_dw->weight = weight; - BLI_linklist_prepend(&dest_dw, tmp_dw); + struct MDeformWeight_Link *tmp_dwlink = MEM_mallocN(sizeof(*tmp_dwlink), __func__); + tmp_dwlink->dw.def_nr = dw->def_nr; + tmp_dwlink->dw.weight = weight; + + /* inline linklist */ + tmp_dwlink->next = dest_dwlink; + dest_dwlink = tmp_dwlink; + totweight++; } } @@ -262,20 +272,31 @@ static void layerInterp_mdeformvert(void **sources, const float *weights, /* delay writing to the destination incase dest is in sources */ /* now we know how many unique deform weights there are, so realloc */ - if (dvert->dw) MEM_freeN(dvert->dw); + if (dvert->dw && (dvert->totweight == totweight)) { + /* pass (fastpath if we don't need to realloc) */ + } + else { + if (dvert->dw) { + MEM_freeN(dvert->dw); + } + + if (totweight) { + dvert->dw = MEM_mallocN(sizeof(*dvert->dw) * totweight, __func__); + } + } if (totweight) { - dvert->dw = MEM_mallocN(sizeof(*dvert->dw) * totweight, - "layerInterp_mdeformvert dvert->dw"); + struct MDeformWeight_Link *node_next; dvert->totweight = totweight; - - for (i = 0, node = dest_dw; node; node = node->next, ++i) - dvert->dw[i] = *((MDeformWeight *)node->link); + for (i = 0, node = dest_dwlink; node; node = node_next, i++) { + node_next = node->next; + dvert->dw[i] = node->dw; + MEM_freeN(node); + } } - else + else { memset(dvert, 0, sizeof(*dvert)); - - BLI_linklist_free(dest_dw, MEM_freeN); + } } static void layerCopy_tface(const void *source, void *dest, int count) diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 0dd9d8550bb..882085aa5db 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -537,7 +537,7 @@ void BKE_deform_split_suffix(const char string[MAX_VGROUP_NAME], char body[MAX_V body[0] = suf[0] = '\0'; - for (i = len - 1; i > 1; i--) { + for (i = len; i > 0; i--) { if (is_char_sep(string[i])) { BLI_strncpy(body, string, i + 1); BLI_strncpy(suf, string + i, (len + 1) - i); @@ -545,7 +545,7 @@ void BKE_deform_split_suffix(const char string[MAX_VGROUP_NAME], char body[MAX_V } } - BLI_strncpy(body, string, len); + memcpy(body, string, len + 1); } /* "a.b.c" -> ("a.", "b.c") */ diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 1d5eaf3a1fc..a62ca530bf9 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -1078,6 +1078,7 @@ DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSettings *c surface->wave_speed = 1.0f; surface->wave_timescale = 1.0f; surface->wave_spring = 0.20f; + surface->wave_smoothness = 1.0f; modifier_path_init(surface->image_output_path, sizeof(surface->image_output_path), "cache_dynamicpaint"); @@ -1253,6 +1254,7 @@ void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct Dyn t_surface->wave_speed = surface->wave_speed; t_surface->wave_timescale = surface->wave_timescale; t_surface->wave_spring = surface->wave_spring; + t_surface->wave_smoothness = surface->wave_smoothness; BLI_strncpy(t_surface->uvlayer_name, surface->uvlayer_name, sizeof(t_surface->uvlayer_name)); BLI_strncpy(t_surface->image_output_path, surface->image_output_path, sizeof(t_surface->image_output_path)); @@ -3288,7 +3290,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, if (!brush->dm) return 0; { - BVHTreeFromMesh treeData = {0}; + BVHTreeFromMesh treeData = {NULL}; float avg_brushNor[3] = {0.0f}; float brush_radius = brush->paint_distance * surface->radius_scale; int numOfVerts; @@ -4465,6 +4467,7 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal int steps, ss; float dt, min_dist, damp_factor; float wave_speed = surface->wave_speed; + float wave_max_slope = (surface->wave_smoothness >= 0.01f) ? (0.5f / surface->wave_smoothness) : 0.0f; double average_dist = 0.0f; const float canvas_size = getSurfaceDimension(sData); float wave_scale = CANVAS_REL_SIZE / canvas_size; @@ -4503,7 +4506,7 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal for (index = 0; index < sData->total_points; index++) { PaintWavePoint *wPoint = &((PaintWavePoint *)sData->type_data)[index]; int numOfNeighs = sData->adj_data->n_num[index]; - float force = 0.0f, avg_dist = 0.0f, avg_height = 0.0f; + float force = 0.0f, avg_dist = 0.0f, avg_height = 0.0f, avg_n_height = 0.0f; int numOfN = 0, numOfRN = 0; int i; @@ -4522,11 +4525,12 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal /* count average height for edge points for open borders */ if (!(sData->adj_data->flags[sData->adj_data->n_target[n_index]] & ADJ_ON_MESH_EDGE)) { - avg_height += tPoint->height; + avg_n_height += tPoint->height; numOfRN++; } force += (tPoint->height - wPoint->height) / (dist * dist); + avg_height += tPoint->height; } avg_dist = (numOfN) ? avg_dist / numOfN : 0.0f; @@ -4534,8 +4538,8 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal sData->adj_data->flags[index] & ADJ_ON_MESH_EDGE) { /* if open borders, apply a fake height to keep waves going on */ - avg_height = (numOfRN) ? avg_height / numOfRN : 0.0f; - wPoint->height = (dt * wave_speed * avg_height + wPoint->height * avg_dist) / (avg_dist + dt * wave_speed); + avg_n_height = (numOfRN) ? avg_n_height / numOfRN : 0.0f; + wPoint->height = (dt * wave_speed * avg_n_height + wPoint->height * avg_dist) / (avg_dist + dt * wave_speed); } /* else do wave eq */ else { @@ -4549,6 +4553,14 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal wPoint->velocity *= damp_factor; /* and new height */ wPoint->height += wPoint->velocity * dt; + + /* limit wave slope steepness */ + if (wave_max_slope && avg_dist) { + float max_offset = wave_max_slope * avg_dist; + float offset = (numOfN) ? (avg_height / numOfN - wPoint->height) : 0.0f; + if (offset > max_offset) wPoint->height += offset - max_offset; + if (offset < -max_offset) wPoint->height += offset + max_offset; + } } } } @@ -4965,7 +4977,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su /* make sure we're dealing with a brush */ if (pmd2->brush) { DynamicPaintBrushSettings *brush = pmd2->brush; - BrushMaterials bMats = {0}; + BrushMaterials bMats = {NULL}; /* calculate brush speed vectors if required */ if (surface->type == MOD_DPAINT_SURFACE_T_PAINT && brush->flags & MOD_DPAINT_DO_SMUDGE) { diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index ddd5e4a1e02..e8e56c6f17b 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -69,11 +69,120 @@ typedef struct EditDerivedBMesh { BMEditMesh *em; - float (*vertexCos)[3]; - float (*vertexNos)[3]; - float (*polyNos)[3]; + /** when set, \a vertexNos, polyNos are lazy initialized */ + const float (*vertexCos)[3]; + + /** lazy initialize (when \a vertexCos is set) */ + float const (*vertexNos)[3]; + float const (*polyNos)[3]; + /** also lazy init but dont depend on \a vertexCos */ + const float (*polyCos)[3]; } EditDerivedBMesh; +/* -------------------------------------------------------------------- */ +/* Lazy initialize datastructures */ + +static void emDM_ensurePolyNormals(EditDerivedBMesh *bmdm); + +static void emDM_ensureVertNormals(EditDerivedBMesh *bmdm) +{ + if (bmdm->vertexCos && (bmdm->vertexNos == NULL)) { + + BMesh *bm = bmdm->em->bm; + const float (*vertexCos)[3], (*polyNos)[3]; + float (*vertexNos)[3]; + + BMFace *efa; + BMVert *eve; + BMIter fiter; + BMIter viter; + int i; + + vertexCos = bmdm->vertexCos; + vertexNos = MEM_callocN(sizeof(*vertexNos) * bm->totvert, __func__); + + /* calculate vertex normals from poly normals */ + emDM_ensurePolyNormals(bmdm); + + BM_mesh_elem_index_ensure(bm, BM_FACE); + + vertexCos = bmdm->vertexCos; + polyNos = bmdm->polyNos; + + BM_ITER_MESH_INDEX (eve, &viter, bm, BM_VERTS_OF_MESH, i) { + float *no = vertexNos[i]; + BM_ITER_ELEM (efa, &fiter, eve, BM_FACES_OF_VERT) { + add_v3_v3(no, polyNos[BM_elem_index_get(efa)]); + } + + /* following Mesh convention; we use vertex coordinate itself + * for normal in this case */ + if (UNLIKELY(normalize_v3(no) == 0.0f)) { + normalize_v3_v3(no, vertexCos[i]); + } + } + + bmdm->vertexNos = (const float (*)[3])vertexNos; + } +} + +static void emDM_ensurePolyNormals(EditDerivedBMesh *bmdm) +{ + if (bmdm->vertexCos && (bmdm->polyNos == NULL)) { + BMesh *bm = bmdm->em->bm; + const float (*vertexCos)[3]; + float (*polyNos)[3]; + + BMFace *efa; + BMIter fiter; + int i; + + BM_mesh_elem_index_ensure(bm, BM_VERT); + + polyNos = MEM_mallocN(sizeof(*polyNos) * bm->totface, __func__); + + vertexCos = bmdm->vertexCos; + + BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) { + BM_elem_index_set(efa, i); /* set_inline */ + BM_face_calc_normal_vcos(bm, efa, polyNos[i], vertexCos); + } + bm->elem_index_dirty &= ~BM_FACE; + + bmdm->polyNos = (const float (*)[3])polyNos; + } +} + +static void emDM_ensurePolyCenters(EditDerivedBMesh *bmdm) +{ + if (bmdm->polyCos == NULL) { + BMesh *bm = bmdm->em->bm; + float (*polyCos)[3]; + + BMFace *efa; + BMIter fiter; + int i; + + polyCos = MEM_mallocN(sizeof(*polyCos) * bm->totface, __func__); + + if (bmdm->vertexCos) { + const float (*vertexCos)[3]; + vertexCos = bmdm->vertexCos; + + BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) { + BM_face_calc_center_mean_vcos(bm, efa, polyCos[i], vertexCos); + } + } + else { + BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) { + BM_face_calc_center_mean(efa, polyCos[i]); + } + } + + bmdm->polyCos = (const float (*)[3])polyCos; + } +} + static void emDM_calcNormals(DerivedMesh *dm) { /* Nothing to do: normals are already calculated and stored on the @@ -86,9 +195,11 @@ static void emDM_recalcTessellation(DerivedMesh *UNUSED(dm)) /* do nothing */ } -static void emDM_foreachMappedVert(DerivedMesh *dm, - void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]), - void *userData) +static void emDM_foreachMappedVert( + DerivedMesh *dm, + void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]), + void *userData, + DMForeachFlag flag) { EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; BMesh *bm = bmdm->em->bm; @@ -97,13 +208,26 @@ static void emDM_foreachMappedVert(DerivedMesh *dm, int i; if (bmdm->vertexCos) { + const float (*vertexCos)[3] = bmdm->vertexCos; + const float (*vertexNos)[3]; + + if (flag & DM_FOREACH_USE_NORMAL) { + emDM_ensureVertNormals(bmdm); + vertexNos = bmdm->vertexNos; + } + else { + vertexNos = NULL; + } + BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { - func(userData, i, bmdm->vertexCos[i], bmdm->vertexNos[i], NULL); + const float *no = (flag & DM_FOREACH_USE_NORMAL) ? vertexNos[i] : NULL; + func(userData, i, vertexCos[i], no, NULL); } } else { BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { - func(userData, i, eve->co, eve->no, NULL); + const float *no = (flag & DM_FOREACH_USE_NORMAL) ? eve->no : NULL; + func(userData, i, eve->co, no, NULL); } } } @@ -248,56 +372,42 @@ static void emDM_drawUVEdges(DerivedMesh *dm) glEnd(); } -static void emDM__calcFaceCent(BMFace *efa, float cent[3], float (*vertexCos)[3]) -{ - BMIter liter; - BMLoop *l; - int tot = 0; - - zero_v3(cent); - - /*simple (and stupid) median (average) based method :/ */ - - if (vertexCos) { - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - add_v3_v3(cent, vertexCos[BM_elem_index_get(l->v)]); - tot++; - } - } - else { - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - add_v3_v3(cent, l->v->co); - tot++; - } - } - - if (tot == 0) return; - mul_v3_fl(cent, 1.0f / (float)tot); -} - -static void emDM_foreachMappedFaceCenter(DerivedMesh *dm, - void (*func)(void *userData, int index, const float co[3], const float no[3]), - void *userData) +static void emDM_foreachMappedFaceCenter( + DerivedMesh *dm, + void (*func)(void *userData, int index, const float co[3], const float no[3]), + void *userData, + DMForeachFlag flag) { EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; BMesh *bm = bmdm->em->bm; - float (*polyNos)[3] = NULL; + const float (*polyNos)[3]; + const float (*polyCos)[3]; BMFace *efa; BMIter iter; - float cent[3]; int i; - /* ensure for face center calculation */ - if (bmdm->vertexCos) { - BM_mesh_elem_index_ensure(bm, BM_VERT); - polyNos = bmdm->polyNos; + emDM_ensurePolyCenters(bmdm); + polyCos = bmdm->polyCos; /* always set */ - BLI_assert(polyNos != NULL); + if (flag & DM_FOREACH_USE_NORMAL) { + emDM_ensurePolyNormals(bmdm); + polyNos = bmdm->polyNos; /* maybe NULL */ + } + else { + polyNos = NULL; } - BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { - emDM__calcFaceCent(efa, cent, bmdm->vertexCos); - func(userData, i, cent, polyNos ? polyNos[i] : efa->no); + if (polyNos) { + BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { + const float *no = polyNos[i]; + func(userData, i, polyCos[i], no); + } + } + else { + BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { + const float *no = (flag & DM_FOREACH_USE_NORMAL) ? efa->no : NULL; + func(userData, i, polyCos[i], no); + } } } @@ -349,10 +459,20 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, if (bmdm->vertexCos) { /* add direct access */ - float (*vertexCos)[3] = bmdm->vertexCos; - float (*vertexNos)[3] = bmdm->vertexNos; - float (*polyNos)[3] = bmdm->polyNos; - // int *triPolyMap = bmdm->triPolyMap; + const float (*vertexCos)[3] = bmdm->vertexCos; + const float (*vertexNos)[3]; + const float (*polyNos)[3]; + + if (skip_normals) { + vertexNos = NULL; + polyNos = NULL; + } + else { + emDM_ensureVertNormals(bmdm); + emDM_ensurePolyNormals(bmdm); + vertexNos = bmdm->vertexNos; + polyNos = bmdm->polyNos; + } BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE); @@ -561,9 +681,6 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, BMEditMesh *em = bmdm->em; BMesh *bm = em->bm; struct BMLoop *(*looptris)[3] = em->looptris; - float (*vertexCos)[3] = bmdm->vertexCos; - float (*vertexNos)[3] = bmdm->vertexNos; - float (*polyNos)[3] = bmdm->polyNos; BMFace *efa; MLoopUV *luv[3], dummyluv = {{0}}; MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */; @@ -593,7 +710,17 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, BM_mesh_elem_index_ensure(bm, BM_VERT); } - if (vertexCos) { + if (bmdm->vertexCos) { + /* add direct access */ + const float (*vertexCos)[3] = bmdm->vertexCos; + const float (*vertexNos)[3]; + const float (*polyNos)[3]; + + emDM_ensureVertNormals(bmdm); + emDM_ensurePolyNormals(bmdm); + vertexNos = bmdm->vertexNos; + polyNos = bmdm->polyNos; + BM_mesh_elem_index_ensure(bm, BM_VERT); for (i = 0; i < em->tottri; i++) { @@ -791,9 +918,11 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm, BMEditMesh *em = bmdm->em; BMesh *bm = em->bm; struct BMLoop *(*looptris)[3] = em->looptris; - float (*vertexCos)[3] = bmdm->vertexCos; - float (*vertexNos)[3] = bmdm->vertexNos; - float (*polyNos)[3] = bmdm->polyNos; + /* add direct access */ + const float (*vertexCos)[3] = bmdm->vertexCos; + const float (*vertexNos)[3]; + const float (*polyNos)[3]; + BMFace *efa; DMVertexAttribs attribs; GPUVertexAttribs gattribs; @@ -805,6 +934,11 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm, memset(&attribs, 0, sizeof(attribs)); + emDM_ensureVertNormals(bmdm); + emDM_ensurePolyNormals(bmdm); + vertexNos = bmdm->vertexNos; + polyNos = bmdm->polyNos; + /* always use smooth shading even for flat faces, else vertex colors wont interpolate */ glShadeModel(GL_SMOOTH); BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE); @@ -926,16 +1060,22 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm, BMEditMesh *em = bmdm->em; BMesh *bm = em->bm; struct BMLoop *(*looptris)[3] = em->looptris; - float (*vertexCos)[3] = bmdm->vertexCos; - float (*vertexNos)[3] = bmdm->vertexNos; - float (*polyNos)[3] = bmdm->polyNos; + const float (*vertexCos)[3] = bmdm->vertexCos; + const float (*vertexNos)[3]; + const float (*polyNos)[3]; BMFace *efa; - DMVertexAttribs attribs = {{{0}}}; + DMVertexAttribs attribs = {{{NULL}}}; GPUVertexAttribs gattribs; int i, matnr, new_matnr; matnr = -1; + emDM_ensureVertNormals(bmdm); + emDM_ensurePolyNormals(bmdm); + + vertexNos = bmdm->vertexNos; + polyNos = bmdm->polyNos; + /* always use smooth shading even for flat faces, else vertex colors wont interpolate */ glShadeModel(GL_SMOOTH); @@ -1139,7 +1279,9 @@ static void emDM_getVertNo(DerivedMesh *dm, int index, float r_no[3]) return; } - if (bmdm->vertexNos) { + + if (bmdm->vertexCos) { + emDM_ensureVertNormals(bmdm); copy_v3_v3(r_no, bmdm->vertexNos[index]); } else { @@ -1159,7 +1301,8 @@ static void emDM_getPolyNo(DerivedMesh *dm, int index, float r_no[3]) return; } - if (bmdm->polyNos) { + if (bmdm->vertexCos) { + emDM_ensurePolyNormals(bmdm); copy_v3_v3(r_no, bmdm->polyNos[index]); } else { @@ -1313,18 +1456,19 @@ static void emDM_copyLoopArray(DerivedMesh *dm, MLoop *r_loop) { EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; BMesh *bm = bmdm->em->bm; - BMIter iter, liter; + BMIter iter; BMFace *efa; - BMLoop *l; BM_mesh_elem_index_ensure(bm, BM_VERT | BM_EDGE); BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - r_loop->v = BM_elem_index_get(l->v); - r_loop->e = BM_elem_index_get(l->e); + BMLoop *l_iter, *l_first; + l_iter = l_first = BM_FACE_FIRST_LOOP(efa); + do { + r_loop->v = BM_elem_index_get(l_iter->v); + r_loop->e = BM_elem_index_get(l_iter->e); r_loop++; - } + } while ((l_iter = l_iter->next) != l_first); } } @@ -1438,9 +1582,17 @@ static void emDM_release(DerivedMesh *dm) if (DM_release(dm)) { if (bmdm->vertexCos) { - MEM_freeN(bmdm->vertexCos); - MEM_freeN(bmdm->vertexNos); - MEM_freeN(bmdm->polyNos); + MEM_freeN((void *)bmdm->vertexCos); + if (bmdm->vertexNos) { + MEM_freeN((void *)bmdm->vertexNos); + } + if (bmdm->polyNos) { + MEM_freeN((void *)bmdm->polyNos); + } + } + + if (bmdm->polyCos) { + MEM_freeN((void *)bmdm->polyCos); } MEM_freeN(bmdm); @@ -1549,7 +1701,7 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, bmdm->dm.release = emDM_release; - bmdm->vertexCos = vertexCos; + bmdm->vertexCos = (const float (*)[3])vertexCos; bmdm->dm.deformedOnly = (vertexCos != NULL); if (cd_dvert_offset != -1) { @@ -1578,38 +1730,6 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, } } - if (vertexCos) { - BMFace *efa; - BMVert *eve; - BMIter fiter; - BMIter viter; - int i; - - BM_mesh_elem_index_ensure(bm, BM_VERT); - - bmdm->vertexNos = MEM_callocN(sizeof(*bmdm->vertexNos) * bm->totvert, "bmdm_vno"); - bmdm->polyNos = MEM_mallocN(sizeof(*bmdm->polyNos) * bm->totface, "bmdm_pno"); - - BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) { - BM_elem_index_set(efa, i); /* set_inline */ - BM_face_normal_update_vcos(bm, efa, bmdm->polyNos[i], (float const (*)[3])vertexCos); - } - bm->elem_index_dirty &= ~BM_FACE; - - BM_ITER_MESH_INDEX (eve, &viter, bm, BM_VERTS_OF_MESH, i) { - float *no = bmdm->vertexNos[i]; - BM_ITER_ELEM (efa, &fiter, eve, BM_FACES_OF_VERT) { - add_v3_v3(no, bmdm->polyNos[BM_elem_index_get(efa)]); - } - - /* following Mesh convention; we use vertex coordinate itself - * for normal in this case */ - if (UNLIKELY(normalize_v3(no) == 0.0f)) { - normalize_v3_v3(no, vertexCos[i]); - } - } - } - return (DerivedMesh *)bmdm; } @@ -1877,7 +1997,7 @@ static void statvis_calc_intersect( static void statvis_calc_distort( BMEditMesh *em, - const float (*vertexCos)[3], + const float (*vertexCos)[3], const float (*polyNos)[3], /* values for calculating */ const float min, const float max, /* result */ @@ -1886,7 +2006,7 @@ static void statvis_calc_distort( BMIter iter; BMesh *bm = em->bm; BMFace *f; - float f_no[3]; + const float *f_no; int index; const float minmax_irange = 1.0f / (max - min); @@ -1903,10 +2023,10 @@ static void statvis_calc_distort( else { BMLoop *l_iter, *l_first; if (vertexCos) { - BM_face_normal_update_vcos(bm, f, f_no, vertexCos); + f_no = polyNos[index]; } else { - copy_v3_v3(f_no, f->no); + f_no = f->no; } fac = 0.0f; @@ -2006,7 +2126,7 @@ void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm, { BKE_editmesh_color_ensure(em, BM_FACE); statvis_calc_overhang( - em, bmdm ? (const float (*)[3])bmdm->polyNos : NULL, + em, bmdm ? bmdm->polyNos : NULL, statvis->overhang_min / (float)M_PI, statvis->overhang_max / (float)M_PI, statvis->overhang_axis, @@ -2018,7 +2138,7 @@ void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm, const float scale = 1.0f / mat4_to_scale(em->ob->obmat); BKE_editmesh_color_ensure(em, BM_FACE); statvis_calc_thickness( - em, bmdm ? (const float (*)[3])bmdm->vertexCos : NULL, + em, bmdm ? bmdm->vertexCos : NULL, statvis->thickness_min * scale, statvis->thickness_max * scale, statvis->thickness_samples, @@ -2029,15 +2149,19 @@ void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm, { BKE_editmesh_color_ensure(em, BM_FACE); statvis_calc_intersect( - em, bmdm ? (const float (*)[3])bmdm->vertexCos : NULL, + em, bmdm ? bmdm->vertexCos : NULL, em->derivedFaceColor); break; } case SCE_STATVIS_DISTORT: { BKE_editmesh_color_ensure(em, BM_FACE); + + if (bmdm) + emDM_ensurePolyNormals(bmdm); + statvis_calc_distort( - em, bmdm ? (const float (*)[3])bmdm->vertexCos : NULL, + em, bmdm ? bmdm->vertexCos : NULL, bmdm ? bmdm->polyNos : NULL, statvis->distort_min, statvis->distort_max, em->derivedFaceColor); @@ -2047,7 +2171,7 @@ void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm, { BKE_editmesh_color_ensure(em, BM_VERT); statvis_calc_sharp( - em, bmdm ? (const float (*)[3])bmdm->vertexCos : NULL, + em, bmdm ? bmdm->vertexCos : NULL, statvis->sharp_min, statvis->sharp_max, /* in this case they are vertex colors */ @@ -2065,7 +2189,7 @@ void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm, struct CageUserData { int totvert; float (*cos_cage)[3]; - BLI_bitmap visit_bitmap; + BLI_bitmap *visit_bitmap; }; static void cage_mapped_verts_callback(void *userData, int index, const float co[3], @@ -2082,7 +2206,7 @@ static void cage_mapped_verts_callback(void *userData, int index, const float co float (*BKE_editmesh_vertexCos_get(BMEditMesh *em, Scene *scene, int *r_numVerts))[3] { DerivedMesh *cage, *final; - BLI_bitmap visit_bitmap; + BLI_bitmap *visit_bitmap; struct CageUserData data; float (*cos_cage)[3]; @@ -2097,7 +2221,7 @@ float (*BKE_editmesh_vertexCos_get(BMEditMesh *em, Scene *scene, int *r_numVerts data.cos_cage = cos_cage; data.visit_bitmap = visit_bitmap; - cage->foreachMappedVert(cage, cage_mapped_verts_callback, &data); + cage->foreachMappedVert(cage, cage_mapped_verts_callback, &data, DM_FOREACH_NOP); MEM_freeN(visit_bitmap); diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index 915c75a0e7f..f24edfea136 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -144,12 +144,8 @@ static void fcm_generator_verify(FModifier *fcm) const int arraysize_new = data->poly_order + 1; /* arraysize needs to be order+1, so resize if not */ if (data->arraysize != arraysize_new) { - if (data->coefficients) { - data->coefficients = MEM_recallocN(data->coefficients, sizeof(float) * arraysize_new); - } - else { - data->coefficients = MEM_callocN(sizeof(float) * arraysize_new, "FMod_Generator_Coefs"); - } + data->coefficients = MEM_recallocN(data->coefficients, + sizeof(float) * arraysize_new); data->arraysize = arraysize_new; } break; @@ -159,12 +155,8 @@ static void fcm_generator_verify(FModifier *fcm) const int arraysize_new = data->poly_order * 2; /* arraysize needs to be (2 * order), so resize if not */ if (data->arraysize != arraysize_new) { - if (data->coefficients) { - data->coefficients = MEM_recallocN(data->coefficients, sizeof(float) * arraysize_new); - } - else { - data->coefficients = MEM_callocN(sizeof(float) * arraysize_new, "FMod_Generator_Coefs"); - } + data->coefficients = MEM_recallocN(data->coefficients, + sizeof(float) * arraysize_new); data->arraysize = arraysize_new; } break; diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 1a444d497a0..86382c64ed3 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -597,7 +597,8 @@ Image *BKE_image_load(Main *bmain, const char *filepath) /* exists? */ file = BLI_open(str, O_BINARY | O_RDONLY, 0); - if (file == -1) return NULL; + if (file < 0) + return NULL; close(file); /* create a short library name */ @@ -652,7 +653,7 @@ Image *BKE_image_load_exists(const char *filepath) } static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, - float color[4], ColorManagedColorspaceSettings *colorspace_settings) + const float color[4], ColorManagedColorspaceSettings *colorspace_settings) { ImBuf *ibuf; unsigned char *rect = NULL; @@ -709,7 +710,7 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char } /* adds new image block, creates ImBuf and initializes color */ -Image *BKE_image_add_generated(Main *bmain, unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, float color[4]) +Image *BKE_image_add_generated(Main *bmain, unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, const float color[4]) { /* on save, type is changed to FILE in editsima.c */ Image *ima = image_alloc(bmain, name, IMA_SRC_GENERATED, IMA_TYPE_UV_TEST); @@ -722,6 +723,7 @@ Image *BKE_image_add_generated(Main *bmain, unsigned int width, unsigned int hei ima->gen_y = height; ima->gen_type = gen_type; ima->gen_flag |= (floatbuf ? IMA_GEN_FLOAT : 0); + ima->gen_depth = depth; ibuf = add_ibuf_size(width, height, ima->name, depth, floatbuf, gen_type, color, &ima->colorspace_settings); image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); @@ -2995,7 +2997,8 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r) /* UV testgrid or black or solid etc */ if (ima->gen_x == 0) ima->gen_x = 1024; if (ima->gen_y == 0) ima->gen_y = 1024; - ibuf = add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 24, (ima->gen_flag & IMA_GEN_FLOAT) != 0, ima->gen_type, + if (ima->gen_depth == 0) ima->gen_depth = 24; + ibuf = add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, ima->gen_depth, (ima->gen_flag & IMA_GEN_FLOAT) != 0, ima->gen_type, color, &ima->colorspace_settings); image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); ima->ok = IMA_OK_LOADED; diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c index eda22a095ef..71b4f9947a4 100644 --- a/source/blender/blenkernel/intern/image_gen.c +++ b/source/blender/blenkernel/intern/image_gen.c @@ -336,7 +336,7 @@ static void checker_board_text(unsigned char *rect, float *rect_float, int width } /* cleanup the buffer. */ - BLF_buffer(mono, NULL, NULL, 0, 0, 0, FALSE); + BLF_buffer(mono, NULL, NULL, 0, 0, 0, NULL); } void BKE_image_buf_fill_checker_color(unsigned char *rect, float *rect_float, int width, int height) diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index a79fa3873f5..d2d2cb1c2d0 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -190,7 +190,8 @@ Key *BKE_key_copy_nolib(Key *key) Key *keyn; KeyBlock *kbn, *kb; - if (key == 0) return 0; + if (key == NULL) + return NULL; keyn = MEM_dupallocN(key); @@ -533,7 +534,7 @@ static char *key_block_get_data(Key *key, KeyBlock *actkb, KeyBlock *kb, char ** if (me->edit_btmesh && me->edit_btmesh->bm->totvert == kb->totelem) { a = 0; - co = MEM_callocN(sizeof(float) * 3 * me->edit_btmesh->bm->totvert, "key_block_get_data"); + co = MEM_mallocN(sizeof(float) * 3 * me->edit_btmesh->bm->totvert, "key_block_get_data"); BM_ITER_MESH (eve, &iter, me->edit_btmesh->bm, BM_VERTS_OF_MESH) { copy_v3_v3(co[a], eve->co); @@ -1091,7 +1092,7 @@ static float *get_weights_array(Object *ob, char *vgroup) float *weights; int i; - weights = MEM_callocN(totvert * sizeof(float), "weights"); + weights = MEM_mallocN(totvert * sizeof(float), "weights"); if (em) { const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); @@ -1622,7 +1623,7 @@ void BKE_key_convert_from_lattice(Lattice *lt, KeyBlock *kb) if (kb->data) MEM_freeN(kb->data); - kb->data = MEM_callocN(lt->key->elemsize * tot, "kb->data"); + kb->data = MEM_mallocN(lt->key->elemsize * tot, "kb->data"); kb->totelem = tot; bp = lt->def; @@ -1664,7 +1665,7 @@ void BKE_key_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb) if (kb->data) MEM_freeN(kb->data); - kb->data = MEM_callocN(cu->key->elemsize * tot, "kb->data"); + kb->data = MEM_mallocN(cu->key->elemsize * tot, "kb->data"); kb->totelem = tot; nu = nurb->first; @@ -1762,7 +1763,7 @@ void BKE_key_convert_from_mesh(Mesh *me, KeyBlock *kb) if (kb->data) MEM_freeN(kb->data); - kb->data = MEM_callocN(me->key->elemsize * me->totvert, "kb->data"); + kb->data = MEM_mallocN(me->key->elemsize * me->totvert, "kb->data"); kb->totelem = me->totvert; mvert = me->mvert; @@ -1812,7 +1813,7 @@ float (*BKE_key_convert_to_vertcos(Object *ob, KeyBlock *kb))[3] if (tot == 0) return NULL; - vertCos = MEM_callocN(tot * sizeof(*vertCos), "BKE_key_convert_to_vertcos vertCos"); + vertCos = MEM_mallocN(tot * sizeof(*vertCos), "BKE_key_convert_to_vertcos vertCos"); /* Copy coords to array */ co = (float *)vertCos; @@ -1895,7 +1896,7 @@ void BKE_key_convert_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3]) return; } - fp = kb->data = MEM_callocN(tot * elemsize, "BKE_key_convert_to_vertcos vertCos"); + fp = kb->data = MEM_mallocN(tot * elemsize, "BKE_key_convert_to_vertcos vertCos"); /* Copy coords to keyblock */ diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 7eb4a3a2a8d..c23fa097d3e 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -1264,17 +1264,13 @@ static ID *is_dupid(ListBase *lb, ID *id, const char *name) static bool check_for_dupid(ListBase *lb, ID *id, char *name) { ID *idtest; - int nr = 0, nrtest, a, left_len; + int nr = 0, a, left_len; #define MAX_IN_USE 64 bool in_use[MAX_IN_USE]; /* to speed up finding unused numbers within [1 .. MAX_IN_USE - 1] */ char left[MAX_ID_NAME + 8], leftest[MAX_ID_NAME + 8]; - /* make sure input name is terminated properly */ - /* if ( strlen(name) > MAX_ID_NAME-3 ) name[MAX_ID_NAME-3] = 0; */ - /* removed since this is only ever called from one place - campbell */ - while (true) { /* phase 1: id already exists? */ @@ -1301,6 +1297,7 @@ static bool check_for_dupid(ListBase *lb, ID *id, char *name) } for (idtest = lb->first; idtest; idtest = idtest->next) { + int nrtest; if ( (id != idtest) && (idtest->lib == NULL) && (*name == *(idtest->name + 2)) && @@ -1315,8 +1312,8 @@ static bool check_for_dupid(ListBase *lb, ID *id, char *name) nr = nrtest + 1; /* track largest unused */ } } - /* At this point, nr will be at least 1. */ - BLI_assert(nr >= 1); + /* At this point, 'nr' will typically be at least 1. (but not always) */ + // BLI_assert(nr >= 1); /* decide which value of nr to use */ for (a = 0; a < MAX_IN_USE; a++) { diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index b3c5ceefb2d..e3f30bad5cf 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -602,7 +602,7 @@ float BKE_mask_point_weight(MaskSpline *spline, MaskSplinePoint *point, const fl float cur_u = 0.0f, cur_w = 0.0f, next_u = 0.0f, next_w = 0.0f, fac; /* Quite warnings */ int i; - for (i = 0; i < point->tot_uw + 1; i++) { + for (i = 0; i <= point->tot_uw; i++) { if (i == 0) { cur_u = 0.0f; @@ -939,8 +939,6 @@ void BKE_mask_free(Main *bmain, Mask *mask) SpaceLink *sl; Scene *scene; - BKE_sequencer_clear_mask_in_clipboard(mask); - for (scr = bmain->screen.first; scr; scr = scr->id.next) { for (area = scr->areabase.first; area; area = area->next) { for (sl = area->spacedata.first; sl; sl = sl->next) { diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index e14b51975c8..1bda662a8b0 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -537,17 +537,17 @@ short *give_totcolp_id(ID *id) return NULL; } -static void data_delete_material_index_id(ID *id, short index) +static void material_data_index_remove_id(ID *id, short index) { /* ensure we don't try get materials from non-obdata */ BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name))); switch (GS(id->name)) { case ID_ME: - BKE_mesh_delete_material_index((Mesh *)id, index); + BKE_mesh_material_index_remove((Mesh *)id, index); break; case ID_CU: - BKE_curve_delete_material_index((Curve *)id, index); + BKE_curve_material_index_remove((Curve *)id, index); break; case ID_MB: /* meta-elems don't have materials atm */ @@ -555,7 +555,25 @@ static void data_delete_material_index_id(ID *id, short index) } } -void material_append_id(ID *id, Material *ma) +static void material_data_index_clear_id(ID *id) +{ + /* ensure we don't try get materials from non-obdata */ + BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name))); + + switch (GS(id->name)) { + case ID_ME: + BKE_mesh_material_index_clear((Mesh *)id); + break; + case ID_CU: + BKE_curve_material_index_clear((Curve *)id); + break; + case ID_MB: + /* meta-elems don't have materials atm */ + break; + } +} + +void BKE_material_append_id(ID *id, Material *ma) { Material ***matar; if ((matar = give_matarar_id(id))) { @@ -572,7 +590,7 @@ void material_append_id(ID *id, Material *ma) } } -Material *material_pop_id(ID *id, int index_i, int remove_material_slot) +Material *BKE_material_pop_id(ID *id, int index_i, bool update_data) { short index = (short)index_i; Material *ret = NULL; @@ -583,40 +601,48 @@ Material *material_pop_id(ID *id, int index_i, int remove_material_slot) ret = (*matar)[index]; id_us_min((ID *)ret); - if (remove_material_slot) { - if (*totcol <= 1) { - *totcol = 0; - MEM_freeN(*matar); - *matar = NULL; - } - else { - Material **mat; - if (index + 1 != (*totcol)) - memmove((*matar) + index, (*matar) + (index + 1), sizeof(void *) * ((*totcol) - (index + 1))); - - (*totcol)--; - - mat = MEM_callocN(sizeof(void *) * (*totcol), "newmatar"); - memcpy(mat, *matar, sizeof(void *) * (*totcol)); - MEM_freeN(*matar); - - *matar = mat; - test_object_materials(G.main, id); - } + if (*totcol <= 1) { + *totcol = 0; + MEM_freeN(*matar); + *matar = NULL; + } + else { + if (index + 1 != (*totcol)) + memmove((*matar) + index, (*matar) + (index + 1), sizeof(void *) * ((*totcol) - (index + 1))); - /* decrease mat_nr index */ - data_delete_material_index_id(id, index); + (*totcol)--; + *matar = MEM_reallocN(*matar, sizeof(void *) * (*totcol)); + test_object_materials(G.main, id); } - /* don't remove material slot, only clear it*/ - else - (*matar)[index] = NULL; + if (update_data) { + /* decrease mat_nr index */ + material_data_index_remove_id(id, index); + } } } return ret; } +void BKE_material_clear_id(struct ID *id, bool update_data) +{ + Material ***matar; + if ((matar = give_matarar_id(id))) { + short *totcol = give_totcolp_id(id); + *totcol = 0; + if (*matar) { + MEM_freeN(*matar); + *matar = NULL; + } + + if (update_data) { + /* decrease mat_nr index */ + material_data_index_clear_id(id); + } + } +} + Material *give_current_material(Object *ob, short act) { Material ***matarar, *ma; @@ -1148,55 +1174,6 @@ void material_drivers_update(Scene *scene, Material *ma, float ctime) ma->id.flag &= ~LIB_DOIT; } - -/* ****************** */ -#if 0 /* UNUSED */ -static char colname_array[125][20] = { -"Black", "DarkRed", "HalfRed", "Red", "Red", -"DarkGreen", "DarkOlive", "Brown", "Chocolate", "OrangeRed", -"HalfGreen", "GreenOlive", "DryOlive", "Goldenrod", "DarkOrange", -"LightGreen", "Chartreuse", "YellowGreen", "Yellow", "Gold", -"Green", "LawnGreen", "GreenYellow", "LightOlive", "Yellow", -"DarkBlue", "DarkPurple", "HotPink", "VioletPink", "RedPink", -"SlateGray", "DarkGray", "PalePurple", "IndianRed", "Tomato", -"SeaGreen", "PaleGreen", "GreenKhaki", "LightBrown", "LightSalmon", -"SpringGreen", "PaleGreen", "MediumOlive", "YellowBrown", "LightGold", -"LightGreen", "LightGreen", "LightGreen", "GreenYellow", "PaleYellow", -"HalfBlue", "DarkSky", "HalfMagenta", "VioletRed", "DeepPink", -"SteelBlue", "SkyBlue", "Orchid", "LightHotPink", "HotPink", -"SeaGreen", "SlateGray", "MediumGray", "Burlywood", "LightPink", -"SpringGreen", "Aquamarine", "PaleGreen", "Khaki", "PaleOrange", -"SpringGreen", "SeaGreen", "PaleGreen", "PaleWhite", "YellowWhite", -"LightBlue", "Purple", "MediumOrchid", "Magenta", "Magenta", -"RoyalBlue", "SlateBlue", "MediumOrchid", "Orchid", "Magenta", -"DeepSkyBlue", "LightSteelBlue", "LightSkyBlue", "Violet", "LightPink", -"Cyan", "DarkTurquoise", "SkyBlue", "Gray", "Snow", -"Mint", "Mint", "Aquamarine", "MintCream", "Ivory", -"Blue", "Blue", "DarkMagenta", "DarkOrchid", "Magenta", -"SkyBlue", "RoyalBlue", "LightSlateBlue", "MediumOrchid", "Magenta", -"DodgerBlue", "SteelBlue", "MediumPurple", "PalePurple", "Plum", -"DeepSkyBlue", "PaleBlue", "LightSkyBlue", "PalePurple", "Thistle", -"Cyan", "ColdBlue", "PaleTurquoise", "GhostWhite", "White" -}; - -void automatname(Material *ma) -{ - int nr, r, g, b; - float ref; - - if (ma == NULL) return; - if (ma->mode & MA_SHLESS) ref = 1.0; - else ref = ma->ref; - - r = (int)(4.99f * (ref * ma->r)); - g = (int)(4.99f * (ref * ma->g)); - b = (int)(4.99f * (ref * ma->b)); - nr = r + 5 * g + 25 * b; - if (nr > 124) nr = 124; - new_id(&G.main->mat, (ID *)ma, colname_array[nr]); - -} -#endif int object_remove_material_slot(Object *ob) { @@ -1225,7 +1202,9 @@ int object_remove_material_slot(Object *ob) totcolp = give_totcolp(ob); matarar = give_matarar(ob); - if (*matarar == NULL) return FALSE; + if (ELEM(NULL, matarar, *matarar)) { + return false; + } /* can happen on face selection in editmode */ if (ob->actcol > ob->totcol) { @@ -1274,7 +1253,7 @@ int object_remove_material_slot(Object *ob) /* check indices from mesh */ if (ELEM4(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) { - data_delete_material_index_id((ID *)ob->data, actcol - 1); + material_data_index_remove_id((ID *)ob->data, actcol - 1); BKE_displist_free(&ob->disp); } @@ -1750,7 +1729,7 @@ static short mesh_getmaterialnumber(Mesh *me, Material *ma) /* append material */ static short mesh_addmaterial(Mesh *me, Material *ma) { - material_append_id(&me->id, NULL); + BKE_material_append_id(&me->id, NULL); me->mat[me->totcol - 1] = ma; id_us_plus(&ma->id); @@ -1887,8 +1866,14 @@ static void convert_tfacematerial(Main *main, Material *ma) mf->mat_nr = mat_nr; } /* remove material from mesh */ - for (a = 0; a < me->totcol; ) - if (me->mat[a] == ma) material_pop_id(&me->id, a, 1); else a++; + for (a = 0; a < me->totcol; ) { + if (me->mat[a] == ma) { + BKE_material_pop_id(&me->id, a, true); + } + else { + a++; + } + } } } diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 439965420f7..0db1f92f70f 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -51,6 +51,7 @@ #include "BLI_bitmap.h" #include "BLI_scanfill.h" #include "BLI_array.h" +#include "BLI_alloca.h" #include "BKE_animsys.h" #include "BKE_main.h" @@ -1851,20 +1852,37 @@ void BKE_mesh_to_curve(Scene *scene, Object *ob) } } -void BKE_mesh_delete_material_index(Mesh *me, short index) +void BKE_mesh_material_index_remove(Mesh *me, short index) { + MPoly *mp; + MFace *mf; int i; - for (i = 0; i < me->totpoly; i++) { - MPoly *mp = &((MPoly *) me->mpoly)[i]; - if (mp->mat_nr && mp->mat_nr >= index) + for (mp = me->mpoly, i = 0; i < me->totpoly; i++, mp++) { + if (mp->mat_nr && mp->mat_nr >= index) { mp->mat_nr--; + } } - - for (i = 0; i < me->totface; i++) { - MFace *mf = &((MFace *) me->mface)[i]; - if (mf->mat_nr && mf->mat_nr >= index) + + for (mf = me->mface, i = 0; i < me->totface; i++, mf++) { + if (mf->mat_nr && mf->mat_nr >= index) { mf->mat_nr--; + } + } +} + +void BKE_mesh_material_index_clear(Mesh *me) +{ + MPoly *mp; + MFace *mf; + int i; + + for (mp = me->mpoly, i = 0; i < me->totpoly; i++, mp++) { + mp->mat_nr = 0; + } + + for (mf = me->mface, i = 0; i < me->totface; i++, mf++) { + mf->mat_nr = 0; } } diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index 878651cdb39..2eced15a147 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -294,7 +294,7 @@ int BKE_mesh_validate_arrays(Mesh *mesh, # define CHECK_FACE_EDGE(a, b) \ if (!BLI_edgehash_haskey(edge_hash, mf->a, mf->b)) { \ PRINT(" face %u: edge " STRINGIFY(a) "/" STRINGIFY(b) \ - " (%u,%u) is missing egde data\n", i, mf->a, mf->b); \ + " (%u,%u) is missing edge data\n", i, mf->a, mf->b); \ do_edge_recalc = TRUE; \ } (void)0 diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index b7257028316..290b0684e40 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -28,16 +28,15 @@ * \ingroup bke */ -#include "BLI_math.h" - #include "MEM_guardedalloc.h" +#include "BLI_math.h" +#include "BLI_alloca.h" + #include "DNA_object_types.h" -#include "BLI_array.h" #include "BKE_DerivedMesh.h" -#include "BKE_bmesh.h" #include "BKE_editmesh.h" /* Static function for alloc */ diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index ef3b7ca0bdf..bf4a63c52a8 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -625,7 +625,7 @@ MovieClip *BKE_movieclip_file_add(Main *bmain, const char *name) /* exists? */ file = BLI_open(str, O_BINARY | O_RDONLY, 0); - if (file == -1) + if (file < 0) return NULL; close(file); @@ -1395,8 +1395,6 @@ void BKE_movieclip_build_proxy_frame_for_ibuf(MovieClip *clip, ImBuf *ibuf, stru void BKE_movieclip_free(MovieClip *clip) { - BKE_sequencer_clear_movieclip_in_clipboard(clip); - free_buffers(clip); BKE_tracking_free(&clip->tracking); @@ -1441,21 +1439,19 @@ void BKE_movieclip_unlink(Main *bmain, MovieClip *clip) bConstraint *con; for (con = ob->constraints.first; con; con = con->next) { - bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con); - - if (cti->type == CONSTRAINT_TYPE_FOLLOWTRACK) { + if (con->type == CONSTRAINT_TYPE_FOLLOWTRACK) { bFollowTrackConstraint *data = (bFollowTrackConstraint *) con->data; if (data->clip == clip) data->clip = NULL; } - else if (cti->type == CONSTRAINT_TYPE_CAMERASOLVER) { + else if (con->type == CONSTRAINT_TYPE_CAMERASOLVER) { bCameraSolverConstraint *data = (bCameraSolverConstraint *) con->data; if (data->clip == clip) data->clip = NULL; } - else if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) { + else if (con->type == CONSTRAINT_TYPE_OBJECTSOLVER) { bObjectSolverConstraint *data = (bObjectSolverConstraint *) con->data; if (data->clip == clip) diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index cba4c9206c9..32ca3ea6d5a 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -105,15 +105,15 @@ void multires_customdata_delete(Mesh *me) } /** Grid hiding **/ -static BLI_bitmap multires_mdisps_upsample_hidden(BLI_bitmap lo_hidden, - int lo_level, - int hi_level, +static BLI_bitmap *multires_mdisps_upsample_hidden(BLI_bitmap *lo_hidden, + int lo_level, + int hi_level, - /* assumed to be at hi_level (or - * null) */ - BLI_bitmap prev_hidden) + /* assumed to be at hi_level (or + * null) */ + BLI_bitmap *prev_hidden) { - BLI_bitmap subd; + BLI_bitmap *subd; int hi_gridsize = ccg_gridsize(hi_level); int lo_gridsize = ccg_gridsize(lo_level); int yh, xh, xl, yl, xo, yo, hi_ndx; @@ -168,11 +168,11 @@ static BLI_bitmap multires_mdisps_upsample_hidden(BLI_bitmap lo_hidden, return subd; } -static BLI_bitmap multires_mdisps_downsample_hidden(BLI_bitmap old_hidden, - int old_level, - int new_level) +static BLI_bitmap *multires_mdisps_downsample_hidden(BLI_bitmap *old_hidden, + int old_level, + int new_level) { - BLI_bitmap new_hidden; + BLI_bitmap *new_hidden; int new_gridsize = ccg_gridsize(new_level); int old_gridsize = ccg_gridsize(old_level); int x, y, factor, old_value; @@ -200,7 +200,7 @@ static void multires_output_hidden_to_ccgdm(CCGDerivedMesh *ccgdm, Mesh *me, int level) { const MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS); - BLI_bitmap *grid_hidden = ccgdm->gridHidden; + BLI_bitmap **grid_hidden = ccgdm->gridHidden; int *gridOffset; int i, j; @@ -210,7 +210,7 @@ static void multires_output_hidden_to_ccgdm(CCGDerivedMesh *ccgdm, for (j = 0; j < me->mpoly[i].totloop; j++) { int g = gridOffset[i] + j; const MDisps *md = &mdisps[g]; - BLI_bitmap gh = md->hidden; + BLI_bitmap *gh = md->hidden; if (gh) { grid_hidden[g] = @@ -224,7 +224,7 @@ static void multires_output_hidden_to_ccgdm(CCGDerivedMesh *ccgdm, * the current level of md.hidden) */ static void multires_mdisps_subdivide_hidden(MDisps *md, int new_level) { - BLI_bitmap subd; + BLI_bitmap *subd; BLI_assert(md->hidden); @@ -245,7 +245,7 @@ static void multires_mdisps_subdivide_hidden(MDisps *md, int new_level) static MDisps *multires_mdisps_initialize_hidden(Mesh *me, int level) { MDisps *mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS, - CD_CALLOC, 0, me->totloop); + CD_CALLOC, NULL, me->totloop); int gridsize = ccg_gridsize(level); int gridarea = gridsize * gridsize; int i, j, k; @@ -647,7 +647,7 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl) multires_copy_grid(ndisps, hdisps, nsize, hsize); if (mdisp->hidden) { - BLI_bitmap gh = + BLI_bitmap *gh = multires_mdisps_downsample_hidden(mdisp->hidden, mdisp->level, lvl); @@ -1251,7 +1251,7 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm) void multires_modifier_update_hidden(DerivedMesh *dm) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; - BLI_bitmap *grid_hidden = ccgdm->gridHidden; + BLI_bitmap **grid_hidden = ccgdm->gridHidden; Mesh *me = ccgdm->multires.ob->data; MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS); int totlvl = ccgdm->multires.totlvl; @@ -1262,7 +1262,7 @@ void multires_modifier_update_hidden(DerivedMesh *dm) for (i = 0; i < me->totloop; i++) { MDisps *md = &mdisps[i]; - BLI_bitmap gh = grid_hidden[i]; + BLI_bitmap *gh = grid_hidden[i]; if (!gh && md->hidden) { MEM_freeN(md->hidden); diff --git a/source/blender/blenkernel/intern/navmesh_conversion.c b/source/blender/blenkernel/intern/navmesh_conversion.c index 75e6ce9837d..1d662ae3116 100644 --- a/source/blender/blenkernel/intern/navmesh_conversion.c +++ b/source/blender/blenkernel/intern/navmesh_conversion.c @@ -440,9 +440,6 @@ int buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int *vertsPerPoly, int ntris = 0, *recastData = NULL; unsigned short *tris = NULL; - /* Don't bother converting if there is nothing to convert */ - if (!*nverts) return 0; - res = buildRawVertIndicesData(dm, nverts, verts, &ntris, &tris, trisToFacesMap, &recastData); if (!res) { printf("Converting navmesh: Error! Can't get vertices and indices from mesh\n"); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 84dfa70abfc..5001aa01653 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -3406,6 +3406,7 @@ static void registerShaderNodes(void) register_node_type_sh_rgb(); register_node_type_sh_wireframe(); register_node_type_sh_wavelength(); + register_node_type_sh_blackbody(); register_node_type_sh_mix_rgb(); register_node_type_sh_valtorgb(); register_node_type_sh_rgbtobw(); @@ -3417,11 +3418,14 @@ static void registerShaderNodes(void) register_node_type_sh_curve_rgb(); register_node_type_sh_math(); register_node_type_sh_vect_math(); + register_node_type_sh_vect_transform(); register_node_type_sh_squeeze(); register_node_type_sh_material_ext(); register_node_type_sh_invert(); register_node_type_sh_seprgb(); register_node_type_sh_combrgb(); + register_node_type_sh_sephsv(); + register_node_type_sh_combhsv(); register_node_type_sh_hue_sat(); register_node_type_sh_attribute(); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index daa57afe14e..962209bef87 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -678,9 +678,10 @@ void BKE_object_unlink(Object *ob) SpaceOops *so = (SpaceOops *)sl; if (so->treestore) { - TreeStoreElem *tselem = so->treestore->data; - int i; - for (i = 0; i < so->treestore->usedelem; i++, tselem++) { + TreeStoreElem *tselem; + BLI_mempool_iter iter; + BLI_mempool_iternew(so->treestore, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { if (tselem->id == (ID *)ob) tselem->id = NULL; } } @@ -693,6 +694,14 @@ void BKE_object_unlink(Object *ob) sbuts->pinid = NULL; } } + else if (sl->spacetype == SPACE_NODE) { + SpaceNode *snode = (SpaceNode *)sl; + + if (snode->from == (ID *)ob) { + snode->flag &= ~SNODE_PIN; + snode->from = NULL; + } + } } sa = sa->next; @@ -2029,15 +2038,13 @@ static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4 } } - if (ok) mul_serie_m4(totmat, par->obmat, tmat, - NULL, NULL, NULL, NULL, NULL, NULL); + if (ok) mul_m4_m4m4(totmat, par->obmat, tmat); else copy_m4_m4(totmat, par->obmat); break; case PARBONE: ob_parbone(ob, par, tmat); - mul_serie_m4(totmat, par->obmat, tmat, - NULL, NULL, NULL, NULL, NULL, NULL); + mul_m4_m4m4(totmat, par->obmat, tmat); break; case PARVERT1: @@ -2053,8 +2060,7 @@ static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4 case PARVERT3: ob_parvert3(ob, par, tmat); - mul_serie_m4(totmat, par->obmat, tmat, - NULL, NULL, NULL, NULL, NULL, NULL); + mul_m4_m4m4(totmat, par->obmat, tmat); break; case PARSKEL: @@ -2063,10 +2069,8 @@ static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4 } /* total */ - mul_serie_m4(tmat, totmat, ob->parentinv, - NULL, NULL, NULL, NULL, NULL, NULL); - mul_serie_m4(obmat, tmat, locmat, - NULL, NULL, NULL, NULL, NULL, NULL); + mul_m4_m4m4(tmat, totmat, ob->parentinv); + mul_m4_m4m4(obmat, tmat, locmat); if (simul) { @@ -2539,7 +2543,7 @@ void BKE_scene_foreach_display_point( Object *ob; for (base = FIRSTBASE; base; base = base->next) { - if (BASE_VISIBLE(v3d, base) && (base->flag & flag) == flag) { + if (BASE_VISIBLE_BGMODE(v3d, scene, base) && (base->flag & flag) == flag) { ob = base->object; if ((ob->transflag & OB_DUPLI) == 0) { diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index 11d58c945fd..62ea16b9fb4 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -202,7 +202,7 @@ PackedFile *newPackedFile(ReportList *reports, const char *filename, const char * and create a PackedFile structure */ file = BLI_open(name, O_BINARY | O_RDONLY, 0); - if (file <= 0) { + if (file < 0) { BKE_reportf(reports, RPT_ERROR, "Unable to pack file, source path '%s' not found", name); } else { @@ -327,20 +327,21 @@ int writePackedFile(ReportList *reports, const char *filename, PackedFile *pf, i BLI_make_existing_file(name); file = BLI_open(name, O_BINARY + O_WRONLY + O_CREAT + O_TRUNC, 0666); - if (file >= 0) { + if (file < 0) { + BKE_reportf(reports, RPT_ERROR, "Error creating file '%s'", name); + ret_value = RET_ERROR; + } + else { if (write(file, pf->data, pf->size) != pf->size) { BKE_reportf(reports, RPT_ERROR, "Error writing file '%s'", name); ret_value = RET_ERROR; } - else + else { BKE_reportf(reports, RPT_INFO, "Saved packed file to: %s", name); + } close(file); } - else { - BKE_reportf(reports, RPT_ERROR, "Error creating file '%s'", name); - ret_value = RET_ERROR; - } if (remove_tmp) { if (ret_value == RET_ERROR) { diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 6bea4bec3ce..6b754743c11 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -3836,7 +3836,7 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti for (m = 0; m < MAX_MTEX; m++, mtexp++) { mtex = *mtexp; - if (mtex && mtex->mapto) { + if (mtex && mtex->tex && mtex->mapto) { float def = mtex->def_var; short blend = mtex->blendtype; short texco = mtex->texco; @@ -3904,7 +3904,7 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex for (m = 0; m < MAX_MTEX; m++, mtexp++) { mtex = *mtexp; - if (mtex && mtex->mapto) { + if (mtex && mtex->tex && mtex->mapto) { float def = mtex->def_var; short blend = mtex->blendtype; short texco = mtex->texco; diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 99e6e898685..205159c94a1 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -538,7 +538,7 @@ void BKE_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, int totface, int /* Do a full rebuild with on Grids data structure */ void BKE_pbvh_build_grids(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj, - int totgrid, CCGKey *key, void **gridfaces, DMFlagMat *flagmats, BLI_bitmap *grid_hidden) + int totgrid, CCGKey *key, void **gridfaces, DMFlagMat *flagmats, BLI_bitmap **grid_hidden) { BBC *prim_bbc = NULL; BB cb; @@ -753,7 +753,7 @@ void BKE_pbvh_search_gather(PBVH *bvh, PBVHNode ***r_array, int *r_tot) { PBVHIter iter; - PBVHNode **array = NULL, **newarray, *node; + PBVHNode **array = NULL, *node; int tot = 0, space = 0; pbvh_iter_begin(&iter, bvh, scb, search_data); @@ -763,14 +763,7 @@ void BKE_pbvh_search_gather(PBVH *bvh, if (tot == space) { /* resize array if needed */ space = (tot == 0) ? 32 : space * 2; - newarray = MEM_callocN(sizeof(PBVHNode) * space, "PBVHNodeSearch"); - - if (array) { - memcpy(newarray, array, sizeof(PBVHNode) * tot); - MEM_freeN(array); - } - - array = newarray; + array = MEM_recallocN_id(array, sizeof(PBVHNode *) * space, __func__); } array[tot] = node; @@ -845,12 +838,12 @@ static void free_tree(node_tree *tree) { if (tree->left) { free_tree(tree->left); - tree->left = 0; + tree->left = NULL; } if (tree->right) { free_tree(tree->right); - tree->right = 0; + tree->right = NULL; } free(tree); @@ -867,7 +860,7 @@ static void BKE_pbvh_search_callback_occluded(PBVH *bvh, { PBVHIter iter; PBVHNode *node; - node_tree *tree = 0; + node_tree *tree = NULL; pbvh_iter_begin(&iter, bvh, scb, search_data); @@ -1253,7 +1246,7 @@ void BKE_pbvh_bounding_box(const PBVH *bvh, float min[3], float max[3]) } } -BLI_bitmap *BKE_pbvh_grid_hidden(const PBVH *bvh) +BLI_bitmap **BKE_pbvh_grid_hidden(const PBVH *bvh) { BLI_assert(bvh->type == PBVH_GRIDS); return bvh->grid_hidden; @@ -1363,7 +1356,7 @@ void BKE_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *pro if (proxy_count) *proxy_count = node->proxy_count; } else { - if (proxies) *proxies = 0; + if (proxies) *proxies = NULL; if (proxy_count) *proxy_count = 0; } } @@ -1469,7 +1462,7 @@ static int pbvh_grids_node_raycast(PBVH *bvh, PBVHNode *node, for (i = 0; i < totgrid; ++i) { CCGElem *grid = bvh->grids[node->prim_indices[i]]; - BLI_bitmap gh; + BLI_bitmap *gh; if (!grid) continue; @@ -1664,7 +1657,7 @@ void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3], } void BKE_pbvh_grids_update(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj, void **gridfaces, - DMFlagMat *flagmats, BLI_bitmap *grid_hidden) + DMFlagMat *flagmats, BLI_bitmap **grid_hidden) { int a; @@ -1795,11 +1788,11 @@ void BKE_pbvh_node_free_proxies(PBVHNode *node) for (p = 0; p < node->proxy_count; p++) { MEM_freeN(node->proxies[p].co); - node->proxies[p].co = 0; + node->proxies[p].co = NULL; } MEM_freeN(node->proxies); - node->proxies = 0; + node->proxies = NULL; node->proxy_count = 0; } @@ -1807,7 +1800,7 @@ void BKE_pbvh_node_free_proxies(PBVHNode *node) void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot) { - PBVHNode **array = NULL, **newarray, *node; + PBVHNode **array = NULL, *node; int tot = 0, space = 0; int n; @@ -1818,14 +1811,7 @@ void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot) if (tot == space) { /* resize array if needed */ space = (tot == 0) ? 32 : space * 2; - newarray = MEM_callocN(sizeof(PBVHNode) * space, "BKE_pbvh_gather_proxies"); - - if (array) { - memcpy(newarray, array, sizeof(PBVHNode) * tot); - MEM_freeN(array); - } - - array = newarray; + array = MEM_recallocN_id(array, sizeof(PBVHNode *) * space, __func__); } array[tot] = node; @@ -1850,10 +1836,10 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, int *grid_indices, *vert_indices; int totgrid, gridsize, uniq_verts, totvert; - vi->grid = 0; - vi->no = 0; - vi->fno = 0; - vi->mvert = 0; + vi->grid = NULL; + vi->no = NULL; + vi->fno = NULL; + vi->mvert = NULL; BKE_pbvh_node_get_grids(bvh, node, &grid_indices, &totgrid, NULL, &gridsize, &grids, NULL); BKE_pbvh_node_num_verts(bvh, node, &uniq_verts, &totvert); diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c index c6a5552dbf7..cd21f8ad968 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.c +++ b/source/blender/blenkernel/intern/pbvh_bmesh.c @@ -294,7 +294,7 @@ static BMVert *pbvh_bmesh_vert_create(PBVH *bvh, int node_index, static BMFace *pbvh_bmesh_face_create(PBVH *bvh, int node_index, BMVert *v_tri[3], BMEdge *e_tri[3], - const BMFace *UNUSED(example)) + const BMFace *f_example) { BMFace *f; void *val = SET_INT_IN_POINTER(node_index); @@ -302,9 +302,10 @@ static BMFace *pbvh_bmesh_face_create(PBVH *bvh, int node_index, /* ensure we never add existing face */ BLI_assert(BM_face_exists(v_tri, 3, NULL) == false); - /* Note: passing NULL for the 'example' parameter, profiling shows - * a small performance bump */ f = BM_face_create(bvh->bm, v_tri, e_tri, 3, 0); + // BM_elem_attrs_copy(bvh->bm, bvh->bm, f_example, f); + f->mat_nr = f_example->mat_nr; + if (!BLI_ghash_haskey(bvh->bm_face_to_node, f)) { BLI_ghash_insert(bvh->nodes[node_index].bm_faces, f, NULL); diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h index b3f7bf6e3d1..4154b8e4799 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.h +++ b/source/blender/blenkernel/intern/pbvh_intern.h @@ -139,11 +139,11 @@ struct PBVH { void **gridfaces; const DMFlagMat *grid_flag_mats; int totgrid; - BLI_bitmap *grid_hidden; + BLI_bitmap **grid_hidden; /* Only used during BVH build and update, * don't need to remain valid after */ - BLI_bitmap vert_bitmap; + BLI_bitmap *vert_bitmap; #ifdef PERFCNTRS int perf_modified; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 06748dfc44d..93f6965e97b 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -268,8 +268,9 @@ static int ptcache_particle_write(int index, void *psys_v, void **data, int cfr PTCACHE_DATA_FROM(data, BPHYS_DATA_SIZE, &pa->size); PTCACHE_DATA_FROM(data, BPHYS_DATA_TIMES, times); - if (boid) + if (boid) { PTCACHE_DATA_FROM(data, BPHYS_DATA_BOIDS, &boid->data); + } /* return flag 1+1=2 for newly born particles to copy exact birth location to previously cached frame */ return 1 + (pa->state.time >= pa->time && pa->prev_state.time <= pa->time); @@ -304,8 +305,9 @@ static void ptcache_particle_read(int index, void *psys_v, void **data, float cf else if (cfra > pa->dietime) pa->state.time = pa->dietime; - if (data[BPHYS_DATA_SIZE]) + if (data[BPHYS_DATA_SIZE]) { PTCACHE_DATA_TO(data, BPHYS_DATA_SIZE, 0, &pa->size); + } if (data[BPHYS_DATA_TIMES]) { float times[3]; @@ -926,7 +928,7 @@ static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v) /* version header */ ptcache_file_read(pf, version, 1, sizeof(char) * 4); if (strncmp(version, DPAINT_CACHE_VERSION, 4)) { - printf("Dynamic Paint: Invalid cache version: %s!\n", version); + printf("Dynamic Paint: Invalid cache version: '%c%c%c%c'!\n", UNPACK4(version)); return 0; } @@ -3576,6 +3578,11 @@ void BKE_ptcache_load_external(PTCacheID *pid) cache->flag &= ~(PTCACHE_OUTDATED|PTCACHE_FRAMES_SKIPPED); } + /* make sure all new frames are loaded */ + if (cache->cached_frames) { + MEM_freeN(cache->cached_frames); + cache->cached_frames=NULL; + } BKE_ptcache_update_info(pid); } diff --git a/source/blender/blenkernel/intern/property.c b/source/blender/blenkernel/intern/property.c index ec23a7db8a1..73f2a864e32 100644 --- a/source/blender/blenkernel/intern/property.c +++ b/source/blender/blenkernel/intern/property.c @@ -177,9 +177,9 @@ void BKE_bproperty_unique(bProperty *first, bProperty *prop, int force) i = 0; do { /* ensure we have enough chars for the new number in the name */ - BLI_snprintf(num, sizeof(num), "%d", i++); - BLI_strncpy(new_name, base_name, sizeof(prop->name) - strlen(num)); - strcat(new_name, num); + const size_t num_len = BLI_snprintf(num, sizeof(num), "%d", i++); + BLI_snprintf(new_name, sizeof(prop->name), + "%.*s%s", (int)(sizeof(prop->name) - num_len), base_name, num); } while (bproperty_get(first, prop, new_name)); BLI_strncpy(prop->name, new_name, sizeof(prop->name)); diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 01f57b95378..fe2f52d79fd 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -136,6 +136,11 @@ void BKE_spacetype_register(SpaceType *st) BLI_addtail(&spacetypes, st); } +int BKE_spacetype_exists(int spaceid) +{ + return BKE_spacetype_from_id(spaceid) != NULL; +} + /* ***************** Space handling ********************** */ void BKE_spacedata_freelist(ListBase *lb) diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index b080cfcff2f..34b19e3f357 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -65,6 +65,7 @@ #include "BKE_fcurve.h" #include "BKE_scene.h" #include "BKE_mask.h" +#include "BKE_library.h" #include "RNA_access.h" @@ -265,6 +266,7 @@ static void seq_free_clipboard_recursive(Sequence *seq_parent) seq_free_clipboard_recursive(seq); } + BKE_sequence_clipboard_pointers_free(seq_parent); BKE_sequence_free_ex(NULL, seq_parent, FALSE); } @@ -279,6 +281,101 @@ void BKE_sequencer_free_clipboard(void) seqbase_clipboard.first = seqbase_clipboard.last = NULL; } +/* -------------------------------------------------------------------- */ +/* Manage pointers in the clipboard. + * note that these pointers should _never_ be access in the sequencer, + * they are only for storage while in the clipboard + * notice 'newid' is used for temp pointer storage here, validate on access. + */ +#define ID_PT (*id_pt) +static void seqclipboard_ptr_free(ID **id_pt) +{ + if (ID_PT) { + BLI_assert(ID_PT->newid != NULL); + MEM_freeN(ID_PT); + ID_PT = NULL; + } +} +static void seqclipboard_ptr_store(ID **id_pt) +{ + if (ID_PT) { + ID *id_prev = ID_PT; + ID_PT = MEM_dupallocN(ID_PT); + ID_PT->newid = id_prev; + } +} +static void seqclipboard_ptr_restore(Main *bmain, ID **id_pt) +{ + if (ID_PT) { + const ListBase *lb = which_libbase(bmain, GS(ID_PT->name)); + void *id_restore; + + BLI_assert(ID_PT->newid != NULL); + if (BLI_findindex(lb, (ID_PT)->newid) != -1) { + /* the pointer is still valid */ + id_restore = (ID_PT)->newid; + } + else { + /* the pointer of the same name still exists */ + id_restore = BLI_findstring(lb, (ID_PT)->name + 2, offsetof(ID, name) + 2); + } + + if (id_restore == NULL) { + /* check for a data with the same filename */ + switch (GS(ID_PT->name)) { + case ID_SO: + { + id_restore = BLI_findstring(lb, ((bSound *)ID_PT)->name, offsetof(bSound, name)); + if (id_restore == NULL) { + id_restore = sound_new_file(bmain, ((bSound *)ID_PT)->name); + (ID_PT)->newid = id_restore; /* reuse next time */ + } + break; + } + case ID_MC: + { + id_restore = BLI_findstring(lb, ((MovieClip *)ID_PT)->name, offsetof(MovieClip, name)); + if (id_restore == NULL) { + id_restore = BKE_movieclip_file_add(bmain, ((MovieClip *)ID_PT)->name); + (ID_PT)->newid = id_restore; /* reuse next time */ + } + break; + } + } + } + + ID_PT = id_restore; + } +} +#undef ID_PT + +void BKE_sequence_clipboard_pointers_free(Sequence *seq) +{ + seqclipboard_ptr_free((ID **)&seq->scene); + seqclipboard_ptr_free((ID **)&seq->scene_camera); + seqclipboard_ptr_free((ID **)&seq->clip); + seqclipboard_ptr_free((ID **)&seq->mask); + seqclipboard_ptr_free((ID **)&seq->sound); +} +void BKE_sequence_clipboard_pointers_store(Sequence *seq) +{ + seqclipboard_ptr_store((ID **)&seq->scene); + seqclipboard_ptr_store((ID **)&seq->scene_camera); + seqclipboard_ptr_store((ID **)&seq->clip); + seqclipboard_ptr_store((ID **)&seq->mask); + seqclipboard_ptr_store((ID **)&seq->sound); +} +void BKE_sequence_clipboard_pointers_restore(Sequence *seq, Main *bmain) +{ + seqclipboard_ptr_restore(bmain, (ID **)&seq->scene); + seqclipboard_ptr_restore(bmain, (ID **)&seq->scene_camera); + seqclipboard_ptr_restore(bmain, (ID **)&seq->clip); + seqclipboard_ptr_restore(bmain, (ID **)&seq->mask); + seqclipboard_ptr_restore(bmain, (ID **)&seq->sound); +} +/* end clipboard pointer mess */ + + Editing *BKE_sequencer_editing_ensure(Scene *scene) { if (scene->ed == NULL) { @@ -818,33 +915,6 @@ void BKE_sequencer_clear_scene_in_allseqs(Main *bmain, Scene *scene) BKE_sequencer_base_recursive_apply(&scene_iter->ed->seqbase, clear_scene_in_allseqs_cb, scene); } } - - /* also clear clipboard */ - BKE_sequencer_base_recursive_apply(&seqbase_clipboard, clear_scene_in_allseqs_cb, scene); -} - -static int clear_movieclip_in_clipboard_cb(Sequence *seq, void *arg_pt) -{ - if (seq->clip == (MovieClip *)arg_pt) - seq->clip = NULL; - return 1; -} - -void BKE_sequencer_clear_movieclip_in_clipboard(MovieClip *clip) -{ - BKE_sequencer_base_recursive_apply(&seqbase_clipboard, clear_movieclip_in_clipboard_cb, clip); -} - -static int clear_mask_in_clipboard_cb(Sequence *seq, void *arg_pt) -{ - if (seq->mask == (Mask *)arg_pt) - seq->mask = NULL; - return 1; -} - -void BKE_sequencer_clear_mask_in_clipboard(Mask *mask) -{ - BKE_sequencer_base_recursive_apply(&seqbase_clipboard, clear_mask_in_clipboard_cb, mask); } typedef struct SeqUniqueInfo { @@ -4245,6 +4315,12 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup if (seq->scene_sound) seqn->scene_sound = sound_scene_add_scene_sound_defaults(sce_audio, seqn); } + else if (seq->type == SEQ_TYPE_MOVIECLIP) { + /* avoid assert */ + } + else if (seq->type == SEQ_TYPE_MASK) { + /* avoid assert */ + } else if (seq->type == SEQ_TYPE_MOVIE) { seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata); @@ -4256,7 +4332,7 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup if (seq->scene_sound) seqn->scene_sound = sound_add_scene_sound_defaults(sce_audio, seqn); - seqn->sound->id.us++; + id_us_plus((ID *)seqn->sound); } else if (seq->type == SEQ_TYPE_IMAGE) { seqn->strip->stripdata = @@ -4278,7 +4354,8 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup } else { - fprintf(stderr, "Aiiiiekkk! sequence type not handled in duplicate!\nExpect a crash now...\n"); + /* sequence type not handled in duplicate! Expect a crash now... */ + BLI_assert(0); } if (dupe_flag & SEQ_DUPE_UNIQUE_NAME) diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 10065910532..b9843ad0619 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -86,7 +86,7 @@ void space_transform_from_matrixs(SpaceTransform *data, float local[4][4], float { float itarget[4][4]; invert_m4_m4(itarget, target); - mul_serie_m4(data->local2target, itarget, local, NULL, NULL, NULL, NULL, NULL, NULL); + mul_m4_m4m4(data->local2target, itarget, local); invert_m4_m4(data->target2local, data->local2target); } @@ -428,7 +428,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) BVHTreeNearest nearest = NULL_BVHTreeNearest; /* Create a bvh-tree of the given target */ - TIMEIT_BENCH(bvhtree_from_mesh_faces(&treeData, calc->target, 0.0, 2, 6), bvhtree_faces); + bvhtree_from_mesh_faces(&treeData, calc->target, 0.0, 2, 6); if (treeData.tree == NULL) { OUT_OF_MEMORY(); return; diff --git a/source/blender/blenkernel/intern/sketch.c b/source/blender/blenkernel/intern/sketch.c index 707d97a1cf1..bbd637a0a77 100644 --- a/source/blender/blenkernel/intern/sketch.c +++ b/source/blender/blenkernel/intern/sketch.c @@ -487,7 +487,7 @@ void sk_endContinuousStroke(SK_Stroke *stk) void sk_updateNextPoint(SK_Sketch *sketch, SK_Stroke *stk) { if (stk) { - memcpy(&sketch->next_point, stk->points[stk->nb_points - 1].p, sizeof(SK_Point)); + memcpy(&(sketch->next_point), &(stk->points[stk->nb_points - 1]), sizeof(SK_Point)); } } diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index b2c0a45cbc4..bb65955e3b5 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -259,7 +259,10 @@ static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object * zero_v3_int(sds->base_res); copy_v3_v3(sds->cell_size, size); } - mul_v3_v3(size, ob->size); + /* apply object scale */ + for (i = 0; i < 3; i++) { + size[i] = fabs(size[i] * ob->size[i]); + } copy_v3_v3(sds->global_size, size); copy_v3_v3(sds->dp0, min); @@ -272,21 +275,21 @@ static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object * /* define grid resolutions from longest domain side */ if (size[0] >= MAX2(size[1], size[2])) { scale = res / size[0]; - sds->scale = size[0] / ob->size[0]; + sds->scale = size[0] / fabs(ob->size[0]); sds->base_res[0] = res; sds->base_res[1] = (int)(size[1] * scale + 0.5f); sds->base_res[2] = (int)(size[2] * scale + 0.5f); } else if (size[1] >= MAX2(size[0], size[2])) { scale = res / size[1]; - sds->scale = size[1] / ob->size[1]; + sds->scale = size[1] / fabs(ob->size[1]); sds->base_res[0] = (int)(size[0] * scale + 0.5f); sds->base_res[1] = res; sds->base_res[2] = (int)(size[2] * scale + 0.5f); } else { scale = res / size[2]; - sds->scale = size[2] / ob->size[2]; + sds->scale = size[2] / fabs(ob->size[2]); sds->base_res[0] = (int)(size[0] * scale + 0.5f); sds->base_res[1] = (int)(size[1] * scale + 0.5f); sds->base_res[2] = res; @@ -719,7 +722,7 @@ static void obstacles_from_derivedmesh(Object *coll_ob, SmokeDomainSettings *sds DerivedMesh *dm = NULL; MVert *mvert = NULL; MFace *mface = NULL; - BVHTreeFromMesh treeData = {0}; + BVHTreeFromMesh treeData = {NULL}; int numverts, i, z; float surface_distance = 0.6; @@ -1570,7 +1573,7 @@ static void emit_from_derivedmesh(Object *flow_ob, SmokeDomainSettings *sds, Smo MVert *mvert_orig = NULL; MFace *mface = NULL; MTFace *tface = NULL; - BVHTreeFromMesh treeData = {0}; + BVHTreeFromMesh treeData = {NULL}; int numOfVerts, i, z; float flow_center[3] = {0}; @@ -2105,7 +2108,7 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd // float scene_subframe = scene->r.subframe; // UNUSED int subframe; for (subframe = 0; subframe <= subframes; subframe++) { - EmissionMap em_temp = {0}; + EmissionMap em_temp = {NULL}; float sample_size = 1.0f / (float)(subframes+1); float prev_frame_pos = sample_size * (float)(subframe+1); float sdt = dt * sample_size; diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index feff8f95fd7..2f8eb7d9931 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -60,10 +60,6 @@ #include "BKE_sequencer.h" #include "BKE_scene.h" -// evil quiet NaN definition -static const int NAN_INT = 0x7FC00000; -#define NAN_FLT *((float *)(&NAN_INT)) - #ifdef WITH_AUDASPACE // evil global ;-) static int sound_cfra; diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 26a5dada108..35482d9553d 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -1505,7 +1505,8 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) static void ccgDM_foreachMappedVert( DerivedMesh *dm, void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]), - void *userData) + void *userData, + DMForeachFlag flag) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGVertIterator *vi; @@ -1514,11 +1515,13 @@ static void ccgDM_foreachMappedVert( for (vi = ccgSubSurf_getVertIterator(ccgdm->ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { CCGVert *v = ccgVertIterator_getCurrent(vi); - CCGElem *vd = ccgSubSurf_getVertData(ccgdm->ss, v); - int index = ccgDM_getVertMapIndex(ccgdm->ss, v); + const int index = ccgDM_getVertMapIndex(ccgdm->ss, v); - if (index != -1) - func(userData, index, CCG_elem_co(&key, vd), CCG_elem_no(&key, vd), NULL); + if (index != -1) { + CCGElem *vd = ccgSubSurf_getVertData(ccgdm->ss, v); + const float *no = (flag & DM_FOREACH_USE_NORMAL) ? CCG_elem_no(&key, vd) : NULL; + func(userData, index, CCG_elem_co(&key, vd), no, NULL); + } } ccgVertIterator_free(vi); @@ -1539,12 +1542,13 @@ static void ccgDM_foreachMappedEdge( for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { CCGEdge *e = ccgEdgeIterator_getCurrent(ei); - CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); - int index = ccgDM_getEdgeMapIndex(ss, e); + const int index = ccgDM_getEdgeMapIndex(ss, e); if (index != -1) { - for (i = 0; i < edgeSize - 1; i++) + CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); + for (i = 0; i < edgeSize - 1; i++) { func(userData, index, CCG_elem_offset_co(&key, edgeData, i), CCG_elem_offset_co(&key, edgeData, i + 1)); + } } } @@ -2530,7 +2534,8 @@ static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, static void ccgDM_foreachMappedFaceCenter( DerivedMesh *dm, void (*func)(void *userData, int index, const float co[3], const float no[3]), - void *userData) + void *userData, + DMForeachFlag flag) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; @@ -2541,13 +2546,13 @@ static void ccgDM_foreachMappedFaceCenter( for (fi = ccgSubSurf_getFaceIterator(ss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { CCGFace *f = ccgFaceIterator_getCurrent(fi); - int index = ccgDM_getFaceMapIndex(ss, f); + const int index = ccgDM_getFaceMapIndex(ss, f); if (index != -1) { /* Face center data normal isn't updated atm. */ CCGElem *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0); - - func(userData, index, CCG_elem_co(&key, vd), CCG_elem_no(&key, vd)); + const float *no = (flag & DM_FOREACH_USE_NORMAL) ? CCG_elem_no(&key, vd) : NULL; + func(userData, index, CCG_elem_co(&key, vd), no); } } @@ -2925,7 +2930,7 @@ static void ccgdm_create_grids(DerivedMesh *dm) gridFaces = MEM_mallocN(sizeof(CCGFace *) * numGrids, "ccgdm.gridFaces"); gridFlagMats = MEM_mallocN(sizeof(DMFlagMat) * numGrids, "ccgdm.gridFlagMats"); - ccgdm->gridHidden = MEM_callocN(sizeof(BLI_bitmap) * numGrids, "ccgdm.gridHidden"); + ccgdm->gridHidden = MEM_callocN(sizeof(*ccgdm->gridHidden) * numGrids, "ccgdm.gridHidden"); for (gIndex = 0, index = 0; index < numFaces; index++) { CCGFace *f = ccgdm->faceMap[index].face; @@ -2997,7 +3002,7 @@ static DMFlagMat *ccgDM_getGridFlagMats(DerivedMesh *dm) return ccgdm->gridFlagMats; } -static BLI_bitmap *ccgDM_getGridHidden(DerivedMesh *dm) +static BLI_bitmap **ccgDM_getGridHidden(DerivedMesh *dm) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; @@ -3134,7 +3139,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int numTex, numCol; int hasPCol, hasOrigSpace; int gridInternalEdges; - WeightTable wtable = {0}; + WeightTable wtable = {NULL}; /* MCol *mcol; */ /* UNUSED */ MEdge *medge = NULL; /* MFace *mface = NULL; */ diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 8d63be5fbd5..f0c01e25598 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -2359,7 +2359,7 @@ static void txt_delete_line(Text *text, TextLine *line) static void txt_combine_lines(Text *text, TextLine *linea, TextLine *lineb) { - char *tmp; + char *tmp, *s; if (!text) return; @@ -2368,8 +2368,10 @@ static void txt_combine_lines(Text *text, TextLine *linea, TextLine *lineb) tmp = MEM_mallocN(linea->len + lineb->len + 1, "textline_string"); - strcpy(tmp, linea->line); - strcat(tmp, lineb->line); + s = tmp; + s += BLI_strcpy_rlen(s, linea->line); + s += BLI_strcpy_rlen(s, lineb->line); + (void)s; make_new_line(linea, tmp); @@ -2622,10 +2624,6 @@ void txt_indent(Text *text) return; } - if (!text) return; - if (!text->curl) return; - if (!text->sell) return; - /* insert spaces rather than tabs */ if (text->flags & TXT_TABSTOSPACES) { add = tab_to_spaces; @@ -2685,9 +2683,9 @@ void txt_unindent(Text *text) /* hardcoded: TXT_TABSIZE = 4 spaces: */ int spaceslen = TXT_TABSIZE; - if (!text) return; - if (!text->curl) return; - if (!text->sell) return; + if (ELEM3(NULL, text, text->curl, text->sell)) { + return; + } /* insert spaces rather than tabs */ if (text->flags & TXT_TABSTOSPACES) { diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 1d0b0deae7e..e2b7358525a 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -906,42 +906,6 @@ void BKE_texture_make_local(Tex *tex) } } -/* ------------------------------------------------------------------------- */ -#if 0 /* UNUSED */ -void autotexname(Tex *tex) -{ - Main *bmain = G.main; - char texstr[20][15] = {"None", "Clouds", "Wood", "Marble", "Magic", "Blend", - "Stucci", "Noise", "Image", "EnvMap", "Musgrave", - "Voronoi", "DistNoise", "Point Density", "Voxel Data", "Ocean", "", "", ""}; - Image *ima; - char di[FILE_MAXDIR], fi[FILE_MAXFILE]; - - if (tex) { - if (tex->use_nodes) { - new_id(&bmain->tex, (ID *)tex, "Noddy"); - } - else if (tex->type == TEX_IMAGE) { - ima = tex->ima; - if (ima) { - BLI_split_file_part(ima->name, fi, sizeof(fi)); - strcpy(di, "I."); - strcat(di, fi); - new_id(&bmain->tex, (ID *)tex, di); - } - else { - new_id(&bmain->tex, (ID *)tex, texstr[tex->type]); - } - } - else { - new_id(&bmain->tex, (ID *)tex, texstr[tex->type]); - } - } -} -#endif - -/* ------------------------------------------------------------------------- */ - Tex *give_current_object_texture(Object *ob) { Material *ma, *node_ma; diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 2c561dd4472..4c363292898 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -654,7 +654,7 @@ void BKE_tracking_track_flag_clear(MovieTrackingTrack *track, int area, int flag */ int BKE_tracking_track_has_marker_at_frame(MovieTrackingTrack *track, int framenr) { - return BKE_tracking_marker_get_exact(track, framenr) != 0; + return BKE_tracking_marker_get_exact(track, framenr) != NULL; } /* Check whether track has got enabled marker at specified frame. @@ -1534,7 +1534,7 @@ void BKE_tracking_camera_get_reconstructed_interpolate(MovieTracking *tracking, /*********************** Distortion/Undistortion *************************/ -static void cameraIntrinscisOptionsFromTracking(libmv_cameraIntrinsicsOptions *camera_intrinsics_options, +static void cameraIntrinscisOptionsFromTracking(libmv_CameraIntrinsicsOptions *camera_intrinsics_options, MovieTracking *tracking, int calibration_width, int calibration_height) { MovieTrackingCamera *camera = &tracking->camera; @@ -1559,7 +1559,7 @@ MovieDistortion *BKE_tracking_distortion_new(void) distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create"); - distortion->intrinsics = libmv_CameraIntrinsicsNewEmpty(); + distortion->intrinsics = libmv_cameraIntrinsicsNewEmpty(); return distortion; } @@ -1567,17 +1567,17 @@ MovieDistortion *BKE_tracking_distortion_new(void) void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *tracking, int calibration_width, int calibration_height) { - libmv_cameraIntrinsicsOptions camera_intrinsics_options; + libmv_CameraIntrinsicsOptions camera_intrinsics_options; cameraIntrinscisOptionsFromTracking(&camera_intrinsics_options, tracking, calibration_width, calibration_height); - libmv_CameraIntrinsicsUpdate(&camera_intrinsics_options, distortion->intrinsics); + libmv_cameraIntrinsicsUpdate(&camera_intrinsics_options, distortion->intrinsics); } void BKE_tracking_distortion_set_threads(MovieDistortion *distortion, int threads) { - libmv_CameraIntrinsicsSetThreads(distortion->intrinsics, threads); + libmv_cameraIntrinsicsSetThreads(distortion->intrinsics, threads); } MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion) @@ -1586,7 +1586,7 @@ MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion) new_distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create"); - new_distortion->intrinsics = libmv_CameraIntrinsicsCopy(distortion->intrinsics); + new_distortion->intrinsics = libmv_cameraIntrinsicsCopy(distortion->intrinsics); return new_distortion; } @@ -1602,12 +1602,12 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking * if (ibuf->rect_float) { if (undistort) { - libmv_CameraIntrinsicsUndistortFloat(distortion->intrinsics, + libmv_cameraIntrinsicsUndistortFloat(distortion->intrinsics, ibuf->rect_float, resibuf->rect_float, ibuf->x, ibuf->y, overscan, ibuf->channels); } else { - libmv_CameraIntrinsicsDistortFloat(distortion->intrinsics, + libmv_cameraIntrinsicsDistortFloat(distortion->intrinsics, ibuf->rect_float, resibuf->rect_float, ibuf->x, ibuf->y, overscan, ibuf->channels); } @@ -1617,12 +1617,12 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking * } else { if (undistort) { - libmv_CameraIntrinsicsUndistortByte(distortion->intrinsics, + libmv_cameraIntrinsicsUndistortByte(distortion->intrinsics, (unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect, ibuf->x, ibuf->y, overscan, ibuf->channels); } else { - libmv_CameraIntrinsicsDistortByte(distortion->intrinsics, + libmv_cameraIntrinsicsDistortByte(distortion->intrinsics, (unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect, ibuf->x, ibuf->y, overscan, ibuf->channels); } @@ -1633,7 +1633,7 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking * void BKE_tracking_distortion_free(MovieDistortion *distortion) { - libmv_CameraIntrinsicsDestroy(distortion->intrinsics); + libmv_cameraIntrinsicsDestroy(distortion->intrinsics); MEM_freeN(distortion); } @@ -1642,7 +1642,7 @@ void BKE_tracking_distort_v2(MovieTracking *tracking, const float co[2], float r { MovieTrackingCamera *camera = &tracking->camera; - libmv_cameraIntrinsicsOptions camera_intrinsics_options; + libmv_CameraIntrinsicsOptions camera_intrinsics_options; double x, y; float aspy = 1.0f / tracking->camera.pixel_aspect; @@ -1652,7 +1652,7 @@ void BKE_tracking_distort_v2(MovieTracking *tracking, const float co[2], float r x = (co[0] - camera->principal[0]) / camera->focal; y = (co[1] - camera->principal[1] * aspy) / camera->focal; - libmv_ApplyCameraIntrinsics(&camera_intrinsics_options, x, y, &x, &y); + libmv_cameraIntrinsicsApply(&camera_intrinsics_options, x, y, &x, &y); /* result is in image coords already */ r_co[0] = x; @@ -1663,13 +1663,13 @@ void BKE_tracking_undistort_v2(MovieTracking *tracking, const float co[2], float { MovieTrackingCamera *camera = &tracking->camera; - libmv_cameraIntrinsicsOptions camera_intrinsics_options; + libmv_CameraIntrinsicsOptions camera_intrinsics_options; double x = co[0], y = co[1]; float aspy = 1.0f / tracking->camera.pixel_aspect; cameraIntrinscisOptionsFromTracking(&camera_intrinsics_options, tracking, 0, 0); - libmv_InvertCameraIntrinsics(&camera_intrinsics_options, x, y, &x, &y); + libmv_cameraIntrinsicsInvert(&camera_intrinsics_options, x, y, &x, &y); r_co[0] = (float)x * camera->focal + camera->principal[0]; r_co[1] = (float)y * camera->focal + camera->principal[1] * aspy; @@ -2529,7 +2529,7 @@ static bool track_context_update_reference(MovieTrackingContext *context, TrackC /* Fill in libmv tracker options structure with settings need to be used to perform track. */ static void tracking_configure_tracker(MovieTrackingTrack *track, float *mask, - struct libmv_trackRegionOptions *options) + libmv_TrackRegionOptions *options) { options->motion_model = track->motion_model; @@ -2654,8 +2654,8 @@ static bool configure_and_run_tracker(ImBuf *destination_ibuf, MovieTrackingTrac double src_pixel_x[5], src_pixel_y[5]; /* Settings for the tracker */ - struct libmv_trackRegionOptions options = {0}; - struct libmv_trackRegionResult result; + libmv_TrackRegionOptions options = {0}; + libmv_TrackRegionResult result; float *patch_new; @@ -2930,17 +2930,17 @@ static struct libmv_Tracks *libmv_tracks_new(ListBase *tracksbase, int width, in } /* Retrieve refined camera intrinsics from libmv to blender. */ -static void reconstruct_retrieve_libmv_intrinscis(MovieReconstructContext *context, MovieTracking *tracking) +static void reconstruct_retrieve_libmv_intrinsics(MovieReconstructContext *context, MovieTracking *tracking) { struct libmv_Reconstruction *libmv_reconstruction = context->reconstruction; - struct libmv_CameraIntrinsics *libmv_intrinsics = libmv_ReconstructionExtractIntrinsics(libmv_reconstruction); + struct libmv_CameraIntrinsics *libmv_intrinsics = libmv_reconstructionExtractIntrinsics(libmv_reconstruction); float aspy = 1.0f / tracking->camera.pixel_aspect; double focal_length, principal_x, principal_y, k1, k2, k3; int width, height; - libmv_CameraIntrinsicsExtract(libmv_intrinsics, &focal_length, &principal_x, &principal_y, + libmv_cameraIntrinsicsExtract(libmv_intrinsics, &focal_length, &principal_x, &principal_y, &k1, &k2, &k3, &width, &height); tracking->camera.focal = focal_length; @@ -2987,13 +2987,13 @@ static int reconstruct_retrieve_libmv_tracks(MovieReconstructContext *context, M while (track) { double pos[3]; - if (libmv_reporojectionPointForTrack(libmv_reconstruction, tracknr, pos)) { + if (libmv_reprojectionPointForTrack(libmv_reconstruction, tracknr, pos)) { track->bundle_pos[0] = pos[0]; track->bundle_pos[1] = pos[1]; track->bundle_pos[2] = pos[2]; track->flag |= TRACK_HAS_BUNDLE; - track->error = libmv_reporojectionErrorForTrack(libmv_reconstruction, tracknr); + track->error = libmv_reprojectionErrorForTrack(libmv_reconstruction, tracknr); } else { track->flag &= ~TRACK_HAS_BUNDLE; @@ -3017,10 +3017,10 @@ static int reconstruct_retrieve_libmv_tracks(MovieReconstructContext *context, M for (a = sfra; a <= efra; a++) { double matd[4][4]; - if (libmv_reporojectionCameraForImage(libmv_reconstruction, a, matd)) { + if (libmv_reprojectionCameraForImage(libmv_reconstruction, a, matd)) { int i, j; float mat[4][4]; - float error = libmv_reporojectionErrorForImage(libmv_reconstruction, a); + float error = libmv_reprojectionErrorForImage(libmv_reconstruction, a); for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) @@ -3081,8 +3081,8 @@ static int reconstruct_retrieve_libmv_tracks(MovieReconstructContext *context, M /* Retrieve all the libmv data from context to blender's side data blocks. */ static int reconstruct_retrieve_libmv(MovieReconstructContext *context, MovieTracking *tracking) { - /* take the intrinscis back from libmv */ - reconstruct_retrieve_libmv_intrinscis(context, tracking); + /* take the intrinsics back from libmv */ + reconstruct_retrieve_libmv_intrinsics(context, tracking); return reconstruct_retrieve_libmv_tracks(context, tracking); } @@ -3243,7 +3243,7 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieTracking * void BKE_tracking_reconstruction_context_free(MovieReconstructContext *context) { if (context->reconstruction) - libmv_destroyReconstruction(context->reconstruction); + libmv_reconstructionDestroy(context->reconstruction); libmv_tracksDestroy(context->tracks); @@ -3266,7 +3266,7 @@ static void reconstruct_update_solve_cb(void *customdata, double progress, const } /* FIll in camera intrinsics structure from reconstruction context. */ -static void camraIntrincicsOptionsFromContext(libmv_cameraIntrinsicsOptions *camera_intrinsics_options, +static void camraIntrincicsOptionsFromContext(libmv_CameraIntrinsicsOptions *camera_intrinsics_options, MovieReconstructContext *context) { camera_intrinsics_options->focal_length = context->focal_length; @@ -3283,7 +3283,7 @@ static void camraIntrincicsOptionsFromContext(libmv_cameraIntrinsicsOptions *cam } /* Fill in reconstruction options structure from reconstruction context. */ -static void reconstructionOptionsFromContext(libmv_reconstructionOptions *reconstruction_options, +static void reconstructionOptionsFromContext(libmv_ReconstructionOptions *reconstruction_options, MovieReconstructContext *context) { reconstruction_options->select_keyframes = context->select_keyframes; @@ -3313,8 +3313,8 @@ void BKE_tracking_reconstruction_solve(MovieReconstructContext *context, short * ReconstructProgressData progressdata; - libmv_cameraIntrinsicsOptions camera_intrinsics_options; - libmv_reconstructionOptions reconstruction_options; + libmv_CameraIntrinsicsOptions camera_intrinsics_options; + libmv_ReconstructionOptions reconstruction_options; progressdata.stop = stop; progressdata.do_update = do_update; @@ -3558,7 +3558,7 @@ void BKE_tracking_detect_fast(MovieTracking *tracking, ListBase *tracksbase, ImB framenr, ibuf->x, ibuf->y, layer, place_outside_layer ? true : false); - libmv_destroyFeatures(features); + libmv_featuresDestroy(features); } /*********************** 2D stabilization *************************/ diff --git a/source/blender/blenlib/BLI_alloca.h b/source/blender/blenlib/BLI_alloca.h new file mode 100644 index 00000000000..b93f5b7123e --- /dev/null +++ b/source/blender/blenlib/BLI_alloca.h @@ -0,0 +1,46 @@ +/* + * ***** 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 ***** + */ + +#ifndef __BLI_ALLOCA_H__ + +/** \file BLI_alloca.h + * \ingroup bli + * + * Defines alloca and utility macro BLI_array_alloca + */ + +/* BLI_array_alloca / alloca */ +#ifdef _MSC_VER +# define alloca _alloca +#endif + +#if defined(__MINGW32__) +# include <malloc.h> /* mingw needs for alloca() */ +#endif + +#if defined(__GNUC__) || defined(__clang__) +#define BLI_array_alloca(arr, realsize) \ + (typeof(arr))alloca(sizeof(*arr) * (realsize)) +#else +#define BLI_array_alloca(arr, realsize) \ + alloca(sizeof(*arr) * (realsize)) +#endif + +#endif /* __BLI_ALLOCA_H__ */ diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h index 3fb50afdeac..566fc95eb4f 100644 --- a/source/blender/blenlib/BLI_array.h +++ b/source/blender/blenlib/BLI_array.h @@ -40,11 +40,11 @@ #define _bli_array_totalsize_dynamic(arr) ( \ ((arr) == NULL) ? \ 0 : \ - MEM_allocN_len(arr) / sizeof(*arr) \ + MEM_allocN_len(arr) / sizeof(*(arr)) \ ) #define _bli_array_totalsize_static(arr) \ - (sizeof(_##arr##_static) / sizeof(*arr)) + (sizeof(_##arr##_static) / sizeof(*(arr))) #define _bli_array_totalsize(arr) ( \ (size_t) \ @@ -66,8 +66,9 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static, /* -------------------------------------------------------------------- */ /* public defines */ +/* use sizeof(*(arr)) to ensure the array exists and is an array */ #define BLI_array_declare(arr) \ - int _##arr##_count = 0; \ + int _##arr##_count = ((void)(sizeof(*(arr))), 0); \ void *_##arr##_static = NULL /* this will use stack space, up to maxstatic array elements, before @@ -95,7 +96,7 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static, (LIKELY(_bli_array_totalsize(arr) >= _##arr##_count + num) ? \ (void)0 /* do nothing */ : \ _bli_array_grow_func((void **)&(arr), _##arr##_static, \ - sizeof(*arr), _##arr##_count, num, \ + sizeof(*(arr)), _##arr##_count, num, \ "BLI_array." #arr), \ (void)0) /* msvc2008 needs this */ \ ), \ @@ -148,8 +149,8 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static, /* only to prevent unused warnings */ #define BLI_array_fake_user(arr) \ - (void)_##arr##_count, \ - (void)_##arr##_static + ((void)_##arr##_count, \ + (void)_##arr##_static) /* -------------------------------------------------------------------- */ @@ -161,7 +162,7 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static, * but use when the max size is known ahead of time */ #define BLI_array_fixedstack_declare(arr, maxstatic, realsize, allocstr) \ char _##arr##_static[maxstatic * sizeof(*(arr))]; \ - const int _##arr##_is_static = ((void *)_##arr##_static) != ( \ + const bool _##arr##_is_static = ((void *)_##arr##_static) != ( \ arr = ((realsize) <= maxstatic) ? \ (void *)_##arr##_static : \ MEM_mallocN(sizeof(*(arr)) * (realsize), allocstr) \ @@ -173,30 +174,13 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static, } (void)0 -/* alloca */ -#ifdef _MSC_VER -# define alloca _alloca -#endif - -#if defined(__MINGW32__) -# include <malloc.h> /* mingw needs for alloca() */ -#endif - -#if defined(__GNUC__) || defined(__clang__) -#define BLI_array_alloca(arr, realsize) \ - (typeof(arr))alloca(sizeof(*arr) * (realsize)) - -#define BLI_array_alloca_and_count(arr, realsize) \ - (typeof(arr))alloca(sizeof(*arr) * (realsize)); \ - const int _##arr##_count = (realsize) +void _bli_array_reverse(void *arr, unsigned int arr_len, size_t arr_stride); +#define BLI_array_reverse(arr, arr_len) \ + _bli_array_reverse(arr, arr_len, sizeof(*(arr))) -#else -#define BLI_array_alloca(arr, realsize) \ - alloca(sizeof(*arr) * (realsize)) +void _bli_array_wrap(void *arr, unsigned int arr_len, size_t arr_stride, int dir); +#define BLI_array_wrap(arr, arr_len, dir) \ + _bli_array_wrap(arr, arr_len, sizeof(*(arr)), dir) -#define BLI_array_alloca_and_count(arr, realsize) \ - alloca(sizeof(*arr) * (realsize)); \ - const int _##arr##_count = (realsize) -#endif #endif /* __BLI_ARRAY_H__ */ diff --git a/source/blender/blenlib/BLI_bitmap.h b/source/blender/blenlib/BLI_bitmap.h index 02e5d6bd797..ca98d28cc40 100644 --- a/source/blender/blenlib/BLI_bitmap.h +++ b/source/blender/blenlib/BLI_bitmap.h @@ -26,7 +26,7 @@ #ifndef __BLI_BITMAP_H__ #define __BLI_BITMAP_H__ -typedef unsigned int *BLI_bitmap; +typedef unsigned int BLI_bitmap; /* warning: the bitmap does not keep track of its own size or check * for out-of-bounds access */ @@ -48,7 +48,7 @@ typedef unsigned int *BLI_bitmap; /* allocate memory for a bitmap with '_tot' bits; free * with MEM_freeN() */ #define BLI_BITMAP_NEW(_tot, _alloc_string) \ - ((BLI_bitmap)MEM_callocN(BLI_BITMAP_SIZE(_tot), \ + ((BLI_bitmap *)MEM_callocN(BLI_BITMAP_SIZE(_tot), \ _alloc_string)) /* get the value of a single bit at '_index' */ diff --git a/source/blender/blenlib/BLI_buffer.h b/source/blender/blenlib/BLI_buffer.h index fe835e7cadc..461b56e157f 100644 --- a/source/blender/blenlib/BLI_buffer.h +++ b/source/blender/blenlib/BLI_buffer.h @@ -53,11 +53,11 @@ enum { #define BLI_buffer_declare_static(type_, name_, flag_, static_count_) \ char name_ ## user; /* warn for free only */ \ - type_ *name_ ## _static_[static_count_]; \ + type_ name_ ## _static_[static_count_]; \ BLI_Buffer name_ = { \ /* clear the static memory if this is a calloc'd array */ \ ((void)((flag_ & BLI_BUFFER_USE_CALLOC) ? \ - memset(name_ ## _static_, 0, sizeof(name_ ## _static_)) : 0\ + memset(name_ ## _static_, 0, sizeof(name_ ## _static_)) : NULL \ ), /* memset-end */ \ name_ ## _static_), \ sizeof(type_), \ diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h index 930715b4bc6..3ad0e18c8d7 100644 --- a/source/blender/blenlib/BLI_ghash.h +++ b/source/blender/blenlib/BLI_ghash.h @@ -73,7 +73,7 @@ void *BLI_ghash_lookup(GHash *gh, const void *key); bool BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp); void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp); void *BLI_ghash_pop(GHash *gh, void *key, GHashKeyFreeFP keyfreefp); -bool BLI_ghash_haskey(GHash *gh, const void *key); +bool BLI_ghash_haskey(GHash *gh, const void *key); int BLI_ghash_size(GHash *gh); /* *** */ diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h index 4b71babdba1..69dbd3253f0 100644 --- a/source/blender/blenlib/BLI_math_base.h +++ b/source/blender/blenlib/BLI_math_base.h @@ -80,6 +80,14 @@ #define MAXFLOAT ((float)3.40282347e+38) #endif +#if defined(__GNUC__) +# define NAN_FLT __builtin_nanf("") +#else +/* evil quiet NaN definition */ +static const int NAN_INT = 0x7FC00000; +# define NAN_FLT (*((float *)(&NAN_INT))) +#endif + /* do not redefine functions from C99 or POSIX.1-2001 */ #if !(defined(_ISOC99_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L)) diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index f9671f57acd..6cb7103be9b 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -147,10 +147,6 @@ int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], int isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2]); int isect_point_tri_v2_int(const int x1, const int y1, const int x2, const int y2, const int a, const int b); bool isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3]); -void isect_point_quad_uv_v2(const float v0[2], const float v1[2], const float v2[2], const float v3[2], - const float pt[2], float r_uv[2]); -void isect_point_face_uv_v2(const int isquad, const float v0[2], const float v1[2], const float v2[2], - const float v3[2], const float pt[2], float r_uv[2]); /* axis-aligned bounding box */ bool isect_aabb_aabb_v3(const float min1[3], const float max1[3], const float min2[3], const float max2[3]); @@ -198,7 +194,7 @@ void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3 void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const float v3[2], const float v4[2], const float co[2], float w[4]); -int barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]); +bool barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]); int barycentric_inside_triangle_v2(const float w[3]); void resolve_tri_uv(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2]); @@ -273,9 +269,9 @@ MINLINE void madd_sh_shfl(float r[9], const float sh[3], const float f); float form_factor_quad(const float p[3], const float n[3], const float q0[3], const float q1[3], const float q2[3], const float q3[3]); -int form_factor_visible_quad(const float p[3], const float n[3], - const float v0[3], const float v1[3], const float v2[3], - float q0[3], float q1[3], float q2[3], float q3[3]); +bool form_factor_visible_quad(const float p[3], const float n[3], + const float v0[3], const float v1[3], const float v2[3], + float q0[3], float q1[3], float q2[3], float q3[3]); float form_factor_hemi_poly(float p[3], float n[3], float v1[3], float v2[3], float v3[3], float v4[3]); diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index 723122d7814..c305cc9a030 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -133,12 +133,12 @@ void normalize_m4_m4(float R[4][4], float A[4][4]); void orthogonalize_m3(float R[3][3], int axis); void orthogonalize_m4(float R[4][4], int axis); -int is_orthogonal_m3(float mat[3][3]); -int is_orthogonal_m4(float mat[4][4]); -int is_orthonormal_m3(float mat[3][3]); -int is_orthonormal_m4(float mat[4][4]); +bool is_orthogonal_m3(float mat[3][3]); +bool is_orthogonal_m4(float mat[4][4]); +bool is_orthonormal_m3(float mat[3][3]); +bool is_orthonormal_m4(float mat[4][4]); -int is_uniform_scaled_m3(float mat[3][3]); +bool is_uniform_scaled_m3(float mat[3][3]); void adjoint_m2_m2(float R[2][2], float A[2][2]); void adjoint_m3_m3(float R[3][3], float A[3][3]); @@ -175,7 +175,7 @@ void mat4_to_size(float r[3], float M[4][4]); void translate_m4(float mat[4][4], float tx, float ty, float tz); void rotate_m4(float mat[4][4], const char axis, const float angle); void rotate_m2(float mat[2][2], const float angle); - +void transform_pivot_set_m4(float mat[4][4], const float pivot[3]); void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]); void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4]); @@ -194,8 +194,11 @@ void loc_axisangle_size_to_mat4(float R[4][4], void blend_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], const float t); void blend_m4_m4m4(float R[4][4], float A[4][4], float B[4][4], const float t); -int is_negative_m3(float mat[3][3]); -int is_negative_m4(float mat[4][4]); +bool is_negative_m3(float mat[3][3]); +bool is_negative_m4(float mat[4][4]); + +bool is_zero_m3(float mat[3][3]); +bool is_zero_m4(float mat[4][4]); /*********************************** Other ***********************************/ diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 304e2ea7fde..e163c06440c 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -36,10 +36,6 @@ extern "C" { #include "BLI_math_inline.h" -#if BLI_MATH_DO_INLINE -#include "intern/math_vector_inline.c" -#endif - /************************************* Init ***********************************/ #ifdef BLI_MATH_GCC_WARN_PRAGMA @@ -47,6 +43,12 @@ extern "C" { # pragma GCC diagnostic ignored "-Wredundant-decls" #endif +#ifdef __GNUC__ +# define UNUSED_RESULT_ATTR __attribute__((warn_unused_result)) +#else +# define UNUSED_RESULT_ATTR +#endif + MINLINE void zero_v2(float r[2]); MINLINE void zero_v3(float r[3]); MINLINE void zero_v4(float r[4]); @@ -115,7 +117,10 @@ MINLINE void mul_v3_v3(float r[3], const float a[3]); MINLINE void mul_v3_v3v3(float r[3], const float a[3], const float b[3]); MINLINE void mul_v4_fl(float r[4], float f); MINLINE void mul_v4_v4fl(float r[3], const float a[3], float f); -MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3]); +MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3]) UNUSED_RESULT_ATTR; +MINLINE float dot_m3_v3_row_x(float M[3][3], const float a[3]) UNUSED_RESULT_ATTR; +MINLINE float dot_m3_v3_row_y(float M[3][3], const float a[3]) UNUSED_RESULT_ATTR; +MINLINE float dot_m3_v3_row_z(float M[3][3], const float a[3]) UNUSED_RESULT_ATTR; MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f); MINLINE void madd_v3_v3v3(float r[3], const float a[3], const float b[3]); @@ -134,10 +139,10 @@ MINLINE void negate_v4_v4(float r[4], const float a[3]); MINLINE void negate_v3_short(short r[3]); -MINLINE float dot_v2v2(const float a[2], const float b[2]); -MINLINE float dot_v3v3(const float a[3], const float b[3]); +MINLINE float dot_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR; +MINLINE float dot_v3v3(const float a[3], const float b[3]) UNUSED_RESULT_ATTR; -MINLINE float cross_v2v2(const float a[2], const float b[2]); +MINLINE float cross_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR; MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3]); MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3]); @@ -146,20 +151,20 @@ MINLINE void star_m3_v3(float rmat[3][3], float a[3]); /*********************************** Length **********************************/ -MINLINE float len_squared_v2(const float v[2]); -MINLINE float len_squared_v3(const float v[3]); -MINLINE float len_manhattan_v2(const float v[2]); -MINLINE int len_manhattan_v2_int(const int v[2]); -MINLINE float len_manhattan_v3(const float v[3]); -MINLINE float len_v2(const float a[2]); -MINLINE float len_v2v2(const float a[2], const float b[2]); -MINLINE float len_squared_v2v2(const float a[2], const float b[2]); -MINLINE float len_squared_v3v3(const float a[3], const float b[3]); -MINLINE float len_manhattan_v2v2(const float a[2], const float b[2]); -MINLINE int len_manhattan_v2v2_int(const int a[2], const int b[2]); -MINLINE float len_manhattan_v3v3(const float a[3], const float b[3]); -MINLINE float len_v3(const float a[3]); -MINLINE float len_v3v3(const float a[3], const float b[3]); +MINLINE float len_squared_v2(const float v[2]) UNUSED_RESULT_ATTR; +MINLINE float len_squared_v3(const float v[3]) UNUSED_RESULT_ATTR; +MINLINE float len_manhattan_v2(const float v[2]) UNUSED_RESULT_ATTR; +MINLINE int len_manhattan_v2_int(const int v[2]) UNUSED_RESULT_ATTR; +MINLINE float len_manhattan_v3(const float v[3]) UNUSED_RESULT_ATTR; +MINLINE float len_v2(const float a[2]) UNUSED_RESULT_ATTR; +MINLINE float len_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR; +MINLINE float len_squared_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR; +MINLINE float len_squared_v3v3(const float a[3], const float b[3]) UNUSED_RESULT_ATTR; +MINLINE float len_manhattan_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR; +MINLINE int len_manhattan_v2v2_int(const int a[2], const int b[2]) UNUSED_RESULT_ATTR; +MINLINE float len_manhattan_v3v3(const float a[3], const float b[3]) UNUSED_RESULT_ATTR; +MINLINE float len_v3(const float a[3]) UNUSED_RESULT_ATTR; +MINLINE float len_v3v3(const float a[3], const float b[3]) UNUSED_RESULT_ATTR; MINLINE float normalize_v2(float r[2]); MINLINE float normalize_v2_v2(float r[2], const float a[2]); @@ -191,35 +196,35 @@ void flip_v2_v2v2(float v[2], const float v1[2], const float v2[2]); /********************************* Comparison ********************************/ -MINLINE int is_zero_v3(const float a[3]); -MINLINE int is_zero_v4(const float a[4]); -MINLINE int is_one_v3(const float a[3]); +MINLINE int is_zero_v3(const float a[3]) UNUSED_RESULT_ATTR; +MINLINE int is_zero_v4(const float a[4]) UNUSED_RESULT_ATTR; +MINLINE int is_one_v3(const float a[3]) UNUSED_RESULT_ATTR; -MINLINE int equals_v2v2(const float v1[2], const float v2[2]); -MINLINE int equals_v3v3(const float a[3], const float b[3]); -MINLINE int compare_v2v2(const float a[2], const float b[2], const float limit); -MINLINE int compare_v3v3(const float a[3], const float b[3], const float limit); -MINLINE int compare_len_v3v3(const float a[3], const float b[3], const float limit); +MINLINE int equals_v2v2(const float v1[2], const float v2[2]) UNUSED_RESULT_ATTR; +MINLINE int equals_v3v3(const float a[3], const float b[3]) UNUSED_RESULT_ATTR; +MINLINE int compare_v2v2(const float a[2], const float b[2], const float limit) UNUSED_RESULT_ATTR; +MINLINE int compare_v3v3(const float a[3], const float b[3], const float limit) UNUSED_RESULT_ATTR; +MINLINE int compare_len_v3v3(const float a[3], const float b[3], const float limit) UNUSED_RESULT_ATTR; -MINLINE int compare_v4v4(const float a[4], const float b[4], const float limit); -MINLINE int equals_v4v4(const float a[4], const float b[4]); +MINLINE int compare_v4v4(const float a[4], const float b[4], const float limit) UNUSED_RESULT_ATTR; +MINLINE int equals_v4v4(const float a[4], const float b[4]) UNUSED_RESULT_ATTR; -MINLINE float line_point_side_v2(const float l1[2], const float l2[2], const float pt[2]); +MINLINE float line_point_side_v2(const float l1[2], const float l2[2], const float pt[2]) UNUSED_RESULT_ATTR; /********************************** Angles ***********************************/ /* - angle with 2 arguments is angle between vector */ /* - angle with 3 arguments is angle between 3 points at the middle point */ /* - angle_normalized_* is faster equivalent if vectors are normalized */ -float angle_v2v2(const float a[2], const float b[2]); -float angle_signed_v2v2(const float v1[2], const float v2[2]); -float angle_v2v2v2(const float a[2], const float b[2], const float c[2]); -float angle_normalized_v2v2(const float a[2], const float b[2]); -float angle_v3v3(const float a[3], const float b[3]); -float angle_v3v3v3(const float a[3], const float b[3], const float c[3]); -float cos_v3v3v3(const float p1[3], const float p2[3], const float p3[3]); -float angle_normalized_v3v3(const float v1[3], const float v2[3]); -float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]); +float angle_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR; +float angle_signed_v2v2(const float v1[2], const float v2[2]) UNUSED_RESULT_ATTR; +float angle_v2v2v2(const float a[2], const float b[2], const float c[2]) UNUSED_RESULT_ATTR; +float angle_normalized_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR; +float angle_v3v3(const float a[3], const float b[3]) UNUSED_RESULT_ATTR; +float angle_v3v3v3(const float a[3], const float b[3], const float c[3]) UNUSED_RESULT_ATTR; +float cos_v3v3v3(const float p1[3], const float p2[3], const float p3[3]) UNUSED_RESULT_ATTR; +float angle_normalized_v3v3(const float v1[3], const float v2[3]) UNUSED_RESULT_ATTR; +float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]) UNUSED_RESULT_ATTR; void angle_tri_v3(float angles[3], const float v1[3], const float v2[3], const float v3[3]); void angle_quad_v3(float angles[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3]); void angle_poly_v3(float *angles, const float *verts[3], int len); @@ -255,7 +260,7 @@ void axis_sort_v3(const float axis_values[3], int r_axis_order[3]); /***************************** Array Functions *******************************/ /* attempted to follow fixed length vertex functions. names could be improved*/ -double dot_vn_vn(const float *array_src_a, const float *array_src_b, const int size); +double dot_vn_vn(const float *array_src_a, const float *array_src_b, const int size) UNUSED_RESULT_ATTR; float normalize_vn_vn(float *array_tar, const float *array_src, const int size); float normalize_vn(float *array_tar, const int size); void range_vn_i(int *array_tar, const int size, const int start); @@ -277,9 +282,16 @@ void fill_vn_i(int *array_tar, const int size, const int val); void fill_vn_ushort(unsigned short *array_tar, const int size, const unsigned short val); void fill_vn_fl(float *array_tar, const int size, const float val); +/**************************** Inline Definitions ******************************/ + +#if BLI_MATH_DO_INLINE +#include "intern/math_vector_inline.c" +#endif + #ifdef BLI_MATH_GCC_WARN_PRAGMA # pragma GCC diagnostic pop #endif +#undef UNUSED_RESULT_ATTR #ifdef __cplusplus } diff --git a/source/blender/blenlib/BLI_memarena.h b/source/blender/blenlib/BLI_memarena.h index 092bb639b91..d54dab42e05 100644 --- a/source/blender/blenlib/BLI_memarena.h +++ b/source/blender/blenlib/BLI_memarena.h @@ -55,6 +55,7 @@ typedef struct MemArena MemArena; struct MemArena *BLI_memarena_new(const int bufsize, const char *name) #if MEM_GNU_ATTRIBUTES +__attribute__((malloc)) __attribute__((warn_unused_result)) __attribute__((nonnull(2))) #endif @@ -85,6 +86,7 @@ __attribute__((nonnull(1))) void *BLI_memarena_alloc(struct MemArena *ma, int size) #if MEM_GNU_ATTRIBUTES +__attribute__((malloc)) __attribute__((warn_unused_result)) __attribute__((nonnull(1))) __attribute__((alloc_size(2))) diff --git a/source/blender/blenlib/BLI_mempool.h b/source/blender/blenlib/BLI_mempool.h index a1cbad73239..1c470d59062 100644 --- a/source/blender/blenlib/BLI_mempool.h +++ b/source/blender/blenlib/BLI_mempool.h @@ -50,17 +50,20 @@ typedef struct BLI_mempool BLI_mempool; BLI_mempool *BLI_mempool_create(int esize, int totelem, int pchunk, int flag) #ifdef __GNUC__ +__attribute__((malloc)) __attribute__((warn_unused_result)) #endif ; void *BLI_mempool_alloc(BLI_mempool *pool) #ifdef __GNUC__ +__attribute__((malloc)) __attribute__((warn_unused_result)) __attribute__((nonnull(1))) #endif ; void *BLI_mempool_calloc(BLI_mempool *pool) #ifdef __GNUC__ +__attribute__((malloc)) __attribute__((warn_unused_result)) __attribute__((nonnull(1))) #endif @@ -86,14 +89,29 @@ __attribute__((warn_unused_result)) __attribute__((nonnull(1))) #endif ; -void BLI_mempool_as_array(BLI_mempool *pool, void **data) +void BLI_mempool_as_table(BLI_mempool *pool, void **data) #ifdef __GNUC__ -__attribute__((nonnull(1))) +__attribute__((nonnull(1, 2))) +#endif +; + +void **BLI_mempool_as_tableN(BLI_mempool *pool, const char *allocstr) +#ifdef __GNUC__ +__attribute__((malloc)) +__attribute__((warn_unused_result)) +__attribute__((nonnull(1, 2))) +#endif +; + +void BLI_mempool_as_array(BLI_mempool *pool, void *data) +#ifdef __GNUC__ +__attribute__((nonnull(1, 2))) #endif ; -void *BLI_mempool_as_arrayN(BLI_mempool *pool, const char *allocstr) +void *BLI_mempool_as_arrayN(BLI_mempool *pool, const char *allocstr) #ifdef __GNUC__ +__attribute__((malloc)) __attribute__((warn_unused_result)) __attribute__((nonnull(1, 2))) #endif diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h index e0a34e35acc..cb812fe8595 100644 --- a/source/blender/blenlib/BLI_path_util.h +++ b/source/blender/blenlib/BLI_path_util.h @@ -89,7 +89,18 @@ void BLI_make_existing_file(const char *name); void BLI_split_dirfile(const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen); void BLI_split_dir_part(const char *string, char *dir, const size_t dirlen); void BLI_split_file_part(const char *string, char *file, const size_t filelen); -void BLI_join_dirfile(char *string, const size_t maxlen, const char *dir, const char *file); +void BLI_path_append(char *__restrict dst, const size_t maxlen, + const char *__restrict file) +#ifdef __GNUC__ +__attribute__((nonnull)) +#endif +; +void BLI_join_dirfile(char *__restrict string, const size_t maxlen, + const char *__restrict dir, const char *__restrict file) +#ifdef __GNUC__ +__attribute__((nonnull)) +#endif +; const char *BLI_path_basename(const char *path); typedef enum bli_rebase_state { diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h index 02eb0734f8c..6c66d2f4e18 100644 --- a/source/blender/blenlib/BLI_string.h +++ b/source/blender/blenlib/BLI_string.h @@ -40,6 +40,7 @@ extern "C" { char *BLI_strdupn(const char *str, const size_t len) #ifdef __GNUC__ +__attribute__((malloc)) __attribute__((warn_unused_result)) __attribute__((nonnull)) #endif @@ -47,6 +48,7 @@ __attribute__((nonnull)) char *BLI_strdup(const char *str) #ifdef __GNUC__ +__attribute__((malloc)) __attribute__((warn_unused_result)) __attribute__((nonnull)) #endif @@ -54,6 +56,7 @@ __attribute__((nonnull)) char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2) #ifdef __GNUC__ +__attribute__((malloc)) __attribute__((warn_unused_result)) __attribute__((nonnull)) #endif @@ -81,13 +84,15 @@ __attribute__((nonnull)) char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix) #ifdef __GNUC__ +__attribute__((malloc)) __attribute__((warn_unused_result)) __attribute__((nonnull)) #endif ; -char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const char *__restrict newText) +char *BLI_replacestrN(const char *__restrict str, const char *__restrict substr_old, const char *__restrict substr_new) #ifdef __GNUC__ +__attribute__((malloc)) __attribute__((warn_unused_result)) __attribute__((nonnull)) #endif @@ -108,6 +113,7 @@ __attribute__ ((format(printf, 3, 0))) char *BLI_sprintfN(const char *__restrict format, ...) #ifdef __GNUC__ +__attribute__((malloc)) __attribute__ ((format(printf, 1, 2))) __attribute__((warn_unused_result)) __attribute__((nonnull)) @@ -183,4 +189,4 @@ __attribute__((nonnull)) } #endif -#endif +#endif /* __BLI_STRING_H__ */ diff --git a/source/blender/blenlib/BLI_string_utf8.h b/source/blender/blenlib/BLI_string_utf8.h index adef843d2cc..db32190494a 100644 --- a/source/blender/blenlib/BLI_string_utf8.h +++ b/source/blender/blenlib/BLI_string_utf8.h @@ -31,43 +31,57 @@ extern "C" { #endif -char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy); -char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy); -int BLI_utf8_invalid_byte(const char *str, int length); -int BLI_utf8_invalid_strip(char *str, int length); +#ifdef __GNUC__ +# define ATTR_NONULL __attribute__((nonnull)) +# define ATTR_NONULL_FIRST __attribute__((nonnull(1))) +# define ATTR_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +# define ATTR_NONULL +# define ATTR_NONULL_FIRST +# define ATTR_UNUSED_RESULT +#endif + +char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONULL; +char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONULL; +int BLI_utf8_invalid_byte(const char *str, int length) ATTR_NONULL; +int BLI_utf8_invalid_strip(char *str, int length) ATTR_NONULL; -int BLI_str_utf8_size(const char *p); /* warning, can return -1 on bad chars */ -int BLI_str_utf8_size_safe(const char *p); +int BLI_str_utf8_size(const char *p) ATTR_NONULL; /* warning, can return -1 on bad chars */ +int BLI_str_utf8_size_safe(const char *p) ATTR_NONULL; /* copied from glib */ -unsigned int BLI_str_utf8_as_unicode(const char *p); -unsigned int BLI_str_utf8_as_unicode_and_size(const char *__restrict p, size_t *__restrict index); -unsigned int BLI_str_utf8_as_unicode_and_size_safe(const char *__restrict p, size_t *__restrict index); -unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__restrict index); +unsigned int BLI_str_utf8_as_unicode(const char *p) ATTR_NONULL; +unsigned int BLI_str_utf8_as_unicode_and_size(const char *__restrict p, size_t *__restrict index) ATTR_NONULL; +unsigned int BLI_str_utf8_as_unicode_and_size_safe(const char *__restrict p, size_t *__restrict index) ATTR_NONULL; +unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__restrict index) ATTR_NONULL; size_t BLI_str_utf8_from_unicode(unsigned int c, char *outbuf); -char *BLI_str_find_prev_char_utf8(const char *str, const char *p); -char *BLI_str_find_next_char_utf8(const char *p, const char *end); -char *BLI_str_prev_char_utf8(const char *p); +char *BLI_str_find_prev_char_utf8(const char *str, const char *p) ATTR_NONULL; +char *BLI_str_find_next_char_utf8(const char *p, const char *end) ATTR_NONULL_FIRST; +char *BLI_str_prev_char_utf8(const char *p) ATTR_NONULL; /* wchar_t functions, copied from blenders own font.c originally */ -size_t BLI_wstrlen_utf8(const wchar_t *src); -size_t BLI_strlen_utf8_ex(const char *strc, int *r_len_bytes); -size_t BLI_strlen_utf8(const char *strc); -size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, int *r_len_bytes); -size_t BLI_strnlen_utf8(const char *strc, const size_t maxlen); -size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxcpy); -size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst, const char *__restrict src, const size_t maxcpy); +size_t BLI_wstrlen_utf8(const wchar_t *src) ATTR_NONULL; +size_t BLI_strlen_utf8_ex(const char *strc, size_t *r_len_bytes) ATTR_NONULL; +size_t BLI_strlen_utf8(const char *strc) ATTR_NONULL; +size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, size_t *r_len_bytes) ATTR_NONULL; +size_t BLI_strnlen_utf8(const char *strc, const size_t maxlen) ATTR_NONULL; +size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxcpy) ATTR_NONULL; +size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst, const char *__restrict src, const size_t maxcpy) ATTR_NONULL; /* count columns that character/string occupies, based on wcwidth.c */ int BLI_wcwidth(wchar_t ucs); -int BLI_wcswidth(const wchar_t *pwcs, size_t n); -int BLI_str_utf8_char_width(const char *p); /* warning, can return -1 on bad chars */ -int BLI_str_utf8_char_width_safe(const char *p); +int BLI_wcswidth(const wchar_t *pwcs, size_t n) ATTR_NONULL; +int BLI_str_utf8_char_width(const char *p) ATTR_NONULL; /* warning, can return -1 on bad chars */ +int BLI_str_utf8_char_width_safe(const char *p) ATTR_NONULL; #define BLI_UTF8_MAX 6 /* mem */ #define BLI_UTF8_WIDTH_MAX 2 /* columns */ #define BLI_UTF8_ERR ((unsigned int)-1) +#undef ATTR_NONULL +#undef ATTR_NONULL_FIRST +#undef ATTR_UNUSED_RESULT + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index 4d80080ed86..63235ad9c82 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -388,8 +388,11 @@ # define BLI_assert(a) (void)0 #endif -/* C++ can't use _Static_assert, expects static_assert() but c++0x only */ -#if (!defined(__cplusplus)) && (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 406)) /* gcc4.6+ only */ +/* C++ can't use _Static_assert, expects static_assert() but c++0x only, + * Coverity also errors out. */ +#if (!defined(__cplusplus)) && \ + (!defined(__COVERITY__)) && \ + (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 406)) /* gcc4.6+ only */ # define BLI_STATIC_ASSERT(a, msg) _Static_assert(a, msg); #else /* TODO msvc, clang */ diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 1d94ca9afbc..b6b69116e67 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -99,6 +99,7 @@ set(SRC intern/winstuff.c BLI_args.h + BLI_alloca.h BLI_array.h BLI_bitmap.h BLI_blenlib.h diff --git a/source/blender/blenlib/intern/BLI_array.c b/source/blender/blenlib/intern/BLI_array.c index 5823b7db3f1..510bf072513 100644 --- a/source/blender/blenlib/intern/BLI_array.c +++ b/source/blender/blenlib/intern/BLI_array.c @@ -59,9 +59,14 @@ */ #include <string.h> +#include <stdlib.h> #include "BLI_array.h" +#include "BLI_sys_types.h" +#include "BLI_utildefines.h" +#include "BLI_alloca.h" + #include "MEM_guardedalloc.h" /** @@ -95,3 +100,40 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static, arr_count += num; #endif } + +void _bli_array_reverse(void *arr_v, unsigned int arr_len, size_t arr_stride) +{ + const unsigned int arr_half_stride = (arr_len / 2) * arr_stride; + unsigned int i, i_end; + char *arr = arr_v; + char *buf = BLI_array_alloca(buf, arr_stride); + + for (i = 0, i_end = (arr_len - 1) * arr_stride; + i < arr_half_stride; + i += arr_stride, i_end -= arr_stride) + { + memcpy(buf, &arr[i], arr_stride); + memcpy(&arr[i], &arr[i_end], arr_stride); + memcpy(&arr[i_end], buf, arr_stride); + } +} + +void _bli_array_wrap(void *arr_v, unsigned int arr_len, size_t arr_stride, int dir) +{ + char *arr = arr_v; + char *buf = BLI_array_alloca(buf, arr_stride); + + if (dir == -1) { + memcpy(buf, arr, arr_stride); + memmove(arr, arr + arr_stride, arr_stride * (arr_len - 1)); + memcpy(arr + (arr_stride * (arr_len - 1)), buf, arr_stride); + } + else if (dir == 1) { + memcpy(buf, arr + (arr_stride * (arr_len - 1)), arr_stride); + memmove(arr + arr_stride, arr, arr_stride * (arr_len - 1)); + memcpy(arr, buf, arr_stride); + } + else { + BLI_assert(0); + } +} diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index 10b3c01d274..14dfbcffebe 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -179,7 +179,8 @@ void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfree gh->nentries = 0; gh->nbuckets = hashsizes[gh->cursize]; - gh->buckets = MEM_recallocN(gh->buckets, gh->nbuckets * sizeof(*gh->buckets)); + MEM_freeN(gh->buckets); + gh->buckets = MEM_callocN(gh->nbuckets * sizeof(*gh->buckets), "buckets"); } /* same as above but return the value, diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c index c645db4c15e..0aaa3e13b3f 100644 --- a/source/blender/blenlib/intern/BLI_heap.c +++ b/source/blender/blenlib/intern/BLI_heap.c @@ -163,7 +163,7 @@ HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr) { HeapNode *node; - if (UNLIKELY((heap->size + 1) > heap->bufsize)) { + if (UNLIKELY(heap->size >= heap->bufsize)) { heap->bufsize *= 2; heap->tree = MEM_reallocN(heap->tree, heap->bufsize * sizeof(*heap->tree)); } @@ -184,7 +184,7 @@ HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr) heap->size++; - heap_up(heap, heap->size - 1); + heap_up(heap, node->index); return node; } @@ -230,6 +230,8 @@ void BLI_heap_remove(Heap *heap, HeapNode *node) { unsigned int i = node->index; + BLI_assert(heap->size != 0); + while (i > 0) { unsigned int p = HEAP_PARENT(i); diff --git a/source/blender/blenlib/intern/BLI_kdtree.c b/source/blender/blenlib/intern/BLI_kdtree.c index 0e7602b7e6b..dd54fe681b0 100644 --- a/source/blender/blenlib/intern/BLI_kdtree.c +++ b/source/blender/blenlib/intern/BLI_kdtree.c @@ -349,7 +349,7 @@ static void add_in_range(KDTreeNearest **ptn, int found, int *totfoundstack, int { KDTreeNearest *to; - if (found + 1 > *totfoundstack) { + if (found >= *totfoundstack) { KDTreeNearest *temp = MEM_callocN((*totfoundstack + 50) * sizeof(KDTreeNode), "psys_treefoundstack"); memcpy(temp, *ptn, *totfoundstack * sizeof(KDTreeNearest)); if (*ptn) diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c index 217a4b9d266..bb326a23d59 100644 --- a/source/blender/blenlib/intern/BLI_mempool.c +++ b/source/blender/blenlib/intern/BLI_mempool.c @@ -334,27 +334,56 @@ void *BLI_mempool_findelem(BLI_mempool *pool, int index) } /** + * Fill in \a data with pointers to each element of the mempool, + * to create lookup table. + * * \param data array of pointers at least the size of 'pool->totused' */ -void BLI_mempool_as_array(BLI_mempool *pool, void **data) +void BLI_mempool_as_table(BLI_mempool *pool, void **data) { BLI_mempool_iter iter; void *elem; void **p = data; BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER); BLI_mempool_iternew(pool, &iter); - for (elem = BLI_mempool_iterstep(&iter); elem; elem = BLI_mempool_iterstep(&iter)) { + while ((elem = BLI_mempool_iterstep(&iter))) { *p++ = elem; } BLI_assert((p - data) == pool->totused); } /** - * Allocate an array from the mempool. + * A version of #BLI_mempool_as_table that allocates and returns the data. + */ +void **BLI_mempool_as_tableN(BLI_mempool *pool, const char *allocstr) +{ + void **data = MEM_mallocN((size_t)pool->totused * sizeof(void *), allocstr); + BLI_mempool_as_table(pool, data); + return data; +} + +/** + * Fill in \a data with the contents of the mempool. + */ +void BLI_mempool_as_array(BLI_mempool *pool, void *data) +{ + BLI_mempool_iter iter; + char *elem, *p = data; + BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER); + BLI_mempool_iternew(pool, &iter); + while ((elem = BLI_mempool_iterstep(&iter))) { + memcpy(p, elem, (size_t)pool->esize); + p += pool->esize; + } + BLI_assert((p - (char *)data) == pool->totused * pool->esize); +} + +/** + * A version of #BLI_mempool_as_array that allocates and returns the data. */ void *BLI_mempool_as_arrayN(BLI_mempool *pool, const char *allocstr) { - void *data = MEM_mallocN((size_t)(BLI_mempool_count(pool) * pool->esize), allocstr); + char *data = MEM_mallocN((size_t)(pool->totused * pool->esize), allocstr); BLI_mempool_as_array(pool, data); return data; } diff --git a/source/blender/blenlib/intern/buffer.c b/source/blender/blenlib/intern/buffer.c index aac3a3bc3f3..36fb04a7bb7 100644 --- a/source/blender/blenlib/intern/buffer.c +++ b/source/blender/blenlib/intern/buffer.c @@ -34,9 +34,12 @@ static void *buffer_alloc(BLI_Buffer *buffer, int len) static void *buffer_realloc(BLI_Buffer *buffer, int len) { - return ((buffer->flag & BLI_BUFFER_USE_CALLOC) ? - MEM_recallocN : MEM_reallocN) - (buffer->data, (buffer->elem_size * len)); + if (buffer->flag & BLI_BUFFER_USE_CALLOC) { + return MEM_recallocN(buffer->data, buffer->elem_size * len); + } + else { + return MEM_reallocN(buffer->data, buffer->elem_size * len); + } } void BLI_buffer_resize(BLI_Buffer *buffer, int new_count) diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index 26b9e08c7f6..4809ba59aaf 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -445,7 +445,7 @@ static void join_dirfile_alloc(char **dst, size_t *alloc_len, const char *dir, c size_t len = strlen(dir) + strlen(file) + 1; if (*dst == NULL) - *dst = MEM_callocN(len + 1, "join_dirfile_alloc path"); + *dst = MEM_mallocN(len + 1, "join_dirfile_alloc path"); else if (*alloc_len < len) *dst = MEM_reallocN(*dst, len + 1); @@ -911,18 +911,15 @@ void BLI_dir_create_recursive(const char *dirname) char static_buf[MAXPATHLEN]; #endif char *tmp; - int needs_free; if (BLI_exists(dirname)) return; #ifdef MAXPATHLEN size = MAXPATHLEN; tmp = static_buf; - needs_free = 0; #else size = strlen(dirname) + 1; - tmp = MEM_callocN(size, "BLI_dir_create_recursive tmp"); - needs_free = 1; + tmp = MEM_callocN(size, __func__); #endif BLI_strncpy(tmp, dirname, size); @@ -934,8 +931,9 @@ void BLI_dir_create_recursive(const char *dirname) BLI_dir_create_recursive(tmp); } - if (needs_free) - MEM_freeN(tmp); +#ifndef MAXPATHLEN + MEM_freeN(tmp); +#endif mkdir(dirname, 0777); } diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 0e7ff521ce8..9b8fd0ad85b 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -695,60 +695,6 @@ int isect_line_sphere_v2(const float l1[2], const float l2[2], } } -/** - * \return - * -1: collinear - * 1: intersection - */ -static short IsectLLPt2Df(const float x0, const float y0, const float x1, const float y1, - const float x2, const float y2, const float x3, const float y3, float *xi, float *yi) - -{ - /* - * this function computes the intersection of the sent lines - * and returns the intersection point, note that the function assumes - * the lines intersect. the function can handle vertical as well - * as horizontal lines. note the function isn't very clever, it simply - * applies the math, but we don't need speed since this is a - * pre-processing step - */ - float c1, c2; /* constants of linear equations */ - float det_inv; /* the inverse of the determinant of the coefficient */ - float m1, m2; /* the slopes of each line */ - /* - * compute slopes, note the cludge for infinity, however, this will - * be close enough - */ - if (fabsf(x1 - x0) > 0.000001f) - m1 = (y1 - y0) / (x1 - x0); - else - return -1; /*m1 = (float)1e+10;*/ /* close enough to infinity */ - - if (fabsf(x3 - x2) > 0.000001f) - m2 = (y3 - y2) / (x3 - x2); - else - return -1; /*m2 = (float)1e+10;*/ /* close enough to infinity */ - - if (fabsf(m1 - m2) < 0.000001f) - return -1; /* parallel lines */ - - /* compute constants */ - - c1 = (y0 - m1 * x0); - c2 = (y2 - m2 * x2); - - /* compute the inverse of the determinate */ - - det_inv = 1.0f / (-m1 + m2); - - /* use Kramers rule to compute xi and yi */ - - *xi = ((-c2 + c1) * det_inv); - *yi = ((m2 * c1 - m1 * c2) * det_inv); - - return 1; -} - /* point in polygon (keep float and int versions in sync) */ bool isect_point_poly_v2(const float pt[2], const float verts[][2], const int nr) { @@ -1718,193 +1664,6 @@ void limit_dist_v3(float v1[3], float v2[3], const float dist) } } -/* Similar to LineIntersectsTriangleUV, except it operates on a quad and in 2d, assumes point is in quad */ -void isect_point_quad_uv_v2(const float v0[2], const float v1[2], const float v2[2], const float v3[2], - const float pt[2], float r_uv[2]) -{ - float x0, y0, x1, y1, wtot, v2d[2], w1, w2; - - /* used for parallel lines */ - float pt3d[3], l1[3], l2[3], pt_on_line[3]; - - /* compute 2 edges of the quad intersection point */ - if (IsectLLPt2Df(v0[0], v0[1], v1[0], v1[1], v2[0], v2[1], v3[0], v3[1], &x0, &y0) == 1) { - /* the intersection point between the quad-edge intersection and the point in the quad we want the uv's for */ - /* should never be paralle !! */ - /*printf("\tnot parallel 1\n");*/ - IsectLLPt2Df(pt[0], pt[1], x0, y0, v0[0], v0[1], v3[0], v3[1], &x1, &y1); - - /* Get the weights from the new intersection point, to each edge */ - v2d[0] = x1 - v0[0]; - v2d[1] = y1 - v0[1]; - w1 = len_v2(v2d); - - v2d[0] = x1 - v3[0]; /* some but for the other vert */ - v2d[1] = y1 - v3[1]; - w2 = len_v2(v2d); - wtot = w1 + w2; - /*w1 = w1/wtot;*/ - /*w2 = w2/wtot;*/ - r_uv[0] = w1 / wtot; - } - else { - /* lines are parallel, lambda_cp_line_ex is 3d grrr */ - /*printf("\tparallel1\n");*/ - pt3d[0] = pt[0]; - pt3d[1] = pt[1]; - pt3d[2] = l1[2] = l2[2] = 0.0f; - - l1[0] = v0[0]; - l1[1] = v0[1]; - l2[0] = v1[0]; - l2[1] = v1[1]; - closest_to_line_v3(pt_on_line, pt3d, l1, l2); - v2d[0] = pt[0] - pt_on_line[0]; /* same, for the other vert */ - v2d[1] = pt[1] - pt_on_line[1]; - w1 = len_v2(v2d); - - l1[0] = v2[0]; - l1[1] = v2[1]; - l2[0] = v3[0]; - l2[1] = v3[1]; - closest_to_line_v3(pt_on_line, pt3d, l1, l2); - v2d[0] = pt[0] - pt_on_line[0]; /* same, for the other vert */ - v2d[1] = pt[1] - pt_on_line[1]; - w2 = len_v2(v2d); - wtot = w1 + w2; - r_uv[0] = w1 / wtot; - } - - /* Same as above to calc the uv[1] value, alternate calculation */ - - if (IsectLLPt2Df(v0[0], v0[1], v3[0], v3[1], v1[0], v1[1], v2[0], v2[1], &x0, &y0) == 1) { /* was v0,v1 v2,v3 now v0,v3 v1,v2*/ - /* never paralle if above was not */ - /*printf("\tnot parallel2\n");*/ - IsectLLPt2Df(pt[0], pt[1], x0, y0, v0[0], v0[1], v1[0], v1[1], &x1, &y1); /* was v0,v3 now v0,v1*/ - - v2d[0] = x1 - v0[0]; - v2d[1] = y1 - v0[1]; - w1 = len_v2(v2d); - - v2d[0] = x1 - v1[0]; - v2d[1] = y1 - v1[1]; - w2 = len_v2(v2d); - wtot = w1 + w2; - r_uv[1] = w1 / wtot; - } - else { - /* lines are parallel, lambda_cp_line_ex is 3d grrr */ - /*printf("\tparallel2\n");*/ - pt3d[0] = pt[0]; - pt3d[1] = pt[1]; - pt3d[2] = l1[2] = l2[2] = 0.0f; - - - l1[0] = v0[0]; - l1[1] = v0[1]; - l2[0] = v3[0]; - l2[1] = v3[1]; - closest_to_line_v3(pt_on_line, pt3d, l1, l2); - v2d[0] = pt[0] - pt_on_line[0]; /* some but for the other vert */ - v2d[1] = pt[1] - pt_on_line[1]; - w1 = len_v2(v2d); - - l1[0] = v1[0]; - l1[1] = v1[1]; - l2[0] = v2[0]; - l2[1] = v2[1]; - closest_to_line_v3(pt_on_line, pt3d, l1, l2); - v2d[0] = pt[0] - pt_on_line[0]; /* some but for the other vert */ - v2d[1] = pt[1] - pt_on_line[1]; - w2 = len_v2(v2d); - wtot = w1 + w2; - r_uv[1] = w1 / wtot; - } - /* may need to flip UV's here */ -} - -/* same as above but does tri's and quads, tri's are a bit of a hack */ -void isect_point_face_uv_v2(const int isquad, - const float v0[2], const float v1[2], const float v2[2], const float v3[2], - const float pt[2], float r_uv[2]) -{ - if (isquad) { - isect_point_quad_uv_v2(v0, v1, v2, v3, pt, r_uv); - } - else { - /* not for quads, use for our abuse of LineIntersectsTriangleUV */ - float p1_3d[3], p2_3d[3], v0_3d[3], v1_3d[3], v2_3d[3], lambda; - - p1_3d[0] = p2_3d[0] = r_uv[0]; - p1_3d[1] = p2_3d[1] = r_uv[1]; - p1_3d[2] = 1.0f; - p2_3d[2] = -1.0f; - v0_3d[2] = v1_3d[2] = v2_3d[2] = 0.0; - - /* generate a new fuv, (this is possibly a non optimal solution, - * since we only need 2d calculation but use 3d func's) - * - * this method makes an imaginary triangle in 2d space using the UV's from the derived mesh face - * Then find new uv coords using the fuv and this face with LineIntersectsTriangleUV. - * This means the new values will be correct in relation to the derived meshes face. - */ - copy_v2_v2(v0_3d, v0); - copy_v2_v2(v1_3d, v1); - copy_v2_v2(v2_3d, v2); - - /* Doing this in 3D is not nice */ - isect_line_tri_v3(p1_3d, p2_3d, v0_3d, v1_3d, v2_3d, &lambda, r_uv); - } -} - -#if 0 /* XXX this version used to be used in isect_point_tri_v2_int() and was called IsPointInTri2D */ - -int isect_point_tri_v2(float pt[2], float v1[2], float v2[2], float v3[2]) -{ - float inp1, inp2, inp3; - - inp1 = (v2[0] - v1[0]) * (v1[1] - pt[1]) + (v1[1] - v2[1]) * (v1[0] - pt[0]); - inp2 = (v3[0] - v2[0]) * (v2[1] - pt[1]) + (v2[1] - v3[1]) * (v2[0] - pt[0]); - inp3 = (v1[0] - v3[0]) * (v3[1] - pt[1]) + (v3[1] - v1[1]) * (v3[0] - pt[0]); - - if (inp1 <= 0.0f && inp2 <= 0.0f && inp3 <= 0.0f) return 1; - if (inp1 >= 0.0f && inp2 >= 0.0f && inp3 >= 0.0f) return 1; - - return 0; -} -#endif - -#if 0 - -int isect_point_tri_v2(float v0[2], float v1[2], float v2[2], float pt[2]) -{ - /* not for quads, use for our abuse of LineIntersectsTriangleUV */ - float p1_3d[3], p2_3d[3], v0_3d[3], v1_3d[3], v2_3d[3]; - /* not used */ - float lambda, uv[3]; - - p1_3d[0] = p2_3d[0] = uv[0] = pt[0]; - p1_3d[1] = p2_3d[1] = uv[1] = uv[2] = pt[1]; - p1_3d[2] = 1.0f; - p2_3d[2] = -1.0f; - v0_3d[2] = v1_3d[2] = v2_3d[2] = 0.0; - - /* generate a new fuv, (this is possibly a non optimal solution, - * since we only need 2d calculation but use 3d func's) - * - * this method makes an imaginary triangle in 2d space using the UV's from the derived mesh face - * Then find new uv coords using the fuv and this face with LineIntersectsTriangleUV. - * This means the new values will be correct in relation to the derived meshes face. - */ - copy_v2_v2(v0_3d, v0); - copy_v2_v2(v1_3d, v1); - copy_v2_v2(v2_3d, v2); - - /* Doing this in 3D is not nice */ - return isect_line_tri_v3(p1_3d, p2_3d, v0_3d, v1_3d, v2_3d, &lambda, uv); -} -#endif - /* * x1,y2 * | \ @@ -2326,7 +2085,7 @@ int barycentric_inside_triangle_v2(const float w[3]) } /* returns 0 for degenerated triangles */ -int barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]) +bool barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]) { float x = co[0], y = co[1]; float x1 = v1[0], y1 = v1[1]; @@ -2339,10 +2098,10 @@ int barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2 w[1] = ((y3 - y1) * (x - x3) + (x1 - x3) * (y - y3)) / det; w[2] = 1.0f - w[0] - w[1]; - return 1; + return true; } - return 0; + return false; } /* used by projection painting @@ -3384,9 +3143,9 @@ static void vec_add_dir(float r[3], const float v1[3], const float v2[3], const r[2] = v1[2] + fac * (v2[2] - v1[2]); } -int form_factor_visible_quad(const float p[3], const float n[3], - const float v0[3], const float v1[3], const float v2[3], - float q0[3], float q1[3], float q2[3], float q3[3]) +bool form_factor_visible_quad(const float p[3], const float n[3], + const float v0[3], const float v1[3], const float v2[3], + float q0[3], float q1[3], float q2[3], float q3[3]) { static const float epsilon = 1e-6f; float c, sd[3]; @@ -3507,11 +3266,11 @@ int form_factor_visible_quad(const float p[3], const float n[3], } else if (sd[2] < 0) { /* --- */ - return 0; + return false; } else { /* --0 */ - return 0; + return false; } } else { @@ -3524,11 +3283,11 @@ int form_factor_visible_quad(const float p[3], const float n[3], } else if (sd[2] < 0) { /* -0- */ - return 0; + return false; } else { /* -00 */ - return 0; + return false; } } } @@ -3566,11 +3325,11 @@ int form_factor_visible_quad(const float p[3], const float n[3], } else if (sd[2] < 0) { /* 0-- */ - return 0; + return false; } else { /* 0-0 */ - return 0; + return false; } } else { @@ -3583,16 +3342,16 @@ int form_factor_visible_quad(const float p[3], const float n[3], } else if (sd[2] < 0) { /* 00- */ - return 0; + return false; } else { /* 000 */ - return 0; + return false; } } } - return 1; + return true; } /* altivec optimization, this works, but is unused */ diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 312805e23f6..611b3298c38 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -433,6 +433,8 @@ void mul_m4_v4d(float mat[4][4], double r[4]) void mul_v3_m3v3(float r[3], float M[3][3], const float a[3]) { + BLI_assert(r != a); + r[0] = M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2]; r[1] = M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2]; r[2] = M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2]; @@ -440,6 +442,8 @@ void mul_v3_m3v3(float r[3], float M[3][3], const float a[3]) void mul_v2_m3v3(float r[2], float M[3][3], const float a[3]) { + BLI_assert(r != a); + r[0] = M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2]; r[1] = M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2]; } @@ -930,7 +934,7 @@ void orthogonalize_m4(float mat[4][4], int axis) mul_v3_fl(mat[2], size[2]); } -int is_orthogonal_m3(float m[3][3]) +bool is_orthogonal_m3(float m[3][3]) { int i, j; @@ -944,7 +948,7 @@ int is_orthogonal_m3(float m[3][3]) return 1; } -int is_orthogonal_m4(float m[4][4]) +bool is_orthogonal_m4(float m[4][4]) { int i, j; @@ -959,7 +963,7 @@ int is_orthogonal_m4(float m[4][4]) return 1; } -int is_orthonormal_m3(float m[3][3]) +bool is_orthonormal_m3(float m[3][3]) { if (is_orthogonal_m3(m)) { int i; @@ -974,7 +978,7 @@ int is_orthonormal_m3(float m[3][3]) return 0; } -int is_orthonormal_m4(float m[4][4]) +bool is_orthonormal_m4(float m[4][4]) { if (is_orthogonal_m4(m)) { int i; @@ -989,7 +993,7 @@ int is_orthonormal_m4(float m[4][4]) return 0; } -int is_uniform_scaled_m3(float m[3][3]) +bool is_uniform_scaled_m3(float m[3][3]) { const float eps = 1e-7; float t[3][3]; @@ -1374,6 +1378,28 @@ void rotate_m2(float mat[2][2], const float angle) mat[1][0] = -mat[0][1]; } +/** + * Scale or rotate around a pivot point, + * a convenience function to avoid having to do inline. + * + * Since its common to make a scale/rotation matrix that pivots around an arbitrary point. + * + * Typical use case is to make 3x3 matrix, copy to 4x4, then pass to this function. + */ +void transform_pivot_set_m4(float mat[4][4], const float pivot[3]) +{ + float tmat[4][4]; + + unit_m4(tmat); + + copy_v3_v3(tmat[3], pivot); + mul_m4_m4m4(mat, tmat, mat); + + /* invert the matrix */ + negate_v3(tmat[3]); + mul_m4_m4m4(mat, mat, tmat); +} + void blend_m3_m3m3(float out[3][3], float dst[3][3], float src[3][3], const float srcweight) { float srot[3][3], drot[3][3]; @@ -1419,20 +1445,34 @@ void blend_m4_m4m4(float out[4][4], float dst[4][4], float src[4][4], const floa loc_quat_size_to_mat4(out, floc, fquat, fsize); } -int is_negative_m3(float mat[3][3]) +bool is_negative_m3(float mat[3][3]) { float vec[3]; cross_v3_v3v3(vec, mat[0], mat[1]); return (dot_v3v3(vec, mat[2]) < 0.0f); } -int is_negative_m4(float mat[4][4]) +bool is_negative_m4(float mat[4][4]) { float vec[3]; cross_v3_v3v3(vec, mat[0], mat[1]); return (dot_v3v3(vec, mat[2]) < 0.0f); } +bool is_zero_m3(float mat[3][3]) +{ + return (is_zero_v3(mat[0]) && + is_zero_v3(mat[1]) && + is_zero_v3(mat[2])); +} +bool is_zero_m4(float mat[4][4]) +{ + return (is_zero_v4(mat[0]) && + is_zero_v4(mat[1]) && + is_zero_v4(mat[2]) && + is_zero_v4(mat[3])); +} + /* make a 4x4 matrix out of 3 transform components */ /* matrices are made in the order: scale * rot * loc */ /* TODO: need to have a version that allows for rotation order... */ diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index d77b1ecf017..8e5040d983b 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -418,6 +418,21 @@ MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3]) (mat[2][3] * co[2]) + mat[3][3]; } +/** + * Has the effect of mul_m3_v3(), on a single axis. + */ +MINLINE float dot_m3_v3_row_x(float M[3][3], const float a[3]) +{ + return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2]; +} +MINLINE float dot_m3_v3_row_y(float M[3][3], const float a[3]) +{ + return M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2]; +} +MINLINE float dot_m3_v3_row_z(float M[3][3], const float a[3]) +{ + return M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2]; +} MINLINE void madd_v2_v2fl(float r[2], const float a[2], float f) { diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index c5205ed5d18..2c06a812c8a 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -695,8 +695,10 @@ bool BLI_path_frame(char *path, int frame, int digits) if (stringframe_chars(path, &ch_sta, &ch_end)) { /* warning, ch_end is the last # +1 */ char tmp[FILE_MAX]; - sprintf(tmp, "%.*s%.*d%s", ch_sta, path, ch_end - ch_sta, frame, path + ch_end); - strcpy(path, tmp); + BLI_snprintf(tmp, sizeof(tmp), + "%.*s%.*d%s", + ch_sta, path, ch_end - ch_sta, frame, path + ch_end); + BLI_strncpy(path, tmp, FILE_MAX); return true; } return false; @@ -1689,6 +1691,26 @@ void BLI_split_file_part(const char *string, char *file, const size_t filelen) } /** + * Append a filename to a dir, ensuring slash separates. + */ +void BLI_path_append(char *dst, const size_t maxlen, const char *file) +{ + size_t dirlen = BLI_strnlen(dst, maxlen); + + /* inline BLI_add_slash */ + if ((dirlen > 0) && (dst[dirlen - 1] != SEP)) { + dst[dirlen++] = SEP; + dst[dirlen] = '\0'; + } + + if (dirlen >= maxlen) { + return; /* fills the path */ + } + + BLI_strncpy(dst + dirlen, file, maxlen - dirlen); +} + +/** * Simple appending of filename to dir, does not check for valid path! * Puts result into *dst, which may be same area as *dir. */ @@ -1696,15 +1718,16 @@ void BLI_join_dirfile(char *dst, const size_t maxlen, const char *dir, const cha { size_t dirlen = BLI_strnlen(dir, maxlen); - if (dst != dir) { - if (dirlen == maxlen) { - memcpy(dst, dir, dirlen); - dst[dirlen - 1] = '\0'; - return; /* dir fills the path */ - } - else { - memcpy(dst, dir, dirlen + 1); - } + /* args can't match */ + BLI_assert(!ELEM(dst, dir, file)); + + if (dirlen == maxlen) { + memcpy(dst, dir, dirlen); + dst[dirlen - 1] = '\0'; + return; /* dir fills the path */ + } + else { + memcpy(dst, dir, dirlen + 1); } if (dirlen + 1 >= maxlen) { @@ -1721,10 +1744,6 @@ void BLI_join_dirfile(char *dst, const size_t maxlen, const char *dir, const cha return; /* fills the path */ } - if (file == NULL) { - return; - } - BLI_strncpy(dst + dirlen, file, maxlen - dirlen); } @@ -1840,7 +1859,7 @@ int BLI_rebase_path(char *abs, size_t abs_len, /* subdirectories relative to blend_dir */ BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, rel_dir); /* same subdirectories relative to dest_dir */ - BLI_join_dirfile(dest_path, sizeof(dest_path), dest_path, base); + BLI_path_append(dest_path, sizeof(dest_path), base); /* keeping original item basename */ } @@ -2061,7 +2080,7 @@ static void bli_where_am_i(char *fullname, const size_t maxlen, const char *name else { strncpy(filename, path, sizeof(filename)); } - BLI_join_dirfile(fullname, maxlen, fullname, name); + BLI_path_append(fullname, maxlen, name); if (add_win32_extension(filename)) { BLI_strncpy(fullname, filename, maxlen); break; diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c index 873ce302b9c..c7163874dca 100644 --- a/source/blender/blenlib/intern/scanfill.c +++ b/source/blender/blenlib/intern/scanfill.c @@ -379,10 +379,10 @@ static ScanFillVertLink *addedgetoscanlist(ScanFillContext *sf_ctx, ScanFillEdge sc = (ScanFillVertLink *)bsearch(&scsearch, sf_ctx->_scdata, len, sizeof(ScanFillVertLink), vergscdata); - if (sc == 0) printf("Error in search edge: %p\n", (void *)eed); + if (sc == NULL) printf("Error in search edge: %p\n", (void *)eed); else if (addedgetoscanvert(sc, eed) == 0) return sc; - return 0; + return NULL; } static short boundinsideEV(ScanFillEdge *eed, ScanFillVert *eve) @@ -669,7 +669,7 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag) a = verts; break; } - if (ed2 == 0) { + if (ed2 == NULL) { sc->edge_first = sc->edge_last = NULL; /* printf("just 1 edge to vert\n"); */ BLI_addtail(&sf_ctx->filledgebase, ed1); @@ -1051,7 +1051,7 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no eed = nexted; } } - if (sf_ctx->filledgebase.first == 0) { + if (sf_ctx->filledgebase.first == NULL) { /* printf("All edges removed\n"); */ return 0; } diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index aeeae000fff..34c6e632131 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -388,17 +388,14 @@ static void bli_adddirstrings(struct BuildDirCtx *dir_ctx) */ st_size = file->s.st_size; - /* FIXME: Either change decimal prefixes to binary ones - * <http://en.wikipedia.org/wiki/Binary_prefix>, or change - * divisor factors from 1024 to 1000. */ if (st_size > 1024 * 1024 * 1024) { - BLI_snprintf(file->size, sizeof(file->size), "%.2f GB", ((double)st_size) / (1024 * 1024 * 1024)); + BLI_snprintf(file->size, sizeof(file->size), "%.2f GiB", ((double)st_size) / (1024 * 1024 * 1024)); } else if (st_size > 1024 * 1024) { - BLI_snprintf(file->size, sizeof(file->size), "%.1f MB", ((double)st_size) / (1024 * 1024)); + BLI_snprintf(file->size, sizeof(file->size), "%.1f MiB", ((double)st_size) / (1024 * 1024)); } else if (st_size > 1024) { - BLI_snprintf(file->size, sizeof(file->size), "%d KB", (int)(st_size / 1024)); + BLI_snprintf(file->size, sizeof(file->size), "%d KiB", (int)(st_size / 1024)); } else { BLI_snprintf(file->size, sizeof(file->size), "%d B", (int)st_size); diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index cb0d4ae307d..572b142d044 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -87,15 +87,18 @@ char *BLI_strdup(const char *str) */ char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2) { - size_t len; - char *n; - - len = strlen(str1) + strlen(str2); - n = MEM_mallocN(len + 1, "strdupcat"); - strcpy(n, str1); - strcat(n, str2); + /* include the NULL terminator of str2 only */ + const size_t str1_len = strlen(str1); + const size_t str2_len = strlen(str2) + 1; + char *str, *s; - return n; + str = MEM_mallocN(str1_len + str2_len, "strdupcat"); + s = str; + + memcpy(s, str1, str1_len); s += str1_len; + memcpy(s, str2, str2_len); + + return str; } /** @@ -302,34 +305,30 @@ char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict } /** + * string with all instances of substr_old replaced with substr_new, * Returns a copy of the cstring \a str into a newly mallocN'd - * string with all instances of oldText replaced with newText, * and returns it. * * \note A rather wasteful string-replacement utility, though this shall do for now... * Feel free to replace this with an even safe + nicer alternative * - * \param str The string to replace occurrences of oldText in - * \param oldText The text in the string to find and replace - * \param newText The text in the string to find and replace + * \param str The string to replace occurrences of substr_old in + * \param substr_old The text in the string to find and replace + * \param substr_new The text in the string to find and replace * \retval Returns the duplicated string */ -char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const char *__restrict newText) +char *BLI_replacestrN(const char *__restrict str, const char *__restrict substr_old, const char *__restrict substr_new) { DynStr *ds = NULL; - size_t lenOld = strlen(oldText); - char *match; - - /* sanity checks */ - if ((str == NULL) || (str[0] == 0)) - return NULL; - else if ((oldText == NULL) || (newText == NULL) || (oldText[0] == 0)) - return BLI_strdup(str); - + size_t len_old = strlen(substr_old); + const char *match; + + BLI_assert(substr_old[0] != '\0'); + /* while we can still find a match for the old substring that we're searching for, * keep dicing and replacing */ - while ( (match = strstr(str, oldText)) ) { + while ((match = strstr(str, substr_old))) { /* the assembly buffer only gets created when we actually need to rebuild the string */ if (ds == NULL) ds = BLI_dynstr_new(); @@ -338,39 +337,35 @@ char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const * copy the text up to this position and advance the current position in the string */ if (str != match) { - /* replace the token at the 'match' position with \0 so that the copied string will be ok, - * add the segment of the string from str to match to the buffer, then restore the value at match + /* add the segment of the string from str to match to the buffer, then restore the value at match */ - match[0] = 0; - BLI_dynstr_append(ds, str); - match[0] = oldText[0]; + BLI_dynstr_nappend(ds, str, (match - str)); /* now our current position should be set on the start of the match */ str = match; } /* add the replacement text to the accumulation buffer */ - BLI_dynstr_append(ds, newText); + BLI_dynstr_append(ds, substr_new); /* advance the current position of the string up to the end of the replaced segment */ - str += lenOld; + str += len_old; } /* finish off and return a new string that has had all occurrences of */ if (ds) { - char *newStr; + char *str_new; /* add what's left of the string to the assembly buffer - * - we've been adjusting str to point at the end of the replaced segments + * - we've been adjusting str to point at the end of the replaced segments */ - if (str != NULL) - BLI_dynstr_append(ds, str); + BLI_dynstr_append(ds, str); /* convert to new c-string (MEM_malloc'd), and free the buffer */ - newStr = BLI_dynstr_get_cstring(ds); + str_new = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); - return newStr; + return str_new; } else { /* just create a new copy of the entire string - we avoid going through the assembly buffer diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c index d435ed8f6e7..225b3c5538f 100644 --- a/source/blender/blenlib/intern/string_utf8.c +++ b/source/blender/blenlib/intern/string_utf8.c @@ -260,7 +260,7 @@ size_t BLI_wstrlen_utf8(const wchar_t *src) return len; } -size_t BLI_strlen_utf8_ex(const char *strc, int *r_len_bytes) +size_t BLI_strlen_utf8_ex(const char *strc, size_t *r_len_bytes) { size_t len; const char *strc_orig = strc; @@ -268,7 +268,7 @@ size_t BLI_strlen_utf8_ex(const char *strc, int *r_len_bytes) for (len = 0; *strc; len++) strc += BLI_str_utf8_size_safe(strc); - *r_len_bytes = (strc - strc_orig); + *r_len_bytes = (size_t)(strc - strc_orig); return len; } @@ -282,7 +282,7 @@ size_t BLI_strlen_utf8(const char *strc) return len; } -size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, int *r_len_bytes) +size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, size_t *r_len_bytes) { size_t len; const char *strc_orig = strc; @@ -292,7 +292,7 @@ size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, int *r_len_byt strc += BLI_str_utf8_size_safe(strc); } - *r_len_bytes = (strc - strc_orig); + *r_len_bytes = (size_t)(strc - strc_orig); return len; } diff --git a/source/blender/blenlib/intern/voronoi.c b/source/blender/blenlib/intern/voronoi.c index 7a545090090..3f6adff1eda 100644 --- a/source/blender/blenlib/intern/voronoi.c +++ b/source/blender/blenlib/intern/voronoi.c @@ -121,7 +121,7 @@ static VoronoiParabola *voronoiParabola_new(void) parabola->is_leaf = FALSE; parabola->event = NULL; parabola->edge = NULL; - parabola->parent = 0; + parabola->parent = NULL; return parabola; } @@ -134,7 +134,7 @@ static VoronoiParabola *voronoiParabola_newSite(float site[2]) parabola->is_leaf = TRUE; parabola->event = NULL; parabola->edge = NULL; - parabola->parent = 0; + parabola->parent = NULL; return parabola; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 50273cb33f3..1f8bbfbec88 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -108,6 +108,7 @@ #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_threads.h" +#include "BLI_mempool.h" #include "BLF_translation.h" @@ -327,7 +328,7 @@ void blo_do_versions_oldnewmap_insert(OldNewMap *onm, void *oldaddr, void *newad oldnewmap_insert(onm, oldaddr, newaddr, nr); } -static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr) +static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr, bool increase_users) { int i; @@ -337,7 +338,8 @@ static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr) OldNew *entry = &onm->entries[++onm->lasthit]; if (entry->old == addr) { - entry->nr++; + if (increase_users) + entry->nr++; return entry->newp; } } @@ -348,7 +350,8 @@ static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr) if (entry->old == addr) { onm->lasthit = i; - entry->nr++; + if (increase_users) + entry->nr++; return entry->newp; } } @@ -1200,34 +1203,39 @@ int BLO_is_a_library(const char *path, char *dir, char *group) static void *newdataadr(FileData *fd, void *adr) /* only direct databocks */ { - return oldnewmap_lookup_and_inc(fd->datamap, adr); + return oldnewmap_lookup_and_inc(fd->datamap, adr, true); +} + +static void *newdataadr_no_us(FileData *fd, void *adr) /* only direct databocks */ +{ + return oldnewmap_lookup_and_inc(fd->datamap, adr, false); } static void *newglobadr(FileData *fd, void *adr) /* direct datablocks with global linking */ { - return oldnewmap_lookup_and_inc(fd->globmap, adr); + return oldnewmap_lookup_and_inc(fd->globmap, adr, true); } static void *newimaadr(FileData *fd, void *adr) /* used to restore image data after undo */ { if (fd->imamap && adr) - return oldnewmap_lookup_and_inc(fd->imamap, adr); + return oldnewmap_lookup_and_inc(fd->imamap, adr, true); return NULL; } static void *newmclipadr(FileData *fd, void *adr) /* used to restore movie clip data after undo */ { if (fd->movieclipmap && adr) - return oldnewmap_lookup_and_inc(fd->movieclipmap, adr); + return oldnewmap_lookup_and_inc(fd->movieclipmap, adr, true); return NULL; } static void *newpackedadr(FileData *fd, void *adr) /* used to restore packed data after undo */ { if (fd->packedmap && adr) - return oldnewmap_lookup_and_inc(fd->packedmap, adr); + return oldnewmap_lookup_and_inc(fd->packedmap, adr, true); - return oldnewmap_lookup_and_inc(fd->datamap, adr); + return oldnewmap_lookup_and_inc(fd->datamap, adr, true); } @@ -5684,16 +5692,24 @@ static void lib_link_screen(FileData *fd, Main *main) } else if (sl->spacetype == SPACE_OUTLINER) { SpaceOops *so= (SpaceOops *)sl; - TreeStoreElem *tselem; - int a; - so->search_tse.id = newlibadr(fd, NULL, so->search_tse.id); if (so->treestore) { - tselem = so->treestore->data; - for (a=0; a < so->treestore->usedelem; a++, tselem++) { + TreeStoreElem *tselem; + BLI_mempool_iter iter; + + BLI_mempool_iternew(so->treestore, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { tselem->id = newlibadr(fd, NULL, tselem->id); } + if (so->treehash) { + /* update hash table, because it depends on ids too */ + BLI_ghash_clear(so->treehash, NULL, NULL); + BLI_mempool_iternew(so->treestore, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { + BLI_ghash_insert(so->treehash, tselem, tselem); + } + } } } else if (sl->spacetype == SPACE_NODE) { @@ -5803,21 +5819,23 @@ static void *restore_pointer_by_name(Main *mainp, ID *id, int user) return NULL; } +static void lib_link_seq_clipboard_pt_restore(ID *id, Main *newmain) +{ + if (id) { + /* clipboard must ensure this */ + BLI_assert(id->newid != NULL); + id->newid = restore_pointer_by_name(newmain, (ID *)id->newid, 1); + } +} static int lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt) { Main *newmain = (Main *)arg_pt; - - if (seq->sound) { - seq->sound = restore_pointer_by_name(newmain, (ID *)seq->sound, 0); - seq->sound->id.us++; - } - - if (seq->scene) - seq->scene = restore_pointer_by_name(newmain, (ID *)seq->scene, 1); - - if (seq->scene_camera) - seq->scene_camera = restore_pointer_by_name(newmain, (ID *)seq->scene_camera, 1); - + + lib_link_seq_clipboard_pt_restore((ID *)seq->scene, newmain); + lib_link_seq_clipboard_pt_restore((ID *)seq->scene_camera, newmain); + lib_link_seq_clipboard_pt_restore((ID *)seq->clip, newmain); + lib_link_seq_clipboard_pt_restore((ID *)seq->mask, newmain); + lib_link_seq_clipboard_pt_restore((ID *)seq->sound, newmain); return 1; } @@ -6014,16 +6032,25 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc } else if (sl->spacetype == SPACE_OUTLINER) { SpaceOops *so= (SpaceOops *)sl; - int a; so->search_tse.id = restore_pointer_by_name(newmain, so->search_tse.id, 0); if (so->treestore) { - TreeStore *ts = so->treestore; - TreeStoreElem *tselem = ts->data; - for (a = 0; a < ts->usedelem; a++, tselem++) { + TreeStoreElem *tselem; + BLI_mempool_iter iter; + + BLI_mempool_iternew(so->treestore, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { tselem->id = restore_pointer_by_name(newmain, tselem->id, 0); } + if (so->treehash) { + /* update hash table, because it depends on ids too */ + BLI_ghash_clear(so->treehash, NULL, NULL); + BLI_mempool_iternew(so->treestore, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { + BLI_ghash_insert(so->treehash, tselem, tselem); + } + } } } else if (sl->spacetype == SPACE_NODE) { @@ -6111,20 +6138,26 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype) ui_list->type = NULL; } - ar->regiondata = newdataadr(fd, ar->regiondata); - if (ar->regiondata) { - if (spacetype == SPACE_VIEW3D) { - RegionView3D *rv3d = ar->regiondata; - - rv3d->localvd = newdataadr(fd, rv3d->localvd); - rv3d->clipbb = newdataadr(fd, rv3d->clipbb); - - rv3d->depths = NULL; - rv3d->gpuoffscreen = NULL; - rv3d->ri = NULL; - rv3d->render_engine = NULL; - rv3d->sms = NULL; - rv3d->smooth_timer = NULL; + if (spacetype == SPACE_EMPTY) { + /* unkown space type, don't leak regiondata */ + ar->regiondata = NULL; + } + else { + ar->regiondata = newdataadr(fd, ar->regiondata); + if (ar->regiondata) { + if (spacetype == SPACE_VIEW3D) { + RegionView3D *rv3d = ar->regiondata; + + rv3d->localvd = newdataadr(fd, rv3d->localvd); + rv3d->clipbb = newdataadr(fd, rv3d->clipbb); + + rv3d->depths = NULL; + rv3d->gpuoffscreen = NULL; + rv3d->ri = NULL; + rv3d->render_engine = NULL; + rv3d->sms = NULL; + rv3d->smooth_timer = NULL; + } } } @@ -6211,6 +6244,11 @@ static bool direct_link_screen(FileData *fd, bScreen *sc) sa->handlers.first = sa->handlers.last = NULL; sa->type = NULL; /* spacetype callbacks */ sa->region_active_win = -1; + + /* if we do not have the spacetype registered (game player), we cannot + * free it, so don't allocate any new memory for such spacetypes. */ + if (!BKE_spacetype_exists(sa->spacetype)) + sa->spacetype = SPACE_EMPTY; for (ar = sa->regionbase.first; ar; ar = ar->next) direct_link_region(fd, ar, sa->spacetype); @@ -6228,7 +6266,12 @@ static bool direct_link_screen(FileData *fd, bScreen *sc) for (sl = sa->spacedata.first; sl; sl = sl->next) { link_list(fd, &(sl->regionbase)); - + + /* if we do not have the spacetype registered (game player), we cannot + * free it, so don't allocate any new memory for such spacetypes. */ + if (!BKE_spacetype_exists(sl->spacetype)) + sl->spacetype = SPACE_EMPTY; + for (ar = sl->regionbase.first; ar; ar = ar->next) direct_link_region(fd, ar, sl->spacetype); @@ -6281,13 +6324,28 @@ static bool direct_link_screen(FileData *fd, bScreen *sc) else if (sl->spacetype == SPACE_OUTLINER) { SpaceOops *soops = (SpaceOops *) sl; - soops->treestore = newdataadr(fd, soops->treestore); - if (soops->treestore) { - soops->treestore->data = newdataadr(fd, soops->treestore->data); + /* use newdataadr_no_us and do not free old memory avoidign double + * frees and use of freed memory. this could happen because of a + * bug fixed in revision 58959 where the treestore memory address + * was not unique */ + TreeStore *ts = newdataadr_no_us(fd, soops->treestore); + soops->treestore = NULL; + if (ts) { + TreeStoreElem *elems = newdataadr_no_us(fd, ts->data); + + soops->treestore = BLI_mempool_create(sizeof(TreeStoreElem), ts->usedelem, + 512, BLI_MEMPOOL_ALLOW_ITER); + if (ts->usedelem && elems) { + int i; + for (i = 0; i < ts->usedelem; i++) { + TreeStoreElem *new_elem = BLI_mempool_alloc(soops->treestore); + *new_elem = elems[i]; + } + } /* we only saved what was used */ - soops->treestore->totelem = soops->treestore->usedelem; soops->storeflag |= SO_TREESTORE_CLEANUP; // at first draw } + soops->treehash = NULL; soops->tree.first = soops->tree.last= NULL; } else if (sl->spacetype == SPACE_IMAGE) { @@ -7244,7 +7302,7 @@ static void link_global(FileData *fd, BlendFileData *bfd) } } -void convert_tface_mt(FileData *fd, Main *main) +static void convert_tface_mt(FileData *fd, Main *main) { Main *gmain; @@ -8140,12 +8198,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) for (ob = main->object.first; ob; ob = ob->id.next) { bConstraint *con; for (con = ob->constraints.first; con; con = con->next) { - bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con); - - if (!cti) - continue; - - if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) { + if (con->type == CONSTRAINT_TYPE_OBJECTSOLVER) { bObjectSolverConstraint *data = (bObjectSolverConstraint *)con->data; if (data->invmat[3][3] == 0.0f) @@ -9487,7 +9540,29 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if (!MAIN_VERSION_ATLEAST(main, 268, 1)) { + Brush *brush; + for (brush = main->brush.first; brush; brush = brush->id.next) { + brush->spacing = MAX2(1, brush->spacing); + } + } + + if (!MAIN_VERSION_ATLEAST(main, 268, 2)) { + Brush *brush; + #define BRUSH_FIXED (1 << 6) + for (brush = main->brush.first; brush; brush = brush->id.next) { + brush->flag &= ~BRUSH_FIXED; + if(brush->cursor_overlay_alpha < 2) + brush->cursor_overlay_alpha = 33; + if(brush->texture_overlay_alpha < 2) + brush->texture_overlay_alpha = 33; + if(brush->mask_overlay_alpha <2) + brush->mask_overlay_alpha = 33; + } + #undef BRUSH_FIXED + } + { bScreen *sc; Object *ob; @@ -10113,6 +10188,7 @@ static void expand_texture(FileData *fd, Main *mainvar, Tex *tex) static void expand_brush(FileData *fd, Main *mainvar, Brush *brush) { expand_doit(fd, mainvar, brush->mtex.tex); + expand_doit(fd, mainvar, brush->mask_mtex.tex); expand_doit(fd, mainvar, brush->clone.image); } diff --git a/source/blender/blenloader/intern/runtime.c b/source/blender/blenloader/intern/runtime.c index d6fd2f92443..ca9f2faf998 100644 --- a/source/blender/blenloader/intern/runtime.c +++ b/source/blender/blenloader/intern/runtime.c @@ -72,7 +72,7 @@ int BLO_is_a_runtime(const char *path) int datastart; char buf[8]; - if (fd == -1) + if (fd < 0) goto cleanup; lseek(fd, -12, SEEK_END); @@ -104,7 +104,7 @@ BlendFileData *BLO_read_runtime(const char *path, ReportList *reports) fd = BLI_open(path, O_BINARY | O_RDONLY, 0); - if (fd == -1) { + if (fd < 0) { BKE_reportf(reports, RPT_ERROR, "Unable to open '%s': %s", path, strerror(errno)); goto cleanup; } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index dd4361be1ff..4f0ccd3c626 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -144,12 +144,13 @@ #include "BLI_bitmap.h" #include "BLI_blenlib.h" #include "BLI_linklist.h" -#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_mempool.h" #include "BKE_action.h" #include "BKE_blender.h" +#include "BKE_bpath.h" #include "BKE_curve.h" #include "BKE_constraint.h" #include "BKE_global.h" // for G @@ -1660,8 +1661,8 @@ static void write_curves(WriteData *wd, ListBase *idbase) if (cu->vfont) { /* TODO, sort out 'cu->len', in editmode its character, object mode its bytes */ - int len_bytes; - int len_chars = BLI_strlen_utf8_ex(cu->str, &len_bytes); + size_t len_bytes; + size_t len_chars = BLI_strlen_utf8_ex(cu->str, &len_bytes); writedata(wd, DATA, len_bytes + 1, cu->str); writestruct(wd, DATA, "CharInfo", len_chars + 1, cu->strinfo); @@ -2393,12 +2394,55 @@ static void write_region(WriteData *wd, ARegion *ar, int spacetype) } } +static void write_soops(WriteData *wd, SpaceOops *so, LinkNode **tmp_mem_list) +{ + BLI_mempool *ts = so->treestore; + + if (ts) { + int elems = BLI_mempool_count(ts); + /* linearize mempool to array */ + TreeStoreElem *data = elems ? BLI_mempool_as_arrayN(ts, "TreeStoreElem") : NULL; + + if (data) { + TreeStore *ts_flat = MEM_callocN(sizeof(TreeStore), "TreeStore"); + + ts_flat->usedelem = elems; + ts_flat->totelem = elems; + ts_flat->data = data; + + /* temporarily replace mempool-treestore by flat-treestore */ + so->treestore = (BLI_mempool *)ts_flat; + writestruct(wd, DATA, "SpaceOops", 1, so); + + writestruct(wd, DATA, "TreeStore", 1, ts_flat); + writestruct(wd, DATA, "TreeStoreElem", elems, data); + + /* we do not free the pointers immediately, because if we have multiple + * outliners in a screen we might get the same address on the next + * malloc, which makes the address no longer unique and so invalid for + * lookups on file read, causing crashes or double frees */ + BLI_linklist_append(tmp_mem_list, ts_flat); + BLI_linklist_append(tmp_mem_list, data); + } + else { + so->treestore = NULL; + writestruct(wd, DATA, "SpaceOops", 1, so); + } + + /* restore old treestore */ + so->treestore = ts; + } else { + writestruct(wd, DATA, "SpaceOops", 1, so); + } +} + static void write_screens(WriteData *wd, ListBase *scrbase) { bScreen *sc; ScrArea *sa; ScrVert *sv; ScrEdge *se; + LinkNode *tmp_mem_list = NULL; sc= scrbase->first; while (sc) { @@ -2475,15 +2519,7 @@ static void write_screens(WriteData *wd, ListBase *scrbase) } else if (sl->spacetype==SPACE_OUTLINER) { SpaceOops *so= (SpaceOops *)sl; - - writestruct(wd, DATA, "SpaceOops", 1, so); - - /* outliner */ - if (so->treestore) { - writestruct(wd, DATA, "TreeStore", 1, so->treestore); - if (so->treestore->data) - writestruct(wd, DATA, "TreeStoreElem", so->treestore->usedelem, so->treestore->data); - } + write_soops(wd, so, &tmp_mem_list); } else if (sl->spacetype==SPACE_IMAGE) { SpaceImage *sima= (SpaceImage *)sl; @@ -2548,6 +2584,8 @@ static void write_screens(WriteData *wd, ListBase *scrbase) sc= sc->id.next; } + + BLI_linklist_freeN(tmp_mem_list); /* flush helps the compression for undo-save */ mywrite(wd, MYWRITE_FLUSH, 0); @@ -3378,7 +3416,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL BLI_snprintf(tempname, sizeof(tempname), "%s@", filepath); file = BLI_open(tempname, O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666); - if (file == -1) { + if (file < 0) { BKE_reportf(reports, RPT_ERROR, "Cannot open file %s for writing: %s", tempname, strerror(errno)); return 0; } diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index b3dd2f57523..228ebcb96c4 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -23,7 +23,7 @@ # # ***** END GPL LICENSE BLOCK ***** -set(INC +set(INC . ../blenfont ../blenkernel @@ -43,6 +43,7 @@ set(SRC operators/bmo_bevel.c operators/bmo_bridge.c operators/bmo_connect.c + operators/bmo_connect_nonplanar.c operators/bmo_connect_pair.c operators/bmo_create.c operators/bmo_dissolve.c @@ -50,7 +51,8 @@ set(SRC operators/bmo_edgenet.c operators/bmo_extrude.c operators/bmo_fill_edgeloop.c - operators/bmo_fill_grid.c + operators/bmo_fill_grid.c + operators/bmo_fill_holes.c operators/bmo_hull.c operators/bmo_inset.c operators/bmo_join_triangles.c @@ -115,7 +117,6 @@ set(SRC intern/bmesh_operator_api.h intern/bmesh_error.h - tools/BME_bevel.c tools/bmesh_bevel.c tools/bmesh_bevel.h tools/bmesh_decimate_collapse.c diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index 022dfe452e7..d1d93bbfd1d 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -271,6 +271,7 @@ extern "C" { #include "tools/bmesh_bevel.h" #include "tools/bmesh_decimate.h" +#include "tools/bmesh_edgesplit.h" #include "tools/bmesh_path.h" #include "tools/bmesh_triangulate.h" diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index 1af4836c225..f5856ee94b3 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -33,7 +33,7 @@ #include "MEM_guardedalloc.h" -#include "BLI_array.h" +#include "BLI_alloca.h" #include "BLI_math.h" #include "BKE_customdata.h" @@ -200,6 +200,8 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, c ev1 = edges[0]->v1; ev2 = edges[0]->v2; + BLI_assert(ELEM(v1, ev1, ev2) && ELEM(v2, ev1, ev2)); + if (v1 == ev2) { /* Swapping here improves performance and consistency of face * structure in the special case that the edges are already in @@ -322,6 +324,7 @@ BMFace *BM_face_create_ngon_verts(BMesh *bm, BMVert **vert_arr, const int len, c BMEdge **edge_arr = BLI_array_alloca(edge_arr, len); unsigned int winding[2] = {0, 0}; int i, i_prev = len - 1; + BMVert *v_winding[2] = {vert_arr[i_prev], vert_arr[0]}; BLI_assert(len > 2); @@ -344,6 +347,7 @@ BMFace *BM_face_create_ngon_verts(BMesh *bm, BMVert **vert_arr, const int len, c /* we want to use the reverse winding to the existing order */ BM_edge_ordered_verts(edge_arr[i], &test_v2, &test_v1); winding[(vert_arr[i_prev] == test_v2)]++; + BLI_assert(vert_arr[i_prev] == test_v2 || vert_arr[i_prev] == test_v1); } } @@ -370,7 +374,11 @@ BMFace *BM_face_create_ngon_verts(BMesh *bm, BMVert **vert_arr, const int len, c /* --- */ /* create the face */ - return BM_face_create_ngon(bm, vert_arr[winding[0]], vert_arr[winding[1]], edge_arr, len, create_flag); + return BM_face_create_ngon( + bm, + v_winding[winding[0]], + v_winding[winding[1]], + edge_arr, len, create_flag); } @@ -515,7 +523,7 @@ BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int len, const /* --- */ /* create edges and find the winding (if faces are attached to any existing edges) */ - vert_arr_map = MEM_mallocN(sizeof(BMVert **) * len, __func__); + vert_arr_map = MEM_mallocN(sizeof(BMVert *) * len, __func__); for (i = 0; i < len; i++) { vert_arr_map[i] = vert_arr[vang[i].index]; @@ -817,11 +825,6 @@ void BM_elem_attrs_copy_ex(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, BLI_assert(ele_src->htype == ele_dst->htype); - if (ele_src->htype != ele_dst->htype) { - BLI_assert(!"type mismatch"); - return; - } - if ((hflag_mask & BM_ELEM_SELECT) == 0) { /* First we copy select */ if (BM_elem_flag_test((BMElem *)ele_src, BM_ELEM_SELECT)) { @@ -833,6 +836,9 @@ void BM_elem_attrs_copy_ex(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, if (hflag_mask == 0) { ele_dst->hflag = ele_src->hflag; } + else if (hflag_mask == 0xff) { + /* pass */ + } else { ele_dst->hflag = ((ele_dst->hflag & hflag_mask) | (ele_src->hflag & ~hflag_mask)); } @@ -860,7 +866,19 @@ void BM_elem_attrs_copy_ex(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, void BM_elem_attrs_copy(BMesh *bm_src, BMesh *bm_dst, const void *ele_src, void *ele_dst) { /* BMESH_TODO, default 'use_flags' to false */ - BM_elem_attrs_copy_ex(bm_src, bm_dst, ele_src, ele_dst, 0); + BM_elem_attrs_copy_ex(bm_src, bm_dst, ele_src, ele_dst, BM_ELEM_SELECT); +} + +void BM_elem_select_copy(BMesh *bm_dst, BMesh *UNUSED(bm_src), void *ele_dst_v, const void *ele_src_v) +{ + BMHeader *ele_dst = ele_dst_v; + const BMHeader *ele_src = ele_src_v; + + BLI_assert(ele_src->htype == ele_dst->htype); + + if ((ele_src->hflag & BM_ELEM_SELECT) != (ele_dst->hflag & BM_ELEM_SELECT)) { + BM_elem_select_set(bm_dst, (BMElem *)ele_dst, (ele_src->hflag & BM_ELEM_SELECT) != 0); + } } /* helper function for 'BM_mesh_copy' */ @@ -894,7 +912,8 @@ static BMFace *bm_mesh_copy_new_face(BMesh *bm_new, BMesh *bm_old, /* use totface in case adding some faces fails */ BM_elem_index_set(f_new, (bm_new->totface - 1)); /* set_inline */ - BM_elem_attrs_copy(bm_old, bm_new, f, f_new); + BM_elem_attrs_copy_ex(bm_old, bm_new, f, f_new, 0xff); + f_new->head.hflag = f->head.hflag; /* low level! don't do this for normal api use */ j = 0; l_iter = l_first = BM_FACE_FIRST_LOOP(f_new); @@ -951,7 +970,8 @@ BMesh *BM_mesh_copy(BMesh *bm_old) BM_ITER_MESH_INDEX (v, &iter, bm_old, BM_VERTS_OF_MESH, i) { /* copy between meshes so cant use 'example' argument */ v_new = BM_vert_create(bm_new, v->co, NULL, BM_CREATE_SKIP_CD); - BM_elem_attrs_copy(bm_old, bm_new, v, v_new); + BM_elem_attrs_copy_ex(bm_old, bm_new, v, v_new, 0xff); + v_new->head.hflag = v->head.hflag; /* low level! don't do this for normal api use */ vtable[i] = v_new; BM_elem_index_set(v, i); /* set_inline */ BM_elem_index_set(v_new, i); /* set_inline */ @@ -968,7 +988,8 @@ BMesh *BM_mesh_copy(BMesh *bm_old) vtable[BM_elem_index_get(e->v2)], e, BM_CREATE_SKIP_CD); - BM_elem_attrs_copy(bm_old, bm_new, e, e_new); + BM_elem_attrs_copy_ex(bm_old, bm_new, e, e_new, 0xff); + e_new->head.hflag = e->head.hflag; /* low level! don't do this for normal api use */ etable[i] = e_new; BM_elem_index_set(e, i); /* set_inline */ BM_elem_index_set(e_new, i); /* set_inline */ @@ -991,6 +1012,12 @@ BMesh *BM_mesh_copy(BMesh *bm_old) bm_old->elem_index_dirty &= ~BM_FACE; bm_new->elem_index_dirty &= ~BM_FACE; + + /* low level! don't do this for normal api use */ + bm_new->totvertsel = bm_old->totvertsel; + bm_new->totedgesel = bm_old->totedgesel; + bm_new->totfacesel = bm_old->totfacesel; + /* safety check */ BLI_assert(i == bm_old->totface); diff --git a/source/blender/bmesh/intern/bmesh_construct.h b/source/blender/bmesh/intern/bmesh_construct.h index 3dcb1eb1ccb..f0bd7b316e9 100644 --- a/source/blender/bmesh/intern/bmesh_construct.h +++ b/source/blender/bmesh/intern/bmesh_construct.h @@ -53,6 +53,7 @@ void BMO_remove_tagged_context(BMesh *bm, const short oflag, const int type); void BM_elem_attrs_copy_ex(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v, const char hflag_mask); void BM_elem_attrs_copy(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v); +void BM_elem_select_copy(BMesh *bm_dst, BMesh *bm_src, void *ele_dst_v, const void *ele_src_v); void BM_mesh_copy_init_customdata(BMesh *bm_dst, BMesh *bm_src, const struct BMAllocTemplate *allocsize); BMesh *BM_mesh_copy(BMesh *bm_old); diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 05c462ac672..b296c367575 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -30,6 +30,7 @@ #include "BLI_math_vector.h" #include "BLI_listbase.h" #include "BLI_array.h" +#include "BLI_alloca.h" #include "BLI_smallhash.h" #include "BLF_translation.h" @@ -594,7 +595,7 @@ static void bm_kill_only_loop(BMesh *bm, BMLoop *l) */ void BM_face_edges_kill(BMesh *bm, BMFace *f) { - BMEdge **edges = BLI_array_alloca_and_count(edges, f->len); + BMEdge **edges = BLI_array_alloca(edges, f->len); BMLoop *l_iter; BMLoop *l_first; int i = 0; @@ -604,7 +605,7 @@ void BM_face_edges_kill(BMesh *bm, BMFace *f) edges[i++] = l_iter->e; } while ((l_iter = l_iter->next) != l_first); - for (i = 0; i < BLI_array_count(edges); i++) { + for (i = 0; i < f->len; i++) { BM_edge_kill(bm, edges[i]); } } @@ -615,7 +616,7 @@ void BM_face_edges_kill(BMesh *bm, BMFace *f) */ void BM_face_verts_kill(BMesh *bm, BMFace *f) { - BMVert **verts = BLI_array_alloca_and_count(verts, f->len); + BMVert **verts = BLI_array_alloca(verts, f->len); BMLoop *l_iter; BMLoop *l_first; int i = 0; @@ -625,7 +626,7 @@ void BM_face_verts_kill(BMesh *bm, BMFace *f) verts[i++] = l_iter->v; } while ((l_iter = l_iter->next) != l_first); - for (i = 0; i < BLI_array_count(verts); i++) { + for (i = 0; i < f->len; i++) { BM_vert_kill(bm, verts[i]); } } @@ -1368,16 +1369,20 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) BMLoop *l_next; BMEdge *e_new; BMVert *v_new, *v_old; - int i, valence1 = 0, valence2 = 0; +#ifndef NDEBUG + int valence1, valence2; bool edok; + int i; +#endif BLI_assert(bmesh_vert_in_edge(e, tv) != false); v_old = bmesh_edge_other_vert_get(e, tv); +#ifndef NDEBUG valence1 = bmesh_disk_count(v_old); - valence2 = bmesh_disk_count(tv); +#endif v_new = BM_vert_create(bm, tv->co, tv, 0); e_new = BM_edge_create(bm, v_new, tv, e, 0); @@ -1400,6 +1405,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) /* add e_new to tv's disk cycle */ bmesh_disk_edge_append(e_new, tv); +#ifndef NDEBUG /* verify disk cycles */ edok = bmesh_disk_validate(valence1, v_old->e, v_old); BMESH_ASSERT(edok != false); @@ -1407,13 +1413,16 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) BMESH_ASSERT(edok != false); edok = bmesh_disk_validate(2, v_new->e, v_new); BMESH_ASSERT(edok != false); +#endif /* Split the radial cycle if present */ l_next = e->l; e->l = NULL; if (l_next) { BMLoop *l_new, *l; +#ifndef NDEBUG int radlen = bmesh_radial_length(l_next); +#endif int first1 = 0, first2 = 0; /* Take the next loop. Remove it from radial. Split it. Append to appropriate radials */ @@ -1470,6 +1479,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) } +#ifndef NDEBUG /* verify length of radial cycle */ edok = bmesh_radial_validate(radlen, e->l); BMESH_ASSERT(edok != false); @@ -1508,6 +1518,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) BM_CHECK_ELEMENT(l->e); BM_CHECK_ELEMENT(l->f); } +#endif } BM_CHECK_ELEMENT(e_new); @@ -1555,8 +1566,8 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_e { BMEdge *e_old; BMVert *v_old, *tv; - BMLoop *l_kill, *l; - int len, radlen = 0, i, valence1, valence2; + BMLoop *l_kill; + int len, radlen = 0, i; bool edok, halt = false; if (bmesh_vert_in_edge(e_kill, v_kill) == 0) { @@ -1566,6 +1577,11 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_e len = bmesh_disk_count(v_kill); if (len == 2) { +#ifndef NDEBUG + int valence1, valence2; + BMLoop *l; +#endif + e_old = bmesh_disk_edge_next(e_kill, v_kill); tv = bmesh_edge_other_vert_get(e_kill, v_kill); v_old = bmesh_edge_other_vert_get(e_old, v_kill); @@ -1577,9 +1593,11 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_e else { BMEdge *e_splice; +#ifndef NDEBUG /* For verification later, count valence of v_old and tv */ valence1 = bmesh_disk_count(v_old); valence2 = bmesh_disk_count(tv); +#endif if (check_edge_double) { e_splice = BM_edge_exists(tv, v_old); @@ -1645,6 +1663,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_e /* deallocate vertex */ bm_kill_only_vert(bm, v_kill); +#ifndef NDEBUG /* Validate disk cycle lengths of v_old, tv are unchanged */ edok = bmesh_disk_validate(valence1, v_old->e, v_old); BMESH_ASSERT(edok != false); @@ -1664,6 +1683,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_e BM_CHECK_ELEMENT(l->e); BM_CHECK_ELEMENT(l->f); } +#endif if (check_edge_double) { if (e_splice) { @@ -1745,10 +1765,10 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) /* validate that for each face, each vertex has another edge in its disk cycle that is * not e, and not shared. */ - if (bmesh_radial_face_find(l_f1->next->e, f2) || - bmesh_radial_face_find(l_f1->prev->e, f2) || - bmesh_radial_face_find(l_f2->next->e, f1) || - bmesh_radial_face_find(l_f2->prev->e, f1) ) + if (BM_edge_in_face(l_f1->next->e, f2) || + BM_edge_in_face(l_f1->prev->e, f2) || + BM_edge_in_face(l_f2->next->e, f1) || + BM_edge_in_face(l_f2->prev->e, f1) ) { return NULL; } @@ -1895,7 +1915,8 @@ bool BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target) * * \return Success */ -bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len) +void bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len, + const bool copy_select) { const int v_edgetot = BM_vert_face_count(v); BMEdge **stack = BLI_array_alloca(stack, v_edgetot); @@ -1950,6 +1971,9 @@ bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len verts[0] = v; for (i = 1; i < maxindex; i++) { verts[i] = BM_vert_create(bm, v->co, v, 0); + if (copy_select) { + BM_elem_select_copy(bm, bm, verts[i], v); + } } /* Replace v with the new verts in each group */ @@ -2019,14 +2043,12 @@ bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len if (r_vout != NULL) { *r_vout = verts; } - - return true; } /** * High level function which wraps both #bmesh_vert_separate and #bmesh_edge_separate */ -bool BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len, +void BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len, BMEdge **e_in, int e_in_len) { int i; @@ -2034,11 +2056,11 @@ bool BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len, for (i = 0; i < e_in_len; i++) { BMEdge *e = e_in[i]; if (e->l && BM_vert_in_edge(e, v)) { - bmesh_edge_separate(bm, e, e->l); + bmesh_edge_separate(bm, e, e->l, false); } } - return bmesh_vert_separate(bm, v, r_vout, r_vout_len); + bmesh_vert_separate(bm, v, r_vout, r_vout_len, false); } /** @@ -2094,18 +2116,20 @@ bool BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target) * \note Does nothing if \a l_sep is already the only loop in the * edge radial. */ -bool bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep) +void bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep, + const bool copy_select) { BMEdge *e_new; - int radlen; +#ifndef NDEBUG + const int radlen = bmesh_radial_length(e->l); +#endif BLI_assert(l_sep->e == e); BLI_assert(e->l); - radlen = bmesh_radial_length(e->l); - if (radlen < 2) { + if (BM_edge_is_boundary(e)) { /* no cut required */ - return true; + return; } if (l_sep == e->l) { @@ -2117,13 +2141,15 @@ bool bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep) bmesh_radial_append(e_new, l_sep); l_sep->e = e_new; + if (copy_select) { + BM_elem_select_copy(bm, bm, e_new, e); + } + BLI_assert(bmesh_radial_length(e->l) == radlen - 1); BLI_assert(bmesh_radial_length(e_new->l) == 1); BM_CHECK_ELEMENT(e_new); BM_CHECK_ELEMENT(e); - - return true; } /** @@ -2142,8 +2168,8 @@ BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *l_sep) /* peel the face from the edge radials on both sides of the * loop vert, disconnecting the face from its fan */ - bmesh_edge_separate(bm, l_sep->e, l_sep); - bmesh_edge_separate(bm, l_sep->prev->e, l_sep->prev); + bmesh_edge_separate(bm, l_sep->e, l_sep, false); + bmesh_edge_separate(bm, l_sep->prev->e, l_sep->prev, false); if (bmesh_disk_count(v_sep) == 2) { /* If there are still only two edges out of v_sep, then @@ -2161,7 +2187,7 @@ BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *l_sep) /* Split all fans connected to the vert, duplicating it for * each fans. */ - bmesh_vert_separate(bm, v_sep, &vtar, &len); + bmesh_vert_separate(bm, v_sep, &vtar, &len, false); /* There should have been at least two fans cut apart here, * otherwise the early exit would have kicked in. */ diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h index 6e691a9a0b5..c9e806335dd 100644 --- a/source/blender/bmesh/intern/bmesh_core.h +++ b/source/blender/bmesh/intern/bmesh_core.h @@ -50,16 +50,18 @@ void BM_face_kill(BMesh *bm, BMFace *f); void BM_edge_kill(BMesh *bm, BMEdge *e); void BM_vert_kill(BMesh *bm, BMVert *v); -bool bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep); +void bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep, + const bool copy_select); bool BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target); bool BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target); -bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len); +void bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len, + const bool copy_select); bool bmesh_loop_reverse(BMesh *bm, BMFace *f); BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del); -bool BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len, +void BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len, BMEdge **e_in, int e_in_len); /* EULER API - For modifying structure */ diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.c b/source/blender/bmesh/intern/bmesh_edgeloop.c index a484bd2fa27..1f052bd206a 100644 --- a/source/blender/bmesh/intern/bmesh_edgeloop.c +++ b/source/blender/bmesh/intern/bmesh_edgeloop.c @@ -56,7 +56,7 @@ static int bm_vert_other_tag(BMVert *v, BMVert *v_prev, BMEdge **r_e) { BMIter iter; - BMEdge *e, *e_next; + BMEdge *e, *e_next = NULL; unsigned int count = 0; BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) { diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index 446d32de5d2..70d1d4c81df 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -36,7 +36,7 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" -#include "BLI_array.h" +#include "BLI_alloca.h" #include "BLI_math.h" #include "BKE_customdata.h" @@ -205,6 +205,7 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source, const b int i; /* convert the 3d coords into 2d for projection */ + BLI_assert(BM_face_is_normal_valid(source)); axis_dominant_v3_to_m3(axis_mat, source->no); i = 0; @@ -638,6 +639,7 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, int i; /* convert the 3d coords into 2d for projection */ + BLI_assert(BM_face_is_normal_valid(source)); axis_dominant_v3_to_m3(axis_mat, source->no); i = 0; @@ -678,6 +680,7 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source) int i; /* convert the 3d coords into 2d for projection */ + BLI_assert(BM_face_is_normal_valid(source)); axis_dominant_v3_to_m3(axis_mat, source->no); i = 0; diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index 61a326bbf97..0a6c0f4b293 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -70,6 +70,79 @@ static void recount_totsels(BMesh *bm) } /** + * \brief Select Mode Clean + * + * Remove isolated selected elements when in a mode doesn't support them. + * eg: in edge-mode a selected vertex must be connected to a selected edge. + * + * \note this could be made apart of #BM_mesh_select_mode_flush_ex + */ +void BM_mesh_select_mode_clean_ex(BMesh *bm, const short selectmode) +{ + if (selectmode & SCE_SELECT_VERTEX) { + /* pass */ + } + else if (selectmode & SCE_SELECT_EDGE) { + BMIter iter; + + if (bm->totvertsel) { + BMVert *v; + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + BM_elem_flag_disable(v, BM_ELEM_SELECT); + } + bm->totvertsel = 0; + } + + if (bm->totedgesel) { + BMEdge *e; + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { + BM_vert_select_set(bm, e->v1, true); + BM_vert_select_set(bm, e->v2, true); + } + } + } + } + else if (selectmode & SCE_SELECT_FACE) { + BMIter iter; + + if (bm->totvertsel) { + BMVert *v; + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + BM_elem_flag_disable(v, BM_ELEM_SELECT); + } + bm->totvertsel = 0; + } + + if (bm->totedgesel) { + BMEdge *e; + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + BM_elem_flag_disable(e, BM_ELEM_SELECT); + } + bm->totedgesel = 0; + } + + if (bm->totfacesel) { + BMFace *f; + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { + BMLoop *l_iter, *l_first; + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + BM_edge_select_set(bm, l_iter->e, true); + } while ((l_iter = l_iter->next) != l_first); + } + } + } + } +} + +void BM_mesh_select_mode_clean(BMesh *bm) +{ + BM_mesh_select_mode_clean_ex(bm, bm->selectmode); +} + +/** * \brief Select Mode Flush * * Makes sure to flush selections 'upwards' @@ -329,18 +402,15 @@ void BM_edge_select_set(BMesh *bm, BMEdge *e, const bool select) if (BM_elem_flag_test(e, BM_ELEM_SELECT)) bm->totedgesel -= 1; BM_elem_flag_disable(e, BM_ELEM_SELECT); - if (bm->selectmode == SCE_SELECT_EDGE || - bm->selectmode == SCE_SELECT_FACE || - bm->selectmode == (SCE_SELECT_EDGE | SCE_SELECT_FACE)) - { - + if ((bm->selectmode & SCE_SELECT_VERTEX) == 0) { BMIter iter; BMVert *verts[2] = {e->v1, e->v2}; BMEdge *e2; int i; + /* check if the vert is used by a selected edge */ for (i = 0; i < 2; i++) { - int deselect = 1; + bool deselect = true; for (e2 = BM_iter_new(&iter, bm, BM_EDGES_OF_VERT, verts[i]); e2; e2 = BM_iter_step(&iter)) { if (e2 == e) { @@ -348,7 +418,7 @@ void BM_edge_select_set(BMesh *bm, BMEdge *e, const bool select) } if (BM_elem_flag_test(e2, BM_ELEM_SELECT)) { - deselect = 0; + deselect = false; break; } } @@ -501,19 +571,19 @@ static int bm_mesh_flag_count(BMesh *bm, const char htype, const char hflag, BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); if (htype & BM_VERT) { - for (ele = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); ele; ele = BM_iter_step(&iter)) { + BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) { if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) continue; if (BM_elem_flag_test_bool(ele, hflag) == test_for_enabled) tot++; } } if (htype & BM_EDGE) { - for (ele = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL); ele; ele = BM_iter_step(&iter)) { + BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) { if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) continue; if (BM_elem_flag_test_bool(ele, hflag) == test_for_enabled) tot++; } } if (htype & BM_FACE) { - for (ele = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL); ele; ele = BM_iter_step(&iter)) { + BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) { if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) continue; if (BM_elem_flag_test_bool(ele, hflag) == test_for_enabled) tot++; } @@ -746,6 +816,13 @@ void BM_editselection_plane(BMEditSelection *ese, float r_plane[3]) } } +static BMEditSelection *bm_select_history_create(BMHeader *ele) +{ + BMEditSelection *ese = (BMEditSelection *) MEM_callocN(sizeof(BMEditSelection), "BMEdit Selection"); + ese->htype = ele->htype; + ese->ele = (BMElem *)ele; + return ese; +} /* --- macro wrapped funcs --- */ bool _bm_select_history_check(BMesh *bm, const BMHeader *ele) @@ -767,9 +844,7 @@ bool _bm_select_history_remove(BMesh *bm, BMHeader *ele) void _bm_select_history_store_notest(BMesh *bm, BMHeader *ele) { - BMEditSelection *ese = (BMEditSelection *) MEM_callocN(sizeof(BMEditSelection), "BMEdit Selection"); - ese->htype = ele->htype; - ese->ele = (BMElem *)ele; + BMEditSelection *ese = bm_select_history_create(ele); BLI_addtail(&(bm->selected), ese); } @@ -779,6 +854,20 @@ void _bm_select_history_store(BMesh *bm, BMHeader *ele) BM_select_history_store_notest(bm, (BMElem *)ele); } } + + +void _bm_select_history_store_after_notest(BMesh *bm, BMEditSelection *ese_ref, BMHeader *ele) +{ + BMEditSelection *ese = bm_select_history_create(ele); + BLI_insertlinkafter(&(bm->selected), ese_ref, ese); +} + +void _bm_select_history_store_after(BMesh *bm, BMEditSelection *ese_ref, BMHeader *ele) +{ + if (!BM_select_history_check(bm, (BMElem *)ele)) { + BM_select_history_store_after_notest(bm, ese_ref, (BMElem *)ele); + } +} /* --- end macro wrapped funcs --- */ @@ -791,16 +880,13 @@ void BM_select_history_clear(BMesh *bm) void BM_select_history_validate(BMesh *bm) { - BMEditSelection *ese, *nextese; - - ese = bm->selected.first; + BMEditSelection *ese, *ese_next; - while (ese) { - nextese = ese->next; + for (ese = bm->selected.first; ese; ese = ese_next) { + ese_next = ese->next; if (!BM_elem_flag_test(ese->ele, BM_ELEM_SELECT)) { BLI_freelinkN(&(bm->selected), ese); } - ese = nextese; } } diff --git a/source/blender/bmesh/intern/bmesh_marking.h b/source/blender/bmesh/intern/bmesh_marking.h index b7040e63458..f23eac61278 100644 --- a/source/blender/bmesh/intern/bmesh_marking.h +++ b/source/blender/bmesh/intern/bmesh_marking.h @@ -59,6 +59,9 @@ void BM_vert_select_set(BMesh *bm, BMVert *v, const bool select); void BM_edge_select_set(BMesh *bm, BMEdge *e, const bool select); void BM_face_select_set(BMesh *bm, BMFace *f, const bool select); +void BM_mesh_select_mode_clean_ex(BMesh *bm, const short selectmode); +void BM_mesh_select_mode_clean(BMesh *bm); + void BM_mesh_select_mode_set(BMesh *bm, int selectmode); void BM_mesh_select_mode_flush_ex(BMesh *bm, const short selectmode); void BM_mesh_select_mode_flush(BMesh *bm); @@ -84,11 +87,15 @@ void BM_editselection_plane(BMEditSelection *ese, float r_plane[3]); #define BM_select_history_remove(bm, ele) _bm_select_history_remove(bm, &(ele)->head) #define BM_select_history_store_notest(bm, ele) _bm_select_history_store_notest(bm, &(ele)->head) #define BM_select_history_store(bm, ele) _bm_select_history_store(bm, &(ele)->head) +#define BM_select_history_store_after_notest(bm, ese_ref, ele) _bm_select_history_store_after_notest(bm, ese_ref, &(ele)->head) +#define BM_select_history_store_after(bm, ese, ese_ref) _bm_select_history_store_after(bm, ese_ref, &(ele)->head) bool _bm_select_history_check(BMesh *bm, const BMHeader *ele); bool _bm_select_history_remove(BMesh *bm, BMHeader *ele); void _bm_select_history_store_notest(BMesh *bm, BMHeader *ele); void _bm_select_history_store(BMesh *bm, BMHeader *ele); +void _bm_select_history_store_after(BMesh *bm, BMEditSelection *ese_ref, BMHeader *ele); +void _bm_select_history_store_after_notest(BMesh *bm, BMEditSelection *ese_ref, BMHeader *ele); void BM_select_history_validate(BMesh *bm); void BM_select_history_clear(BMesh *em); diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index 7c4af8eaa3b..81d4aad0fdf 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -84,7 +84,7 @@ #include "MEM_guardedalloc.h" #include "BLI_listbase.h" -#include "BLI_array.h" +#include "BLI_alloca.h" #include "BLI_math_vector.h" #include "BKE_mesh.h" @@ -583,9 +583,8 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface) MEdge *med, *medge; BMVert *v, *eve; BMEdge *e; - BMLoop *l; BMFace *f; - BMIter iter, liter; + BMIter iter; int i, j, ototvert; const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); @@ -699,22 +698,26 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface) i = 0; j = 0; BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + BMLoop *l_iter, *l_first; mpoly->loopstart = j; mpoly->totloop = f->len; mpoly->mat_nr = f->mat_nr; mpoly->flag = BM_face_flag_to_mflag(f); - l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f); - for ( ; l; l = BM_iter_step(&liter), j++, mloop++) { - mloop->e = BM_elem_index_get(l->e); - mloop->v = BM_elem_index_get(l->v); + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + mloop->e = BM_elem_index_get(l_iter->e); + mloop->v = BM_elem_index_get(l_iter->v); - /* copy over customdat */ - CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l->head.data, j); - BM_CHECK_ELEMENT(l); - BM_CHECK_ELEMENT(l->e); - BM_CHECK_ELEMENT(l->v); - } + /* copy over customdata */ + CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l_iter->head.data, j); + + j++; + mloop++; + BM_CHECK_ELEMENT(l_iter); + BM_CHECK_ELEMENT(l_iter->e); + BM_CHECK_ELEMENT(l_iter->v); + } while ((l_iter = l_iter->next) != l_first); if (f == bm->act_face) me->act_face = i; diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index cb8e9bd7004..418fc16ea55 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -490,26 +490,22 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float BMEdge *e2; BMVert *tv2; - BMIter iter; - BMLoop *l_iter = NULL, *kvloop = NULL, *tvloop = NULL; - - void *src[2]; - float w[2]; - /* Only intended to be called for 2-valence vertices */ BLI_assert(bmesh_disk_count(v_kill) <= 2); - /* first modify the face loop data */ - w[0] = 1.0f - fac; - w[1] = fac; + /* first modify the face loop data */ if (e_kill->l) { + BMLoop *l_iter; + const float w[2] = {1.0f - fac, fac}; + l_iter = e_kill->l; do { if (l_iter->v == tv && l_iter->next->v == v_kill) { - tvloop = l_iter; - kvloop = l_iter->next; + void *src[2]; + BMLoop *tvloop = l_iter; + BMLoop *kvloop = l_iter->next; src[0] = kvloop->head.data; src[1] = tvloop->head.data; @@ -525,11 +521,12 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float tv2 = BM_edge_other_vert(e2, v_kill); if (join_faces) { + BMIter fiter; BMFace **faces = NULL; BMFace *f; - BLI_array_staticdeclare(faces, 8); + BLI_array_staticdeclare(faces, BM_DEFAULT_ITER_STACK_SIZE); - BM_ITER_ELEM (f, &iter, v_kill, BM_FACES_OF_VERT) { + BM_ITER_ELEM (f, &fiter, v_kill, BM_FACES_OF_VERT) { BLI_array_append(faces, f); } @@ -543,6 +540,8 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float } } + BLI_assert(BLI_array_count(faces) < 8); + BLI_array_free(faces); } else { @@ -553,8 +552,8 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float /* e_new = BM_edge_exists(tv, tv2); */ /* same as return above */ if (e_new && kill_degenerate_faces) { - BLI_array_declare(bad_faces); BMFace **bad_faces = NULL; + BLI_array_staticdeclare(bad_faces, BM_DEFAULT_ITER_STACK_SIZE); BMIter fiter; BMFace *f; @@ -1073,7 +1072,7 @@ BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const bool ccw, const short check_f f_hflag_prev_1 = l1->f->head.hflag; f_hflag_prev_2 = l2->f->head.hflag; - /* don't delete the edge, manually remove the egde after so we can copy its attributes */ + /* don't delete the edge, manually remove the edge after so we can copy its attributes */ f = BM_faces_join_pair(bm, l1->f, l2->f, NULL, true); if (f == NULL) { diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 497c9e1c153..4f8a851c780 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -518,6 +518,7 @@ static BMOpDefine bmo_bridge_loops_def = { {"use_cyclic", BMO_OP_SLOT_BOOL}, {"use_merge", BMO_OP_SLOT_BOOL}, {"merge_factor", BMO_OP_SLOT_FLT}, + {"twist_offset", BMO_OP_SLOT_INT}, {{'\0'}}, }, /* slots_out */ @@ -552,6 +553,29 @@ static BMOpDefine bmo_grid_fill_def = { BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH, }; + +/* + * Fill Holes. + * + * Fill boundary edges with faces, copying surrounding customdata. + */ +static BMOpDefine bmo_holes_fill_def = { + "holes_fill", + /* slots_in */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */ + {"sides", BMO_OP_SLOT_INT}, /* number of face sides to fill */ + {{'\0'}}, + }, + /* slots_out */ + /* maps new faces to the group numbers they came from */ + {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */ + {{'\0'}}, + }, + bmo_holes_fill_exec, + BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH, +}; + + /* * Edge Loop Fill. * @@ -639,6 +663,7 @@ static BMOpDefine bmo_rotate_def = { {{"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 */ + {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -655,6 +680,7 @@ static BMOpDefine bmo_translate_def = { "translate", /* slots_in */ {{"vec", BMO_OP_SLOT_VEC}, /* translation offset */ + {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {{'\0'}}, }, @@ -672,6 +698,7 @@ static BMOpDefine bmo_scale_def = { "scale", /* slots_in */ {{"vec", BMO_OP_SLOT_VEC}, /* scale factor */ + {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {{'\0'}}, }, @@ -691,6 +718,7 @@ static BMOpDefine bmo_transform_def = { "transform", /* slots_in */ {{"matrix", BMO_OP_SLOT_MAT}, /* transform matrix */ + {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {{'\0'}}, }, @@ -840,6 +868,27 @@ static BMOpDefine bmo_connect_verts_def = { }; /* + * Connect Verts Across non Planer Faces. + * + * Split faces by connecting edges along non planer **faces**. + */ +static BMOpDefine bmo_connect_verts_nonplanar_def = { + "connect_verts_nonplanar", + /* slots_in */ + {{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */ + {"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, + {{'\0'}}, + }, + /* slots_out */ + {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, + {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, + {{'\0'}}, + }, + bmo_connect_verts_nonplanar_exec, + BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH, +}; + +/* * Connect Verts. * * Split faces by adding edges that connect **verts**. @@ -947,7 +996,9 @@ static BMOpDefine bmo_dissolve_limit_def = { {"delimit", BMO_OP_SLOT_INT}, {{'\0'}}, }, - {{{'\0'}}}, /* no output */ + /* slots_out */ + {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, + {{'\0'}}}, bmo_dissolve_limit_exec, BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH, }; @@ -1044,7 +1095,7 @@ static BMOpDefine bmo_subdivide_edgering_def = { {{'\0'}}, }, {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */ - {{'\0'}}}, /* no output */ + {{'\0'}}}, bmo_subdivide_edgering_exec, BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH, }; @@ -1133,6 +1184,7 @@ static BMOpDefine bmo_spin_def = { {"axis", BMO_OP_SLOT_VEC}, /* rotation axis */ {"dvec", BMO_OP_SLOT_VEC}, /* translation delta per step */ {"angle", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */ + {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */ {"steps", BMO_OP_SLOT_INT}, /* number of steps */ {"use_duplicate", BMO_OP_SLOT_BOOL}, /* duplicate or extrude? */ {{'\0'}}, @@ -1224,7 +1276,6 @@ static BMOpDefine bmo_rotate_uvs_def = { {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, otherwise clockwise */ {{'\0'}}, }, - /* slots_out */ {{{'\0'}}}, /* no output */ bmo_rotate_uvs_exec, BMO_OPTYPE_FLAG_NOP, @@ -1704,6 +1755,7 @@ const BMOpDefine *bmo_opdefines[] = { &bmo_collapse_def, &bmo_collapse_uvs_def, &bmo_connect_verts_def, + &bmo_connect_verts_nonplanar_def, &bmo_connect_vert_pair_def, &bmo_contextual_create_def, #ifdef WITH_BULLET @@ -1723,6 +1775,7 @@ const BMOpDefine *bmo_opdefines[] = { &bmo_dissolve_limit_def, &bmo_dissolve_verts_def, &bmo_duplicate_def, + &bmo_holes_fill_def, &bmo_edgeloop_fill_def, &bmo_edgenet_fill_def, &bmo_edgenet_prepare_def, diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 63c00d5b545..b71d5a7e7d4 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -34,7 +34,6 @@ #include "BLI_memarena.h" #include "BLI_mempool.h" #include "BLI_listbase.h" -#include "BLI_array.h" #include "BLF_translation.h" @@ -411,7 +410,7 @@ void BMO_slot_mat_set(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], cons slot->data.p = BLI_memarena_alloc(op->arena, sizeof(float) * 4 * 4); if (size == 4) { - memcpy(slot->data.p, mat, sizeof(float) * 4 * 4); + copy_m4_m4(slot->data.p, (float (*)[4])mat); } else if (size == 3) { copy_m4_m3(slot->data.p, (float (*)[3])mat); @@ -508,13 +507,13 @@ bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_na void *BMO_slot_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, int *len) { BMOpSlot *slot = BMO_slot_get(slot_args, slot_name); - void *ret; + void **ret; /* could add support for mapping type */ BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF); - ret = MEM_mallocN(sizeof(void **) * slot->len, __func__); - memcpy(ret, slot->data.buf, sizeof(void **) * slot->len); + ret = MEM_mallocN(sizeof(void *) * slot->len, __func__); + memcpy(ret, slot->data.buf, sizeof(void *) * slot->len); *len = slot->len; return ret; } diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h index 4c6129cf43f..56d63694d88 100644 --- a/source/blender/bmesh/intern/bmesh_operators.h +++ b/source/blender/bmesh/intern/bmesh_operators.h @@ -49,9 +49,9 @@ enum { }; enum { + SUBDIV_SELECT_NONE, SUBDIV_SELECT_ORIG, SUBDIV_SELECT_INNER, - SUBDIV_SELECT_INNER_SEL, SUBDIV_SELECT_LOOPCUT }; diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h index e6a4760060c..33c10411c0f 100644 --- a/source/blender/bmesh/intern/bmesh_operators_private.h +++ b/source/blender/bmesh/intern/bmesh_operators_private.h @@ -40,6 +40,7 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op); void bmo_collapse_exec(BMesh *bm, BMOperator *op); void bmo_collapse_uvs_exec(BMesh *bm, BMOperator *op); void bmo_connect_verts_exec(BMesh *bm, BMOperator *op); +void bmo_connect_verts_nonplanar_exec(BMesh *bm, BMOperator *op); void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op); void bmo_contextual_create_exec(BMesh *bm, BMOperator *op); void bmo_convex_hull_exec(BMesh *bm, BMOperator *op); @@ -58,6 +59,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_edgeloop_fill_exec(BMesh *bm, BMOperator *op); +void bmo_holes_fill_exec(BMesh *bm, BMOperator *op); void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op); void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op); void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op); diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 88186df89fb..43b261c118d 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -32,8 +32,8 @@ #include "MEM_guardedalloc.h" +#include "BLI_alloca.h" #include "BLI_math.h" -#include "BLI_array.h" #include "BLI_scanfill.h" #include "BLI_listbase.h" @@ -95,7 +95,7 @@ static void calc_poly_normal(float normal[3], float verts[][3], int nverts) * * Same as #calc_poly_normal but operates directly on a bmesh face. */ -static void bm_face_calc_poly_normal(BMFace *f, float n[3]) +static void bm_face_calc_poly_normal(const BMFace *f, float n[3]) { BMLoop *l_first = BM_FACE_FIRST_LOOP(f); BMLoop *l_iter = l_first; @@ -125,7 +125,7 @@ static void bm_face_calc_poly_normal(BMFace *f, float n[3]) * Same as #calc_poly_normal and #bm_face_calc_poly_normal * but takes an array of vertex locations. */ -static void bm_face_calc_poly_normal_vertex_cos(BMFace *f, float n[3], +static void bm_face_calc_poly_normal_vertex_cos(BMFace *f, float r_no[3], float const (*vertexCos)[3]) { BMLoop *l_first = BM_FACE_FIRST_LOOP(f); @@ -133,29 +133,47 @@ static void bm_face_calc_poly_normal_vertex_cos(BMFace *f, float n[3], float const *v_prev = vertexCos[BM_elem_index_get(l_first->prev->v)]; float const *v_curr = vertexCos[BM_elem_index_get(l_first->v)]; - zero_v3(n); + zero_v3(r_no); /* Newell's Method */ do { - add_newell_cross_v3_v3v3(n, v_prev, v_curr); + add_newell_cross_v3_v3v3(r_no, v_prev, v_curr); l_iter = l_iter->next; v_prev = v_curr; v_curr = vertexCos[BM_elem_index_get(l_iter->v)]; } while (l_iter != l_first); - if (UNLIKELY(normalize_v3(n) == 0.0f)) { - n[2] = 1.0f; /* other axis set to 0.0 */ + if (UNLIKELY(normalize_v3(r_no) == 0.0f)) { + r_no[2] = 1.0f; /* other axis set to 0.0 */ } } /** + * \brief COMPUTE POLY CENTER (BMFace) + */ +static void bm_face_calc_poly_center_mean_vertex_cos(BMFace *f, float r_cent[3], + float const (*vertexCos)[3]) +{ + BMLoop *l_first = BM_FACE_FIRST_LOOP(f); + BMLoop *l_iter = l_first; + + zero_v3(r_cent); + + /* Newell's Method */ + do { + add_v3_v3(r_cent, vertexCos[BM_elem_index_get(l_iter->v)]); + } while ((l_iter = l_iter->next) != l_first); + mul_v3_fl(r_cent, 1.0f / f->len); +} + +/** * For tools that insist on using triangles, ideally we would cache this data. * * \param r_loops Store face loop pointers, (f->len) * \param r_index Store triangle triples, indicies into \a r_loops, ((f->len - 2) * 3) */ -int BM_face_calc_tessellation(BMFace *f, BMLoop **r_loops, int (*_r_index)[3]) +int BM_face_calc_tessellation(const BMFace *f, BMLoop **r_loops, int (*_r_index)[3]) { int *r_index = (int *)_r_index; BMLoop *l_first = BM_FACE_FIRST_LOOP(f); @@ -370,8 +388,7 @@ void BM_face_calc_center_bounds(BMFace *f, float r_cent[3]) */ void BM_face_calc_center_mean(BMFace *f, float r_cent[3]) { - BMLoop *l_iter; - BMLoop *l_first; + BMLoop *l_iter, *l_first; zero_v3(r_cent); @@ -379,9 +396,7 @@ void BM_face_calc_center_mean(BMFace *f, float r_cent[3]) do { add_v3_v3(r_cent, l_iter->v->co); } while ((l_iter = l_iter->next) != l_first); - - if (f->len) - mul_v3_fl(r_cent, 1.0f / (float) f->len); + mul_v3_fl(r_cent, 1.0f / (float) f->len); } /** @@ -564,7 +579,7 @@ void BM_vert_normal_update_all(BMVert *v) * is passed in as well. */ -void BM_face_calc_normal(BMFace *f, float r_no[3]) +void BM_face_calc_normal(const BMFace *f, float r_no[3]) { BMLoop *l; @@ -601,9 +616,9 @@ void BM_face_normal_update(BMFace *f) BM_face_calc_normal(f, f->no); } -/* exact same as 'bmesh_face_normal_update' but accepts vertex coords */ -void BM_face_normal_update_vcos(BMesh *bm, BMFace *f, float no[3], - float const (*vertexCos)[3]) +/* exact same as 'BM_face_calc_normal' but accepts vertex coords */ +void BM_face_calc_normal_vcos(BMesh *bm, BMFace *f, float r_no[3], + float const (*vertexCos)[3]) { BMLoop *l; @@ -620,7 +635,7 @@ void BM_face_normal_update_vcos(BMesh *bm, BMFace *f, float no[3], const float *co3 = vertexCos[BM_elem_index_get((l = l->next)->v)]; const float *co4 = vertexCos[BM_elem_index_get((l->next)->v)]; - normal_quad_v3(no, co1, co2, co3, co4); + normal_quad_v3(r_no, co1, co2, co3, co4); break; } case 3: @@ -629,22 +644,33 @@ void BM_face_normal_update_vcos(BMesh *bm, BMFace *f, float no[3], const float *co2 = vertexCos[BM_elem_index_get((l = l->next)->v)]; const float *co3 = vertexCos[BM_elem_index_get((l->next)->v)]; - normal_tri_v3(no, co1, co2, co3); + normal_tri_v3(r_no, co1, co2, co3); break; } case 0: { - zero_v3(no); + zero_v3(r_no); break; } default: { - bm_face_calc_poly_normal_vertex_cos(f, no, vertexCos); + bm_face_calc_poly_normal_vertex_cos(f, r_no, vertexCos); break; } } } +/* exact same as 'BM_face_calc_normal' but accepts vertex coords */ +void BM_face_calc_center_mean_vcos(BMesh *bm, BMFace *f, float r_cent[3], + float const (*vertexCos)[3]) +{ + /* must have valid index data */ + BLI_assert((bm->elem_index_dirty & BM_VERT) == 0); + (void)bm; + + bm_face_calc_poly_center_mean_vertex_cos(f, r_cent, vertexCos); +} + /** * \brief Face Flip Normal * @@ -980,6 +1006,8 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, float *abscoss = BLI_array_alloca(abscoss, f_len_orig); float mat[3][3]; + BLI_assert(BM_face_is_normal_valid(f)); + axis_dominant_v3_to_m3(mat, f->no); /* copy vertex coordinates to vertspace area */ @@ -1035,7 +1063,7 @@ void BM_face_legal_splits(BMFace *f, BMLoop *(*loops)[2], int len) { const int len2 = len * 2; BMLoop *l; - float v1[2], v2[2], v3[2] /*, v4[3 */, no[3], mid[2], *p1, *p2, *p3, *p4; + float v1[2], v2[2], v3[2], mid[2], *p1, *p2, *p3, *p4; float out[2] = {-FLT_MAX, -FLT_MAX}; float axis_mat[3][3]; float (*projverts)[2] = BLI_array_alloca(projverts, f->len); @@ -1043,10 +1071,9 @@ void BM_face_legal_splits(BMFace *f, BMLoop *(*loops)[2], int len) float fac1 = 1.0000001f, fac2 = 0.9f; //9999f; //0.999f; int i, j, a = 0, clen; - /* TODO, the face normal may already be correct */ - BM_face_calc_normal(f, no); + BLI_assert(BM_face_is_normal_valid(f)); - axis_dominant_v3_to_m3(axis_mat, no); + axis_dominant_v3_to_m3(axis_mat, f->no); for (i = 0, l = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l = l->next) { BM_elem_index_set(l, i); /* set_loop */ diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h index 2f6b54b91d3..e5dc5c081c3 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.h +++ b/source/blender/bmesh/intern/bmesh_polygon.h @@ -27,23 +27,25 @@ * \ingroup bmesh */ -int BM_face_calc_tessellation(BMFace *f, BMLoop **r_loops, int (*r_index)[3]) +int BM_face_calc_tessellation(const BMFace *f, BMLoop **r_loops, int (*r_index)[3]) #ifdef __GNUC__ __attribute__((warn_unused_result)) __attribute__((nonnull)) #endif ; -void BM_face_calc_normal(BMFace *f, float r_no[3]); +void BM_face_calc_normal(const BMFace *f, float r_no[3]); +void BM_face_calc_normal_vcos(BMesh *bm, BMFace *f, float r_no[3], + float const (*vertexCos)[3]); float BM_face_calc_area(BMFace *f); float BM_face_calc_perimeter(BMFace *f); void BM_face_calc_plane(BMFace *f, float r_plane[3]); void BM_face_calc_center_bounds(BMFace *f, float center[3]); void BM_face_calc_center_mean(BMFace *f, float center[3]); +void BM_face_calc_center_mean_vcos(BMesh *bm, BMFace *f, float r_cent[3], + float const (*vertexCos)[3]); void BM_face_calc_center_mean_weighted(BMFace *f, float center[3]); void BM_face_normal_update(BMFace *f); -void BM_face_normal_update_vcos(BMesh *bm, BMFace *f, float no[3], - float const (*vertexCos)[3]); void BM_edge_normals_update(BMEdge *e); diff --git a/source/blender/bmesh/intern/bmesh_private.h b/source/blender/bmesh/intern/bmesh_private.h index 6fd18c07179..7ec418b2253 100644 --- a/source/blender/bmesh/intern/bmesh_private.h +++ b/source/blender/bmesh/intern/bmesh_private.h @@ -53,8 +53,8 @@ int bmesh_elem_check(void *element, const char htype); } (void)0 #endif -int bmesh_radial_length(BMLoop *l); -int bmesh_disk_count(BMVert *v); +int bmesh_radial_length(const BMLoop *l); +int bmesh_disk_count(const BMVert *v); /** * Internal BMHeader.api_flag diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 720997fcef8..6eab3c625fa 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -33,8 +33,8 @@ #include "MEM_guardedalloc.h" -#include "BLI_array.h" #include "BLI_math.h" +#include "BLI_alloca.h" #include "bmesh.h" #include "intern/bmesh_private.h" @@ -336,18 +336,18 @@ bool BM_verts_in_face(BMFace *f, BMVert **varr, int len) /** * Returns whether or not a given edge is is part of a given face. */ -bool BM_edge_in_face(BMFace *f, BMEdge *e) +bool BM_edge_in_face(BMEdge *e, BMFace *f) { - BMLoop *l_iter; - BMLoop *l_first; - - l_iter = l_first = BM_FACE_FIRST_LOOP(f); + if (e->l) { + BMLoop *l_iter, *l_first; - do { - if (l_iter->e == e) { - return true; - } - } while ((l_iter = l_iter->next) != l_first); + l_iter = l_first = e->l; + do { + if (l_iter->f == f) { + return true; + } + } while ((l_iter = l_iter->radial_next) != l_first); + } return false; } @@ -644,7 +644,7 @@ int BM_vert_face_count(BMVert *v) * Tests whether or not the vertex is part of a wire edge. * (ie: has no faces attached to it) */ -bool BM_vert_is_wire(BMVert *v) +bool BM_vert_is_wire(const BMVert *v) { if (v->e) { BMEdge *e_first, *e_iter; @@ -667,7 +667,7 @@ bool BM_vert_is_wire(BMVert *v) * Tests whether or not the edge is part of a wire. * (ie: has no faces attached to it) */ -bool BM_edge_is_wire(BMEdge *e) +bool BM_edge_is_wire(const BMEdge *e) { return (e->l == NULL); } @@ -679,7 +679,7 @@ bool BM_edge_is_wire(BMEdge *e) * 3: Is part of a an edge with more than 2 faces. * 4: Is part of a wire edge. */ -bool BM_vert_is_manifold(BMVert *v) +bool BM_vert_is_manifold(const BMVert *v) { BMEdge *e, *e_old; BMLoop *l; @@ -744,7 +744,7 @@ bool BM_vert_is_manifold(BMVert *v) */ #if 1 /* fast path for checking manifold */ -bool BM_edge_is_manifold(BMEdge *e) +bool BM_edge_is_manifold(const BMEdge *e) { const BMLoop *l = e->l; return (l && (l->radial_next != l) && /* not 0 or 1 face users */ @@ -767,7 +767,7 @@ int BM_edge_is_manifold(BMEdge *e) * Tests that the edge is manifold and * that both its faces point the same way. */ -bool BM_edge_is_contiguous(BMEdge *e) +bool BM_edge_is_contiguous(const BMEdge *e) { const BMLoop *l = e->l; const BMLoop *l_other; @@ -780,7 +780,7 @@ bool BM_edge_is_contiguous(BMEdge *e) * Check if the edge is convex or concave * (depends on face winding) */ -bool BM_edge_is_convex(BMEdge *e) +bool BM_edge_is_convex(const BMEdge *e) { if (BM_edge_is_manifold(e)) { BMLoop *l1 = e->l; @@ -803,7 +803,7 @@ bool BM_edge_is_convex(BMEdge *e) */ #if 1 /* fast path for checking boundary */ -bool BM_edge_is_boundary(BMEdge *e) +bool BM_edge_is_boundary(const BMEdge *e) { const BMLoop *l = e->l; return (l && (l->radial_next == l)); @@ -821,7 +821,7 @@ int BM_edge_is_boundary(BMEdge *e) } #endif -bool BM_vert_is_boundary(BMVert *v) +bool BM_vert_is_boundary(const BMVert *v) { if (v->e) { BMEdge *e_first, *e_iter; @@ -884,15 +884,15 @@ bool BM_face_share_face_check(BMFace *f1, BMFace *f2) /** * Counts the number of edges two faces share (if any) */ -int BM_face_share_edge_count(BMFace *f1, BMFace *f2) +int BM_face_share_edge_count(BMFace *f_a, BMFace *f_b) { BMLoop *l_iter; BMLoop *l_first; int count = 0; - l_iter = l_first = BM_FACE_FIRST_LOOP(f1); + l_iter = l_first = BM_FACE_FIRST_LOOP(f_a); do { - if (bmesh_radial_face_find(l_iter->e, f2)) { + if (BM_edge_in_face(l_iter->e, f_b)) { count++; } } while ((l_iter = l_iter->next) != l_first); @@ -910,7 +910,7 @@ bool BM_face_share_edge_check(BMFace *f1, BMFace *f2) l_iter = l_first = BM_FACE_FIRST_LOOP(f1); do { - if (bmesh_radial_face_find(l_iter->e, f2)) { + if (BM_edge_in_face(l_iter->e, f2)) { return true; } } while ((l_iter = l_iter->next) != l_first); @@ -930,7 +930,7 @@ bool BM_edge_share_face_check(BMEdge *e1, BMEdge *e2) l = e1->l; do { f = l->f; - if (bmesh_radial_face_find(e2, f)) { + if (BM_edge_in_face(e2, f)) { return true; } l = l->radial_next; @@ -952,7 +952,7 @@ bool BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2) do { f = l->f; if (f->len == 4) { - if (bmesh_radial_face_find(e2, f)) { + if (BM_edge_in_face(e2, f)) { return true; } } @@ -1047,8 +1047,8 @@ BMLoop *BM_face_edge_share_loop(BMFace *f, BMEdge *e) * \note This is in fact quite a simple check, mainly include this function so the intent is more obvious. * We know these 2 verts will _always_ make up the loops edge */ -void BM_edge_ordered_verts_ex(BMEdge *edge, BMVert **r_v1, BMVert **r_v2, - BMLoop *edge_loop) +void BM_edge_ordered_verts_ex(const BMEdge *edge, BMVert **r_v1, BMVert **r_v2, + const BMLoop *edge_loop) { BLI_assert(edge_loop->e == edge); (void)edge; /* quiet warning in release build */ @@ -1056,7 +1056,7 @@ void BM_edge_ordered_verts_ex(BMEdge *edge, BMVert **r_v1, BMVert **r_v2, *r_v2 = edge_loop->next->v; } -void BM_edge_ordered_verts(BMEdge *edge, BMVert **r_v1, BMVert **r_v2) +void BM_edge_ordered_verts(const BMEdge *edge, BMVert **r_v1, BMVert **r_v2) { BM_edge_ordered_verts_ex(edge, r_v1, r_v2, edge->l); } @@ -1065,7 +1065,7 @@ void BM_edge_ordered_verts(BMEdge *edge, BMVert **r_v1, BMVert **r_v2) * Check if the loop is convex or concave * (depends on face normal) */ -bool BM_loop_is_convex(BMLoop *l) +bool BM_loop_is_convex(const BMLoop *l) { float e_dir_prev[3]; float e_dir_next[3]; @@ -1182,11 +1182,11 @@ void BM_loop_calc_face_tangent(BMLoop *l, float r_tangent[3]) * * \return angle in radians */ -float BM_edge_calc_face_angle(BMEdge *e) +float BM_edge_calc_face_angle(const BMEdge *e) { if (BM_edge_is_manifold(e)) { - BMLoop *l1 = e->l; - BMLoop *l2 = e->l->radial_next; + const BMLoop *l1 = e->l; + const BMLoop *l2 = e->l->radial_next; return angle_normalized_v3v3(l1->f->no, l2->f->no); } else { @@ -1202,7 +1202,7 @@ float BM_edge_calc_face_angle(BMEdge *e) * * \return angle in radians */ -float BM_edge_calc_face_angle_signed(BMEdge *e) +float BM_edge_calc_face_angle_signed(const BMEdge *e) { if (BM_edge_is_manifold(e)) { BMLoop *l1 = e->l; @@ -1228,7 +1228,7 @@ float BM_edge_calc_face_angle_signed(BMEdge *e) * \param r_tangent The loop corner tangent to set */ -void BM_edge_calc_face_tangent(BMEdge *e, BMLoop *e_loop, float r_tangent[3]) +void BM_edge_calc_face_tangent(const BMEdge *e, const BMLoop *e_loop, float r_tangent[3]) { float tvec[3]; BMVert *v1, *v2; @@ -1685,13 +1685,13 @@ bool BM_face_exists_multi_edge(BMEdge **earr, int len) } /* convenience functions for checking flags */ -bool BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag) +bool BM_edge_is_any_vert_flag_test(const BMEdge *e, const char hflag) { return (BM_elem_flag_test(e->v1, hflag) || BM_elem_flag_test(e->v2, hflag)); } -bool BM_face_is_any_vert_flag_test(BMFace *f, const char hflag) +bool BM_face_is_any_vert_flag_test(const BMFace *f, const char hflag) { BMLoop *l_iter; BMLoop *l_first; @@ -1705,7 +1705,7 @@ bool BM_face_is_any_vert_flag_test(BMFace *f, const char hflag) return false; } -bool BM_face_is_any_edge_flag_test(BMFace *f, const char hflag) +bool BM_face_is_any_edge_flag_test(const BMFace *f, const char hflag) { BMLoop *l_iter; BMLoop *l_first; @@ -1719,7 +1719,19 @@ bool BM_face_is_any_edge_flag_test(BMFace *f, const char hflag) return false; } -static void bm_mesh_calc_volume_face(BMFace *f, float *r_vol) +/** + * Use within assert's to check normals are valid. + */ +bool BM_face_is_normal_valid(const BMFace *f) +{ + const float eps = 0.0001f; + float no[3]; + + BM_face_calc_normal(f, no); + return len_squared_v3v3(no, f->no) < (eps * eps); +} + +static void bm_mesh_calc_volume_face(const BMFace *f, float *r_vol) { int tottri = f->len - 2; BMLoop **loops = BLI_array_alloca(loops, f->len); @@ -1758,20 +1770,27 @@ float BM_mesh_calc_volume(BMesh *bm, bool is_signed) return vol; } - +/* note, almost duplicate of BM_mesh_calc_edge_groups, keep in sync */ /** - * TODO (as we need) - * - option to walk over faces by verts. - * - option to walk over non manifold edges. + * Calculate isolated groups of faces with optional filtering. * * \param bm the BMesh. - * \param r_groups_array Array of ints to fill in, length of bm->totface. + * \param r_groups_array Array of ints to fill in, length of bm->totface + * (or when hflag_test is set, the number of flagged faces). * \param r_group_index index, length pairs into \a r_groups_array, size of return value - * int pairs: (array_start, array_length). + * int pairs: (array_start, array_length). + * \param filter_fn Filter the edges or verts we step over (depends on \a htype_step) + * as to which types we deal with. + * \param user_data Optional user data for \a filter_fn, can be NULL. + * \param hflag_test Optional flag to test faces, + * use to exclude faces from the calculation, 0 for all faces. + * \param htype_step BM_VERT to walk over face-verts, BM_EDGE to walk over faces edges + * (having both set is supported too). * \return The number of groups found. */ int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_index)[2], - bool (*filter_fn)(BMElem *, void *user_data), void *user_data, const char htype) + BMElemFilterFunc filter_fn, void *user_data, + const char hflag_test, const char htype_step) { #ifdef DEBUG int group_index_len = 1; @@ -1786,11 +1805,11 @@ int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_inde int group_curr = 0; - const unsigned int tot_faces = bm->totface; + unsigned int tot_faces = 0; unsigned int tot_touch = 0; - BMFace **fstack; - STACK_DECLARE(fstack); + BMFace **stack; + STACK_DECLARE(stack); BMIter iter; BMFace *f; @@ -1798,30 +1817,38 @@ int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_inde STACK_INIT(group_array); - BLI_assert(((htype & ~(BM_VERT | BM_EDGE)) == 0) && (htype != 0)); + BLI_assert(((htype_step & ~(BM_VERT | BM_EDGE)) == 0) && (htype_step != 0)); /* init the array */ BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) { + if ((hflag_test == 0) || BM_elem_flag_test(f, hflag_test)) { + tot_faces++; + BM_elem_flag_disable(f, BM_ELEM_TAG); + } + else { + /* never walk over tagged */ + BM_elem_flag_enable(f, BM_ELEM_TAG); + } + BM_elem_index_set(f, i); /* set_inline */ - BM_elem_flag_disable(f, BM_ELEM_TAG); } bm->elem_index_dirty &= ~BM_FACE; /* detect groups */ - fstack = MEM_mallocN(sizeof(*fstack) * tot_faces, __func__); + stack = MEM_mallocN(sizeof(*stack) * tot_faces, __func__); while (tot_touch != tot_faces) { - int *fg; + int *group_item; bool ok = false; BLI_assert(tot_touch < tot_faces); - STACK_INIT(fstack); + STACK_INIT(stack); BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { if (BM_elem_flag_test(f, BM_ELEM_TAG) == false) { BM_elem_flag_enable(f, BM_ELEM_TAG); - STACK_PUSH(fstack, f); + STACK_PUSH(stack, f); ok = true; break; } @@ -1835,48 +1862,50 @@ int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_inde group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_index_len); } - fg = group_index[group_curr]; - fg[0] = STACK_SIZE(group_array); - fg[1] = 0; + group_item = group_index[group_curr]; + group_item[0] = STACK_SIZE(group_array); + group_item[1] = 0; - while ((f = STACK_POP(fstack))) { + while ((f = STACK_POP(stack))) { BMLoop *l_iter, *l_first; /* add face */ STACK_PUSH(group_array, BM_elem_index_get(f)); tot_touch++; - fg[1]++; + group_item[1]++; /* done */ - if (htype & BM_EDGE) { + if (htype_step & BM_EDGE) { /* search for other faces */ l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { BMLoop *l_radial_iter = l_iter->radial_next; - if ((l_radial_iter != l_iter) && filter_fn((BMElem *)l_iter->e, user_data)) { + if ((l_radial_iter != l_iter) && + ((filter_fn == NULL) || filter_fn((BMElem *)l_iter->e, user_data))) + { do { BMFace *f_other = l_radial_iter->f; if (BM_elem_flag_test(f_other, BM_ELEM_TAG) == false) { BM_elem_flag_enable(f_other, BM_ELEM_TAG); - STACK_PUSH(fstack, f_other); + STACK_PUSH(stack, f_other); } } while ((l_radial_iter = l_radial_iter->radial_next) != l_iter); } } while ((l_iter = l_iter->next) != l_first); } - if (htype & BM_VERT) { + if (htype_step & BM_VERT) { BMIter liter; /* search for other faces */ l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { - if (filter_fn((BMElem *)l_iter->v, user_data)) { + if ((filter_fn == NULL) || filter_fn((BMElem *)l_iter->v, user_data)) { BMLoop *l_other; BM_ITER_ELEM (l_other, &liter, l_iter, BM_LOOPS_OF_LOOP) { BMFace *f_other = l_other->f; if (BM_elem_flag_test(f_other, BM_ELEM_TAG) == false) { BM_elem_flag_enable(f_other, BM_ELEM_TAG); - STACK_PUSH(fstack, f_other); + STACK_PUSH(stack, f_other); } } } @@ -1887,7 +1916,139 @@ int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_inde group_curr++; } - MEM_freeN(fstack); + MEM_freeN(stack); + + /* reduce alloc to required size */ + group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_curr); + *r_group_index = group_index; + + return group_curr; +} + +/* note, almost duplicate of BM_mesh_calc_face_groups, keep in sync */ +/** + * Calculate isolated groups of edges with optional filtering. + * + * \param bm the BMesh. + * \param r_groups_array Array of ints to fill in, length of bm->totedge + * (or when hflag_test is set, the number of flagged edges). + * \param r_group_index index, length pairs into \a r_groups_array, size of return value + * int pairs: (array_start, array_length). + * \param filter_fn Filter the edges or verts we step over (depends on \a htype_step) + * as to which types we deal with. + * \param user_data Optional user data for \a filter_fn, can be NULL. + * \param hflag_test Optional flag to test edges, + * use to exclude edges from the calculation, 0 for all edges. + * \return The number of groups found. + * + * \note Unlike #BM_mesh_calc_face_groups there is no 'htype_step' argument, + * since we always walk over verts. + */ +int BM_mesh_calc_edge_groups(BMesh *bm, int *r_groups_array, int (**r_group_index)[2], + BMElemFilterFunc filter_fn, void *user_data, + const char hflag_test) +{ +#ifdef DEBUG + int group_index_len = 1; +#else + int group_index_len = 32; +#endif + + int (*group_index)[2] = MEM_mallocN(sizeof(*group_index) * group_index_len, __func__); + + int *group_array = r_groups_array; + STACK_DECLARE(group_array); + + int group_curr = 0; + + unsigned int tot_edges = 0; + unsigned int tot_touch = 0; + + BMEdge **stack; + STACK_DECLARE(stack); + + BMIter iter; + BMEdge *e; + int i; + + STACK_INIT(group_array); + + /* init the array */ + BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) { + if ((hflag_test == 0) || BM_elem_flag_test(e, hflag_test)) { + tot_edges++; + BM_elem_flag_disable(e, BM_ELEM_TAG); + } + else { + /* never walk over tagged */ + BM_elem_flag_enable(e, BM_ELEM_TAG); + } + + BM_elem_index_set(e, i); /* set_inline */ + } + bm->elem_index_dirty &= ~BM_EDGE; + + /* detect groups */ + stack = MEM_mallocN(sizeof(*stack) * tot_edges, __func__); + + while (tot_touch != tot_edges) { + int *group_item; + bool ok = false; + + BLI_assert(tot_touch < tot_edges); + + STACK_INIT(stack); + + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_TAG) == false) { + BM_elem_flag_enable(e, BM_ELEM_TAG); + STACK_PUSH(stack, e); + ok = true; + break; + } + } + + BLI_assert(ok == true); + + /* manage arrays */ + if (group_index_len == group_curr) { + group_index_len *= 2; + group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_index_len); + } + + group_item = group_index[group_curr]; + group_item[0] = STACK_SIZE(group_array); + group_item[1] = 0; + + while ((e = STACK_POP(stack))) { + BMIter viter; + BMIter eiter; + BMVert *v; + + /* add edge */ + STACK_PUSH(group_array, BM_elem_index_get(e)); + tot_touch++; + group_item[1]++; + /* done */ + + /* search for other edges */ + BM_ITER_ELEM (v, &viter, e, BM_VERTS_OF_EDGE) { + if ((filter_fn == NULL) || filter_fn((BMElem *)v, user_data)) { + BMEdge *e_other; + BM_ITER_ELEM (e_other, &eiter, v, BM_EDGES_OF_VERT) { + if (BM_elem_flag_test(e_other, BM_ELEM_TAG) == false) { + BM_elem_flag_enable(e_other, BM_ELEM_TAG); + STACK_PUSH(stack, e_other); + } + } + } + } + } + + group_curr++; + } + + MEM_freeN(stack); /* reduce alloc to required size */ group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_curr); diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index f62de692778..2c931de995e 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -27,11 +27,13 @@ * \ingroup bmesh */ +typedef bool (*BMElemFilterFunc)(BMElem *, void *user_data); + bool BM_vert_in_face(BMFace *f, BMVert *v); int BM_verts_in_face_count(BMFace *f, BMVert **varr, int len); bool BM_verts_in_face(BMFace *f, BMVert **varr, int len); -bool BM_edge_in_face(BMFace *f, BMEdge *e); +bool BM_edge_in_face(BMEdge *e, BMFace *f); bool BM_edge_in_loop(BMEdge *e, BMLoop *l); bool BM_vert_in_edge(const BMEdge *e, const BMVert *v); @@ -56,26 +58,26 @@ int BM_edge_face_count(BMEdge *e); int BM_vert_face_count(BMVert *v); BMEdge *BM_vert_other_disk_edge(BMVert *v, BMEdge *e); -bool BM_vert_is_wire(BMVert *v); -bool BM_edge_is_wire(BMEdge *e); +bool BM_vert_is_wire(const BMVert *v); +bool BM_edge_is_wire(const BMEdge *e); -bool BM_vert_is_manifold(BMVert *v); -bool BM_edge_is_manifold(BMEdge *e); -bool BM_vert_is_boundary(BMVert *v); -bool BM_edge_is_boundary(BMEdge *e); -bool BM_edge_is_contiguous(BMEdge *e); -bool BM_edge_is_convex(BMEdge *e); +bool BM_vert_is_manifold(const BMVert *v); +bool BM_edge_is_manifold(const BMEdge *e); +bool BM_vert_is_boundary(const BMVert *v); +bool BM_edge_is_boundary(const BMEdge *e); +bool BM_edge_is_contiguous(const BMEdge *e); +bool BM_edge_is_convex(const BMEdge *e); -bool BM_loop_is_convex(BMLoop *l); +bool BM_loop_is_convex(const BMLoop *l); float BM_loop_calc_face_angle(BMLoop *l); void BM_loop_calc_face_normal(BMLoop *l, float r_normal[3]); void BM_loop_calc_face_direction(BMLoop *l, float r_normal[3]); void BM_loop_calc_face_tangent(BMLoop *l, float r_tangent[3]); -float BM_edge_calc_face_angle(BMEdge *e); -float BM_edge_calc_face_angle_signed(BMEdge *e); -void BM_edge_calc_face_tangent(BMEdge *e, BMLoop *e_loop, float r_tangent[3]); +float BM_edge_calc_face_angle(const BMEdge *e); +float BM_edge_calc_face_angle_signed(const BMEdge *e); +void BM_edge_calc_face_tangent(const BMEdge *e, const BMLoop *e_loop, float r_tangent[3]); float BM_vert_calc_edge_angle(BMVert *v); float BM_vert_calc_shell_factor(BMVert *v); @@ -93,7 +95,7 @@ bool BM_face_exists(BMVert **varr, int len, BMFace **r_existface); bool BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len); bool BM_face_exists_multi_edge(BMEdge **earr, int len); -int BM_face_share_face_count(BMFace *f1, BMFace *f2); +int BM_face_share_face_count(BMFace *f_a, BMFace *f_b); int BM_face_share_edge_count(BMFace *f1, BMFace *f2); bool BM_face_share_face_check(BMFace *f1, BMFace *f2); @@ -106,17 +108,24 @@ BMVert *BM_edge_share_vert(BMEdge *e1, BMEdge *e2); BMLoop *BM_face_vert_share_loop(BMFace *f, BMVert *v); BMLoop *BM_face_edge_share_loop(BMFace *f, BMEdge *e); -void BM_edge_ordered_verts(BMEdge *edge, BMVert **r_v1, BMVert **r_v2); -void BM_edge_ordered_verts_ex(BMEdge *edge, BMVert **r_v1, BMVert **r_v2, - BMLoop *edge_loop); +void BM_edge_ordered_verts(const BMEdge *edge, BMVert **r_v1, BMVert **r_v2); +void BM_edge_ordered_verts_ex(const BMEdge *edge, BMVert **r_v1, BMVert **r_v2, + const BMLoop *edge_loop); + +bool BM_edge_is_any_vert_flag_test(const BMEdge *e, const char hflag); +bool BM_face_is_any_vert_flag_test(const BMFace *f, const char hflag); +bool BM_face_is_any_edge_flag_test(const BMFace *f, const char hflag); -bool BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag); -bool BM_face_is_any_vert_flag_test(BMFace *f, const char hflag); -bool BM_face_is_any_edge_flag_test(BMFace *f, const char hflag); +bool BM_face_is_normal_valid(const BMFace *f); float BM_mesh_calc_volume(BMesh *bm, bool is_signed); + int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_index)[2], - bool (*filter_fn)(BMElem *, void *user_data), void *user_data, const char htype); + BMElemFilterFunc filter_fn, void *user_data, + const char hflag_test, const char htype_step); +int BM_mesh_calc_edge_groups(BMesh *bm, int *r_groups_array, int (**r_group_index)[2], + BMElemFilterFunc filter_fn, void *user_data, + const char hflag_test); /* not really any good place to put this */ float bmesh_subd_falloff_calc(const int falloff, float val); diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c index a0907f0db7a..286425cbacf 100644 --- a/source/blender/bmesh/intern/bmesh_structure.c +++ b/source/blender/bmesh/intern/bmesh_structure.c @@ -45,7 +45,7 @@ bool bmesh_vert_in_edge(const BMEdge *e, const BMVert *v) if (e->v1 == v || e->v2 == v) return true; return false; } -bool bmesh_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e) +bool bmesh_verts_in_edge(const BMVert *v1, const BMVert *v2, const BMEdge *e) { if (e->v1 == v1 && e->v2 == v2) return true; else if (e->v1 == v2 && e->v2 == v1) return true; @@ -130,7 +130,6 @@ bool bmesh_edge_swapverts(BMEdge *e, BMVert *v_orig, BMVert *v_new) * Functions relating to this cycle: * - #bmesh_radial_append * - #bmesh_radial_loop_remove - * - #bmesh_radial_face_find * - #bmesh_radial_facevert_count * - #bmesh_radial_faceloop_find_first * - #bmesh_radial_faceloop_find_next @@ -217,7 +216,7 @@ void bmesh_disk_edge_remove(BMEdge *e, BMVert *v) * * \return Pointer to the next edge in the disk cycle for the vertex v. */ -BMEdge *bmesh_disk_edge_next(BMEdge *e, BMVert *v) +BMEdge *bmesh_disk_edge_next(const BMEdge *e, const BMVert *v) { if (v == e->v1) return e->v1_disk_link.next; @@ -226,7 +225,7 @@ BMEdge *bmesh_disk_edge_next(BMEdge *e, BMVert *v) return NULL; } -BMEdge *bmesh_disk_edge_prev(BMEdge *e, BMVert *v) +BMEdge *bmesh_disk_edge_prev(const BMEdge *e, const BMVert *v) { if (v == e->v1) return e->v1_disk_link.prev; @@ -235,7 +234,7 @@ BMEdge *bmesh_disk_edge_prev(BMEdge *e, BMVert *v) return NULL; } -BMEdge *bmesh_disk_edge_exists(BMVert *v1, BMVert *v2) +BMEdge *bmesh_disk_edge_exists(const BMVert *v1, const BMVert *v2) { BMEdge *e_iter, *e_first; @@ -252,7 +251,7 @@ BMEdge *bmesh_disk_edge_exists(BMVert *v1, BMVert *v2) return NULL; } -int bmesh_disk_count(BMVert *v) +int bmesh_disk_count(const BMVert *v) { if (v->e) { BMEdge *e_first, *e_iter; @@ -305,7 +304,7 @@ bool bmesh_disk_validate(int len, BMEdge *e, BMVert *v) * equivalent to counting the number of * faces incident upon this vertex */ -int bmesh_disk_facevert_count(BMVert *v) +int bmesh_disk_facevert_count(const BMVert *v) { /* is there an edge on this vert at all */ if (v->e) { @@ -334,29 +333,28 @@ int bmesh_disk_facevert_count(BMVert *v) * vert's loops attached * to it. */ -BMEdge *bmesh_disk_faceedge_find_first(BMEdge *e, BMVert *v) +BMEdge *bmesh_disk_faceedge_find_first(const BMEdge *e, const BMVert *v) { - BMEdge *searchedge = NULL; - searchedge = e; + const BMEdge *e_find = e; do { - if (searchedge->l && bmesh_radial_facevert_count(searchedge->l, v)) { - return searchedge; + if (e_find->l && bmesh_radial_facevert_count(e_find->l, v)) { + return (BMEdge *)e_find; } - } while ((searchedge = bmesh_disk_edge_next(searchedge, v)) != e); + } while ((e_find = bmesh_disk_edge_next(e_find, v)) != e); return NULL; } -BMEdge *bmesh_disk_faceedge_find_next(BMEdge *e, BMVert *v) +BMEdge *bmesh_disk_faceedge_find_next(const BMEdge *e, const BMVert *v) { - BMEdge *searchedge = NULL; - searchedge = bmesh_disk_edge_next(e, v); + BMEdge *e_find = NULL; + e_find = bmesh_disk_edge_next(e, v); do { - if (searchedge->l && bmesh_radial_facevert_count(searchedge->l, v)) { - return searchedge; + if (e_find->l && bmesh_radial_facevert_count(e_find->l, v)) { + return e_find; } - } while ((searchedge = bmesh_disk_edge_next(searchedge, v)) != e); - return e; + } while ((e_find = bmesh_disk_edge_next(e_find, v)) != e); + return (BMEdge *)e; } /*****radial cycle functions, e.g. loops surrounding edges**** */ @@ -436,19 +434,19 @@ void bmesh_radial_loop_remove(BMLoop *l, BMEdge *e) * Finds the first loop of v around radial * cycle */ -BMLoop *bmesh_radial_faceloop_find_first(BMLoop *l, BMVert *v) +BMLoop *bmesh_radial_faceloop_find_first(const BMLoop *l, const BMVert *v) { - BMLoop *l_iter; + const BMLoop *l_iter; l_iter = l; do { if (l_iter->v == v) { - return l_iter; + return (BMLoop *)l_iter; } } while ((l_iter = l_iter->radial_next) != l); return NULL; } -BMLoop *bmesh_radial_faceloop_find_next(BMLoop *l, BMVert *v) +BMLoop *bmesh_radial_faceloop_find_next(const BMLoop *l, const BMVert *v) { BMLoop *l_iter; l_iter = l->radial_next; @@ -457,12 +455,12 @@ BMLoop *bmesh_radial_faceloop_find_next(BMLoop *l, BMVert *v) return l_iter; } } while ((l_iter = l_iter->radial_next) != l); - return l; + return (BMLoop *)l; } -int bmesh_radial_length(BMLoop *l) +int bmesh_radial_length(const BMLoop *l) { - BMLoop *l_iter = l; + const BMLoop *l_iter = l; int i = 0; if (!l) @@ -509,28 +507,15 @@ void bmesh_radial_append(BMEdge *e, BMLoop *l) l->e = e; } -bool bmesh_radial_face_find(BMEdge *e, BMFace *f) -{ - BMLoop *l_iter; - int i, len; - - len = bmesh_radial_length(e->l); - for (i = 0, l_iter = e->l; i < len; i++, l_iter = l_iter->radial_next) { - if (l_iter->f == f) - return true; - } - return false; -} - /** * \brief RADIAL COUNT FACE VERT * * Returns the number of times a vertex appears * in a radial cycle */ -int bmesh_radial_facevert_count(BMLoop *l, BMVert *v) +int bmesh_radial_facevert_count(const BMLoop *l, const BMVert *v) { - BMLoop *l_iter; + const BMLoop *l_iter; int count = 0; l_iter = l; do { diff --git a/source/blender/bmesh/intern/bmesh_structure.h b/source/blender/bmesh/intern/bmesh_structure.h index f10e3a12377..f64fb911ab4 100644 --- a/source/blender/bmesh/intern/bmesh_structure.h +++ b/source/blender/bmesh/intern/bmesh_structure.h @@ -47,11 +47,11 @@ bool bmesh_loop_validate(BMFace *f); /* DISK CYCLE MANAGMENT */ void bmesh_disk_edge_append(BMEdge *e, BMVert *v); void bmesh_disk_edge_remove(BMEdge *e, BMVert *v); -BMEdge *bmesh_disk_edge_next(BMEdge *e, BMVert *v); -BMEdge *bmesh_disk_edge_prev(BMEdge *e, BMVert *v); -int bmesh_disk_facevert_count(BMVert *v); -BMEdge *bmesh_disk_faceedge_find_first(BMEdge *e, BMVert *v); -BMEdge *bmesh_disk_faceedge_find_next(BMEdge *e, BMVert *v); +BMEdge *bmesh_disk_edge_next(const BMEdge *e, const BMVert *v); +BMEdge *bmesh_disk_edge_prev(const BMEdge *e, const BMVert *v); +int bmesh_disk_facevert_count(const BMVert *v); +BMEdge *bmesh_disk_faceedge_find_first(const BMEdge *e, const BMVert *v); +BMEdge *bmesh_disk_faceedge_find_next(const BMEdge *e, const BMVert *v); /* RADIAL CYCLE MANAGMENT */ void bmesh_radial_append(BMEdge *e, BMLoop *l); @@ -60,19 +60,18 @@ void bmesh_radial_loop_remove(BMLoop *l, BMEdge *e); * bmesh_radial_loop_next(BMLoop *l) / prev. * just use member access l->radial_next, l->radial_prev now */ -bool bmesh_radial_face_find(BMEdge *e, BMFace *f); -int bmesh_radial_facevert_count(BMLoop *l, BMVert *v); -BMLoop *bmesh_radial_faceloop_find_first(BMLoop *l, BMVert *v); -BMLoop *bmesh_radial_faceloop_find_next(BMLoop *l, BMVert *v); -BMLoop *bmesh_radial_faceloop_find_vert(BMFace *f, BMVert *v); +int bmesh_radial_facevert_count(const BMLoop *l, const BMVert *v); +BMLoop *bmesh_radial_faceloop_find_first(const BMLoop *l, const BMVert *v); +BMLoop *bmesh_radial_faceloop_find_next(const BMLoop *l, const BMVert *v); +BMLoop *bmesh_radial_faceloop_find_vert(const BMFace *f, const BMVert *v); bool bmesh_radial_validate(int radlen, BMLoop *l); /* EDGE UTILITIES */ bool bmesh_vert_in_edge(const BMEdge *e, const BMVert *v); -bool bmesh_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e); +bool bmesh_verts_in_edge(const BMVert *v1, const BMVert *v2, const BMEdge *e); bool bmesh_edge_swapverts(BMEdge *e, BMVert *orig, BMVert *newv); /* relink edge */ BMVert *bmesh_edge_other_vert_get(BMEdge *e, BMVert *v); -BMEdge *bmesh_disk_edge_exists(BMVert *v1, BMVert *v2); +BMEdge *bmesh_disk_edge_exists(const BMVert *v1, const BMVert *v2); bool bmesh_disk_validate(int len, BMEdge *e, BMVert *v); #endif /* __BMESH_STRUCTURE_H__ */ diff --git a/source/blender/bmesh/intern/bmesh_walkers.c b/source/blender/bmesh/intern/bmesh_walkers.c index 04edec01a5c..80b85ab6edd 100644 --- a/source/blender/bmesh/intern/bmesh_walkers.c +++ b/source/blender/bmesh/intern/bmesh_walkers.c @@ -92,10 +92,11 @@ void BMW_init(BMWalker *walker, BMesh *bm, int type, if (UNLIKELY(type >= BMW_MAXWALKERS || type < 0)) { fprintf(stderr, - "Invalid walker type in BMW_init; type: %d, " + "%s: Invalid walker type in BMW_init; type: %d, " "searchmask: (v:%d, e:%d, f:%d), flag: %d, layer: %d\n", - type, mask_vert, mask_edge, mask_face, flag, layer); - BMESH_ASSERT(0); + __func__, type, mask_vert, mask_edge, mask_face, flag, layer); + BLI_assert(0); + return; } if (type != BMW_CUSTOM) { diff --git a/source/blender/bmesh/operators/bmo_beautify.c b/source/blender/bmesh/operators/bmo_beautify.c index 2c0bc7f95d9..22b686db64e 100644 --- a/source/blender/bmesh/operators/bmo_beautify.c +++ b/source/blender/bmesh/operators/bmo_beautify.c @@ -276,7 +276,7 @@ static void bm_edge_update_beauty_cost_single(BMEdge *e, Heap *eheap, HeapNode * } } -/* we have rotated an edge, tag other egdes and clear this one */ +/* we have rotated an edge, tag other edges and clear this one */ static void bm_edge_update_beauty_cost(BMEdge *e, Heap *eheap, HeapNode **eheap_table, GHash **edge_state_arr, const int flag) { @@ -415,9 +415,9 @@ void bmo_beautify_fill_exec(BMesh *bm, BMOperator *op) /* edge is manifold and can be rotated */ if (BM_edge_rotate_check(e) && - /* faces are tagged */ - BMO_elem_flag_test(bm, e->l->f, FACE_MARK) && - BMO_elem_flag_test(bm, e->l->radial_next->f, FACE_MARK)) + /* faces are tagged */ + BMO_elem_flag_test(bm, e->l->f, FACE_MARK) && + BMO_elem_flag_test(bm, e->l->radial_next->f, FACE_MARK)) { BM_elem_index_set(e, edge_array_len); /* set_dirty */ BM_elem_flag_enable(e, BM_ELEM_TAG); diff --git a/source/blender/bmesh/operators/bmo_bridge.c b/source/blender/bmesh/operators/bmo_bridge.c index 5b046524e95..f63e742d8ba 100644 --- a/source/blender/bmesh/operators/bmo_bridge.c +++ b/source/blender/bmesh/operators/bmo_bridge.c @@ -142,7 +142,7 @@ static bool bm_edge_test_cb(BMEdge *e, void *bm_v) static void bridge_loop_pair(BMesh *bm, struct BMEdgeLoopStore *el_store_a, struct BMEdgeLoopStore *el_store_b, - const bool use_merge, const float merge_factor) + const bool use_merge, const float merge_factor, const int twist_offset) { const float eps = 0.00001f; LinkData *el_a_first, *el_b_first; @@ -268,6 +268,15 @@ static void bridge_loop_pair(BMesh *bm, if (is_closed) { bm_bridge_best_rotation(el_store_a, el_store_b); + + /* add twist */ + if (twist_offset != 0) { + const int len_b = BM_edgeloop_length_get(el_store_b); + ListBase *lb_b = BM_edgeloop_verts_get(el_store_b); + const int offset = twist_offset % len_b; + LinkData *el_b = BLI_rfindlink(lb_b, (offset < 0) ? (offset + len_b) : offset); + BLI_rotatelist(lb_b, el_b); + } } /* Assign after flipping is finalized */ @@ -476,6 +485,7 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op) const bool use_merge = BMO_slot_bool_get(op->slots_in, "use_merge"); const float merge_factor = BMO_slot_float_get(op->slots_in, "merge_factor"); const bool use_cyclic = BMO_slot_bool_get(op->slots_in, "use_cyclic") && (use_merge == false); + const int twist_offset = BMO_slot_int_get(op->slots_in, "twist_offset"); int count; bool change = false; @@ -535,7 +545,7 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op) bridge_loop_pair(bm, (struct BMEdgeLoopStore *)el_store, (struct BMEdgeLoopStore *)el_store_next, - use_merge, merge_factor); + use_merge, merge_factor, twist_offset); if (use_pairs) { el_store = el_store->next; } diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c index 50588ad70a9..c718cac4bd6 100644 --- a/source/blender/bmesh/operators/bmo_connect.c +++ b/source/blender/bmesh/operators/bmo_connect.c @@ -29,8 +29,8 @@ #include "MEM_guardedalloc.h" #include "BLI_math.h" -#include "BLI_array.h" #include "BLI_utildefines.h" +#include "BLI_alloca.h" #include "bmesh.h" diff --git a/source/blender/bmesh/operators/bmo_connect_nonplanar.c b/source/blender/bmesh/operators/bmo_connect_nonplanar.c new file mode 100644 index 00000000000..6d30b327a6c --- /dev/null +++ b/source/blender/bmesh/operators/bmo_connect_nonplanar.c @@ -0,0 +1,229 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/bmesh/operators/bmo_connect_nonplanar.c + * \ingroup bmesh + * + * Connect verts non-planer faces iteratively (splits faces). + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" +#include "BLI_utildefines.h" +#include "BLI_alloca.h" + +#include "bmesh.h" + +#include "intern/bmesh_operators_private.h" /* own include */ + +#define EDGE_OUT (1 << 0) +#define FACE_OUT (1 << 1) + +/** + * Calculates the face subset normal. + */ +static bool bm_face_subset_calc_normal(BMLoop *l_first, BMLoop *l_last, float r_no[3]) +{ + float const *v_prev, *v_curr; + + /* Newell's Method */ + BMLoop *l_iter = l_first; + BMLoop *l_term = l_last->next; + + zero_v3(r_no); + + v_prev = l_last->v->co; + do { + v_curr = l_iter->v->co; + add_newell_cross_v3_v3v3(r_no, v_prev, v_curr); + v_prev = v_curr; + } while ((l_iter = l_iter->next) != l_term); + + return (normalize_v3(r_no) != 0.0f); +} + +/** + * Calculates how non-planar the face subset is. + */ +static float bm_face_subset_calc_planar(BMLoop *l_first, BMLoop *l_last, const float no[3]) +{ + float axis_mat[3][3]; + float z_prev, z_curr; + float delta_z = 0.0f; + + /* Newell's Method */ + BMLoop *l_iter = l_first; + BMLoop *l_term = l_last->next; + + axis_dominant_v3_to_m3(axis_mat, no); + + z_prev = dot_m3_v3_row_z(axis_mat, l_last->v->co); + do { + z_curr = dot_m3_v3_row_z(axis_mat, l_iter->v->co); + delta_z += fabsf(z_curr - z_prev); + z_prev = z_curr; + } while ((l_iter = l_iter->next) != l_term); + + return delta_z; +} + +static bool bm_face_split_find(BMFace *f, BMVert *v_pair[2], float *r_angle) +{ + BMLoop *l_iter, *l_first; + BMLoop **l_arr = BLI_array_alloca(l_arr, f->len); + const unsigned int f_len = f->len; + unsigned int i_a, i_b; + bool found = false; + + /* angle finding */ + float err_best = FLT_MAX; + float angle_best = FLT_MAX; + + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + i_a = 0; + do { + l_arr[i_a++] = l_iter; + } while ((l_iter = l_iter->next) != l_first); + + /* now for the big search, O(N^2), however faces normally aren't so large */ + for (i_a = 0; i_a < f_len; i_a++) { + BMLoop *l_a = l_arr[i_a]; + for (i_b = i_a + 2; i_b < f_len; i_b++) { + BMLoop *l_b = l_arr[i_b]; + /* check these are not touching + * (we could be smarter here) */ + if ((l_a->next != l_b) && + (l_a->prev != l_b)) + { + /* first calculate normals */ + float no_a[3], no_b[3]; + + if (bm_face_subset_calc_normal(l_a, l_b, no_a) && + bm_face_subset_calc_normal(l_b, l_a, no_b)) + { + const float err_a = bm_face_subset_calc_planar(l_a, l_b, no_a); + const float err_b = bm_face_subset_calc_planar(l_b, l_a, no_b); + const float err_test = err_a + err_b; + + if (err_test < err_best) { + /* check we're legal (we could batch this) */ + BMLoop *l_split[2] = {l_a, l_b}; + BM_face_legal_splits(f, &l_split, 1); + if (l_split[0]) { + err_best = err_test; + v_pair[0] = l_a->v; + v_pair[1] = l_b->v; + + angle_best = angle_normalized_v3v3(no_a, no_b); + found = true; + } + } + } + } + } + } + + *r_angle = angle_best; + + return found; + + +} + +static bool bm_face_split_by_angle(BMesh *bm, BMFace *f, BMFace *r_f_pair[2], const float angle_limit) +{ + BMVert *v_pair[2]; + float angle; + + if (bm_face_split_find(f, v_pair, &angle) && (angle > angle_limit)) { + BMFace *f_new; + BMLoop *l_new; + f_new = BM_face_split(bm, f, v_pair[0], v_pair[1], &l_new, NULL, false); + if (f_new) { + r_f_pair[0] = f; + r_f_pair[1] = f_new; + + BMO_elem_flag_enable(bm, f, FACE_OUT); + BMO_elem_flag_enable(bm, f_new, FACE_OUT); + BMO_elem_flag_enable(bm, l_new->e, EDGE_OUT); + return true; + } + } + + return false; + +} + +void bmo_connect_verts_nonplanar_exec(BMesh *bm, BMOperator *op) +{ + BMOIter siter; + BMFace *f; + int totface = 0, totloop = 0; + int tottris; + BMFace **fstack; + STACK_DECLARE(fstack); + + const float angle_limit = BMO_slot_float_get(op->slots_in, "angle_limit"); + + + BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) { + if (f->len > 3) { + totface += 1; + totloop += f->len; + } + } + + if (totface == 0) { + return; + } + + /* over alloc, if we split every face */ + tottris = poly_to_tri_count(totface, totloop); + fstack = MEM_mallocN(sizeof(BMFace *) * tottris, __func__); + + STACK_INIT(fstack); + + BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) { + if (f->len > 3) { + STACK_PUSH(fstack, f); + } + } + + while ((f = STACK_POP(fstack))) { + BMFace *f_pair[2]; + if (bm_face_split_by_angle(bm, f, f_pair, angle_limit)) { + int j; + for (j = 0; j < 2; j++) { + BM_face_normal_update(f_pair[j]); + if (f_pair[j]->len > 3) { + STACK_PUSH(fstack, f_pair[j]); + } + } + } + } + + MEM_freeN(fstack); + + BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, EDGE_OUT); + BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_OUT); +} diff --git a/source/blender/bmesh/operators/bmo_connect_pair.c b/source/blender/bmesh/operators/bmo_connect_pair.c index 872f1cea2c7..0bc29c56256 100644 --- a/source/blender/bmesh/operators/bmo_connect_pair.c +++ b/source/blender/bmesh/operators/bmo_connect_pair.c @@ -84,17 +84,11 @@ typedef struct PathLinkState { float co_prev[3]; } PathLinkState; -/* only the x axis */ -static float mul_v1_m3v3(float M[3][3], const float a[3]) -{ - return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2]; -} - static int state_isect_co_pair(const PathContext *pc, const float co_a[3], const float co_b[3]) { - const float diff_a = mul_v1_m3v3((float (*)[3])pc->matrix, co_a) - pc->axis_sep; - const float diff_b = mul_v1_m3v3((float (*)[3])pc->matrix, co_b) - pc->axis_sep; + const float diff_a = dot_m3_v3_row_x((float (*)[3])pc->matrix, co_a) - pc->axis_sep; + const float diff_b = dot_m3_v3_row_x((float (*)[3])pc->matrix, co_b) - pc->axis_sep; const int test_a = (fabsf(diff_a) < CONNECT_EPS) ? 0 : (diff_a < 0.0f) ? -1 : 1; const int test_b = (fabsf(diff_b) < CONNECT_EPS) ? 0 : (diff_b < 0.0f) ? -1 : 1; @@ -110,7 +104,7 @@ static int state_isect_co_pair(const PathContext *pc, static int state_isect_co_exact(const PathContext *pc, const float co[3]) { - const float diff = mul_v1_m3v3((float (*)[3])pc->matrix, co) - pc->axis_sep; + const float diff = dot_m3_v3_row_x((float (*)[3])pc->matrix, co) - pc->axis_sep; return (fabsf(diff) <= CONNECT_EPS); } @@ -119,8 +113,8 @@ static float state_calc_co_pair_fac(const PathContext *pc, { float diff_a, diff_b, diff_tot; - diff_a = fabsf(mul_v1_m3v3((float (*)[3])pc->matrix, co_a) - pc->axis_sep); - diff_b = fabsf(mul_v1_m3v3((float (*)[3])pc->matrix, co_b) - pc->axis_sep); + diff_a = fabsf(dot_m3_v3_row_x((float (*)[3])pc->matrix, co_a) - pc->axis_sep); + diff_b = fabsf(dot_m3_v3_row_x((float (*)[3])pc->matrix, co_b) - pc->axis_sep); diff_tot = (diff_a + diff_b); return (diff_tot > FLT_EPSILON) ? (diff_a / diff_tot) : 0.5f; } @@ -443,7 +437,7 @@ void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op) normalize_v3_v3(pc.matrix[2], basis_nor); invert_m3(pc.matrix); - pc.axis_sep = mul_v1_m3v3(pc.matrix, pc.v_a->co); + pc.axis_sep = dot_m3_v3_row_x(pc.matrix, pc.v_a->co); } /* add first vertex */ diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c index e43c04f7d08..64d0ec6ac27 100644 --- a/source/blender/bmesh/operators/bmo_create.c +++ b/source/blender/bmesh/operators/bmo_create.c @@ -278,7 +278,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) * this connectivity could be used rather then treating * them as a bunch of isolated verts. */ - BMVert **vert_arr = MEM_mallocN(sizeof(BMVert **) * totv, __func__); + BMVert **vert_arr = MEM_mallocN(sizeof(BMVert *) * totv, __func__); BMFace *f; BMO_iter_as_array(op->slots_in, "geom", BM_VERT, (void **)vert_arr, totv); diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c index e4f2423ca17..d633182de42 100644 --- a/source/blender/bmesh/operators/bmo_dissolve.c +++ b/source/blender/bmesh/operators/bmo_dissolve.c @@ -103,10 +103,10 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op) { BMOIter oiter; BMFace *f; - BLI_array_declare(faces); - BLI_array_declare(regions); BMFace ***regions = NULL; BMFace **faces = NULL; + BLI_array_declare(regions); + BLI_array_declare(faces); BMFace *act_face = bm->act_face; BMWalker regwalker; int i; @@ -430,5 +430,8 @@ void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op) BM_mesh_decimate_dissolve_ex(bm, angle_limit, do_dissolve_boundaries, delimit, (BMVert **)BMO_SLOT_AS_BUFFER(vinput), vinput->len, - (BMEdge **)BMO_SLOT_AS_BUFFER(einput), einput->len); + (BMEdge **)BMO_SLOT_AS_BUFFER(einput), einput->len, + FACE_NEW); + + BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "region.out", BM_FACE, FACE_NEW); } diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c index d65e2669a58..1dc7b0a414d 100644 --- a/source/blender/bmesh/operators/bmo_dupe.c +++ b/source/blender/bmesh/operators/bmo_dupe.c @@ -28,8 +28,8 @@ #include "MEM_guardedalloc.h" -#include "BLI_array.h" #include "BLI_math.h" +#include "BLI_alloca.h" #include "bmesh.h" @@ -150,10 +150,7 @@ static BMFace *copy_face(BMOperator *op, #endif /* lookup edge */ - for (i = 0, source_loop = BM_iter_new(&iter, source_mesh, BM_LOOPS_OF_FACE, source_face); - source_loop; - source_loop = BM_iter_step(&iter), i++) - { + BM_ITER_ELEM_INDEX (source_loop, &iter, source_face, BM_LOOPS_OF_FACE, i) { vtar[i] = BLI_ghash_lookup(vhash, source_loop->v); edar[i] = BLI_ghash_lookup(ehash, source_loop->e); } @@ -388,33 +385,30 @@ void bmo_split_exec(BMesh *bm, BMOperator *op) BMEdge *e; BMFace *f; BMIter iter, iter2; - int found; /* make sure to remove edges and verts we don't need */ - for (e = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL); e; e = BM_iter_step(&iter)) { - found = 0; - f = BM_iter_new(&iter2, bm, BM_FACES_OF_EDGE, e); - for ( ; f; f = BM_iter_step(&iter2)) { + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + bool found = false; + BM_ITER_ELEM (f, &iter2, e, BM_FACES_OF_EDGE) { if (!BMO_elem_flag_test(bm, f, SPLIT_INPUT)) { - found = 1; + found = true; break; } } - if (!found) { + if (found == false) { BMO_elem_flag_enable(bm, e, SPLIT_INPUT); } } - for (v = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); v; v = BM_iter_step(&iter)) { - found = 0; - e = BM_iter_new(&iter2, bm, BM_EDGES_OF_VERT, v); - for ( ; e; e = BM_iter_step(&iter2)) { + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + bool found = false; + BM_ITER_ELEM (e, &iter2, v, BM_EDGES_OF_VERT) { if (!BMO_elem_flag_test(bm, e, SPLIT_INPUT)) { - found = 1; + found = true; break; } } - if (!found) { + if (found == false) { BMO_elem_flag_enable(bm, v, SPLIT_INPUT); } } @@ -492,8 +486,8 @@ 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 matrix=%m3 verts=%S", - cent, rmat, &dupop, "geom.out"); + "rotate cent=%v matrix=%m3 space=%s verts=%S", + cent, rmat, op, "space", &dupop, "geom.out"); BMO_slot_copy(&dupop, slots_out, "geom.out", op, slots_out, "geom_last.out"); BMO_op_finish(bm, &dupop); @@ -503,8 +497,8 @@ 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 matrix=%m3 verts=%S", - cent, rmat, &extop, "geom.out"); + "rotate cent=%v matrix=%m3 space=%s verts=%S", + cent, rmat, op, "space", &extop, "geom.out"); BMO_slot_copy(&extop, slots_out, "geom.out", op, slots_out, "geom_last.out"); BMO_op_finish(bm, &extop); @@ -513,8 +507,8 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op) if (usedvec) { mul_m3_v3(rmat, dvec); BMO_op_callf(bm, op->flag, - "translate vec=%v verts=%S", - dvec, op, "geom_last.out"); + "translate vec=%v space=%s verts=%S", + dvec, op, "space", op, "geom_last.out"); } } } diff --git a/source/blender/bmesh/operators/bmo_edgenet.c b/source/blender/bmesh/operators/bmo_edgenet.c index 903cef05604..923b877b822 100644 --- a/source/blender/bmesh/operators/bmo_edgenet.c +++ b/source/blender/bmesh/operators/bmo_edgenet.c @@ -31,6 +31,7 @@ #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_array.h" +#include "BLI_alloca.h" #include "BLI_smallhash.h" #include "BLI_rand.h" #include "BLI_heap.h" @@ -302,8 +303,7 @@ static void rotsys_make_consistent(BMesh *bm, EdgeData *edata, VertData *vdata) BMVert *startv = NULL; float dis; - v = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); - for (i = 0; i < bm->totvert; i++, BM_iter_step(&iter)) { + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { vd = vdata + BM_elem_index_get(v); if (vd->tag) @@ -827,10 +827,8 @@ static EPath *edge_find_shortest_path(BMesh *bm, BMOperator *op, BMEdge *edge, E } if (!v2) { - if (path) { - edge_free_path(pathbase, path); - path = NULL; - } + edge_free_path(pathbase, path); + path = NULL; continue; } @@ -888,27 +886,82 @@ BLI_INLINE void vote_on_winding(BMEdge *edge, EPathNode *node, unsigned int wind winding[(test_v1 == node->v)]++; } +static BMFace *bm_face_from_path(BMesh *bm, EPath *path, + EdgeData *edata, + const bool use_fill_check) +{ + /* accumulte winding directions for each edge which has a face */ + const unsigned int path_len = BLI_countlist(&path->nodes); + unsigned int winding[2] = {0, 0}; + unsigned int i; + + EPathNode *node; + + BMVert **verts = BLI_array_alloca(verts, path_len); + BMEdge **edges = BLI_array_alloca(edges, path_len); + BMEdge *e; + BMVert *v; + + for (node = path->nodes.first, i = 0; node; node = node->next, i++) { + + v = node->v; + e = BM_edge_exists(v, node->next ? + node->next->v : + ((EPathNode *)path->nodes.first)->v); + + /* check on the winding */ + if (e->l) { + if (UNLIKELY(count_edge_faces(bm, e) >= 2)) { + return NULL; + } + + vote_on_winding(e, node, winding); + } + + verts[i] = v; + edges[i] = e; + } + + /* do after incase we bail early, above */ + for (i = 0; i < path_len; i++) { + edata[BM_elem_index_get(edges[i])].ftag++; + } + + + /* if these are even it doesn't really matter what to do, + * with consistent geometry one will be zero, the choice is clear */ + if (winding[0] > winding[1]) { + BLI_array_wrap(verts, path_len, -1); + BLI_array_reverse(verts, path_len); + BLI_array_reverse(edges, path_len); + } + + if ((use_fill_check == false) || + /* fairly expensive check - see if there are already faces filling this area */ + (BM_face_exists_multi(verts, edges, path_len) == false)) + { + return BM_face_create(bm, verts, edges, path_len, BM_CREATE_NO_DOUBLE); + } + else { + return NULL; + } +} + void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op) { BMIter iter; BMOIter siter; BMFace *f; BMEdge *e; - BMVert **verts = NULL; - BLI_array_declare(verts); EPath *path; - EPathNode *node; EdgeData *edata; VertData *vdata; - BMEdge **edges = NULL; PathBase *pathbase; - BLI_array_declare(edges); const bool use_restrict = BMO_slot_bool_get(op->slots_in, "use_restrict"); const bool use_fill_check = BMO_slot_bool_get(op->slots_in, "use_fill_check"); const short mat_nr = BMO_slot_int_get(op->slots_in, "mat_nr"); const bool use_smooth = BMO_slot_bool_get(op->slots_in, "use_smooth"); - int i, j; - unsigned int winding[2]; /* accumulte winding directions for each edge which has a face */ + int i; BMOpSlot *slot_restrict = BMO_slot_get(op->slots_in, "restrict"); BMOpSlot *slot_face_groupmap_out = BMO_slot_get(op->slots_out, "face_groupmap.out"); @@ -981,99 +1034,28 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op) edata[BM_elem_index_get(edge)].tag += 1; path = edge_find_shortest_path(bm, op, edge, edata, vdata, pathbase, group); - if (!path) - continue; - - winding[0] = winding[1] = 0; - - BLI_array_empty(edges); - BLI_array_empty(verts); - i = 0; - for (node = path->nodes.first; node; node = node->next) { - if (!node->next) - continue; - - e = BM_edge_exists(node->v, node->next->v); - - /* this should never happe */ - if (!e) - break; - - /* check on the winding */ - if (e->l) { - vote_on_winding(e, node, winding); - } - - edata[BM_elem_index_get(e)].ftag++; - BLI_array_grow_one(edges); - edges[i++] = e; - - BLI_array_append(verts, node->v); - } - - if (edge->l) { - vote_on_winding(edge, path->nodes.last, winding); - } - - BLI_array_grow_one(edges); - edges[i++] = edge; - edata[BM_elem_index_get(edge)].ftag++; - - for (j = 0; j < i; j++) { - if (count_edge_faces(bm, edges[j]) >= 2) { - edge_free_path(pathbase, path); - break; + if (path && path->nodes.first) { + BMFace *f = bm_face_from_path(bm, path, edata, + use_fill_check); + + if (f && !BMO_elem_flag_test(bm, f, ELE_ORIG)) { + BMO_elem_flag_enable(bm, f, FACE_NEW); + f->mat_nr = mat_nr; + if (use_smooth) { + BM_elem_flag_enable(f, BM_ELEM_SMOOTH); + } } - } - if (j != i) { - continue; - } - - if (i) { - BMVert *v1, *v2; - - /* to define the winding order must select first edge, - * otherwise we could leave this as-is */ - edge = edges[0]; - - /* if these are even it doesn't really matter what to do, - * with consistent geometry one will be zero, the choice is clear */ - if (winding[0] < winding[1]) { - v1 = verts[0]; - v2 = verts[1]; - } - else { - v1 = verts[1]; - v2 = verts[0]; + if (use_restrict) { + BMO_slot_map_int_insert(op, slot_face_groupmap_out, f, path->group); } - if ((use_fill_check == false) || - /* 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, 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; - if (use_smooth) { - BM_elem_flag_enable(f, BM_ELEM_SMOOTH); - } - } - - if (use_restrict) { - BMO_slot_map_int_insert(op, slot_face_groupmap_out, f, path->group); - } - } + edge_free_path(pathbase, path); } - - edge_free_path(pathbase, path); } BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_NEW); - BLI_array_free(edges); - BLI_array_free(verts); edge_pathbase_free(pathbase); MEM_freeN(edata); MEM_freeN(vdata); diff --git a/source/blender/bmesh/operators/bmo_fill_holes.c b/source/blender/bmesh/operators/bmo_fill_holes.c new file mode 100644 index 00000000000..40a682e790d --- /dev/null +++ b/source/blender/bmesh/operators/bmo_fill_holes.c @@ -0,0 +1,137 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Campbell Barton. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/bmesh/operators/bmo_fill_holes.c + * \ingroup bmesh + * + * Fill boundary edge loop(s) with faces. + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_alloca.h" +#include "BLI_math.h" + +#include "bmesh.h" + +#include "intern/bmesh_operators_private.h" /* own include */ + +#define EDGE_MARK 2 +#define ELE_OUT 4 + +/** + * Clone of BM_face_find_longest_loop that ensures the loop has an adjacent face + */ +static BMLoop *bm_face_find_longest_loop_manifold(BMFace *f) +{ + BMLoop *longest_loop = NULL; + float longest_len = 0.0f; + BMLoop *l_iter, *l_first; + + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + + do { + if (BM_edge_is_wire(l_iter->e) == false) { + const float len = len_squared_v3v3(l_iter->v->co, l_iter->next->v->co); + if (len >= longest_len) { + longest_loop = l_iter; + longest_len = len; + } + } + } while ((l_iter = l_iter->next) != l_first); + + return longest_loop; +} + +static BMFace *bm_face_from_eloop(BMesh *bm, struct BMEdgeLoopStore *el_store) +{ + LinkData *node = BM_edgeloop_verts_get(el_store)->first; + const int len = BM_edgeloop_length_get(el_store); + BMVert **f_verts = BLI_array_alloca(f_verts, len); + BMFace *f; + BMLoop *l; + unsigned int i = 0; + + do { + f_verts[i++] = node->data; + } while ((node = node->next)); + + f = BM_face_create_ngon_verts(bm, f_verts, len, 0, true, false); + BM_face_copy_shared(bm, f); + + l = bm_face_find_longest_loop_manifold(f); + if (l) { + BMFace *f_other = l->radial_next->f; + BLI_assert(l->radial_next != l); + BM_elem_attrs_copy(bm, bm, f_other, f); + } + + return f; +} + +static bool bm_edge_test_cb(BMEdge *e, void *bm_v) +{ + return BMO_elem_flag_test((BMesh *)bm_v, e, EDGE_MARK); +} + +void bmo_holes_fill_exec(BMesh *bm, BMOperator *op) +{ + ListBase eloops = {NULL, NULL}; + LinkData *el_store; + + BMEdge *e; + int count; + + BMOIter siter; + + const int sides = BMO_slot_int_get(op->slots_in, "sides"); + + /* clear tags */ + + BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false); + + /* tag edges that may be apart of loops */ + BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { + BMO_elem_flag_set(bm, e, EDGE_MARK, BM_edge_is_boundary(e)); + } + + count = BM_mesh_edgeloops_find(bm, &eloops, bm_edge_test_cb, (void *)bm); + + for (el_store = eloops.first; el_store; el_store = el_store->next) { + if (BM_edgeloop_is_closed((struct BMEdgeLoopStore *)el_store)) { + const int len = BM_edgeloop_length_get((struct BMEdgeLoopStore *)el_store); + if ((sides == 0) || (len <= sides)) { + BMFace *f; + + f = bm_face_from_eloop(bm, (struct BMEdgeLoopStore *)el_store); + BMO_elem_flag_enable(bm, f, ELE_OUT); + } + } + } + + (void)count; + + BM_mesh_edgeloops_free(&eloops); + + BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, ELE_OUT); +} diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c index 97444a50438..a7b98cda2b3 100644 --- a/source/blender/bmesh/operators/bmo_inset.c +++ b/source/blender/bmesh/operators/bmo_inset.c @@ -277,6 +277,8 @@ static void bm_interp_face_store(InterpFace *iface, BMesh *bm, BMFace *f, MemAre void *axis_mat = iface->axis_mat; int i; + BLI_assert(BM_face_is_normal_valid(f)); + axis_dominant_v3_to_m3(axis_mat, f->no); iface->f = f; @@ -455,7 +457,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op) /* run the separate arg */ - bmesh_edge_separate(bm, es->e_old, es->l); + bmesh_edge_separate(bm, es->e_old, es->l, false); /* calc edge-split info */ es->e_new = es->l->e; @@ -533,7 +535,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op) /* disable touching twice, this _will_ happen if the flags not disabled */ BM_elem_flag_disable(v, BM_ELEM_TAG); - bmesh_vert_separate(bm, v, &vout, &r_vout_len); + bmesh_vert_separate(bm, v, &vout, &r_vout_len, false); v = NULL; /* don't use again */ /* in some cases the edge doesn't split off */ diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c index 39f7b0953b1..12065743136 100644 --- a/source/blender/bmesh/operators/bmo_join_triangles.c +++ b/source/blender/bmesh/operators/bmo_join_triangles.c @@ -34,7 +34,6 @@ #include "DNA_meshdata_types.h" #include "BLI_math.h" -#include "BLI_array.h" #include "BKE_customdata.h" @@ -42,6 +41,8 @@ #include "intern/bmesh_operators_private.h" /* own include */ +#define FACE_OUT (1 << 0) + /* assumes edges are validated before reaching this poin */ static float measure_facepair(const float v1[3], const float v2[3], const float v3[3], const float v4[3], float limit) @@ -195,10 +196,9 @@ static int fplcmp(const void *v1, const void *v2) { const JoinEdge *e1 = (JoinEdge *)v1, *e2 = (JoinEdge *)v2; - if (e1->weight > e2->weight) return 1; + if (e1->weight > e2->weight) return 1; else if (e1->weight < e2->weight) return -1; - - return 0; + else return 0; } void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) @@ -210,148 +210,141 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) const bool do_mat = BMO_slot_bool_get(op->slots_in, "cmp_materials"); const float limit = BMO_slot_float_get(op->slots_in, "limit"); - BMIter iter, liter; + BMIter iter; BMOIter siter; BMFace *f; - BMLoop *l; BMEdge *e; - BLI_array_declare(jedges); JoinEdge *jedges = NULL; - int i, totedge; + unsigned i, totedge; + unsigned int totedge_tag = 0; /* flag all edges of all input face */ BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) { - BMO_elem_flag_enable(bm, f, FACE_INPUT); - BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - BMO_elem_flag_enable(bm, l->e, EDGE_MARK); + if (f->len == 3) { + BMO_elem_flag_enable(bm, f, FACE_INPUT); } } - /* unflag edges that are invalid; e.g. aren't surrounded by triangle */ + /* flag edges surrounded by 2 flagged triangles */ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - BMFace *f1, *f2; - if (!BMO_elem_flag_test(bm, e, EDGE_MARK)) - continue; - - if (!BM_edge_face_pair(e, &f1, &f2)) { - BMO_elem_flag_disable(bm, e, EDGE_MARK); - continue; - } - - if (f1->len != 3 || f2->len != 3) { - BMO_elem_flag_disable(bm, e, EDGE_MARK); - continue; + BMFace *f_a, *f_b; + if (BM_edge_face_pair(e, &f_a, &f_b) && + (BMO_elem_flag_test(bm, f_a, FACE_INPUT) && BMO_elem_flag_test(bm, f_b, FACE_INPUT))) + { + BMO_elem_flag_enable(bm, e, EDGE_MARK); + totedge_tag++; } + } - if (!BMO_elem_flag_test(bm, f1, FACE_INPUT) || !BMO_elem_flag_test(bm, f2, FACE_INPUT)) { - BMO_elem_flag_disable(bm, e, EDGE_MARK); - continue; - } + if (totedge_tag == 0) { + return; } - + + /* over alloc, some of the edges will be delimited */ + jedges = MEM_mallocN(sizeof(*jedges) * totedge_tag, __func__); + i = 0; BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { BMVert *v1, *v2, *v3, *v4; - BMFace *f1, *f2; + BMFace *f_a, *f_b; float measure; if (!BMO_elem_flag_test(bm, e, EDGE_MARK)) continue; - f1 = e->l->f; - f2 = e->l->radial_next->f; - - v1 = e->l->v; - v2 = e->l->prev->v; - v3 = e->l->next->v; - v4 = e->l->radial_next->prev->v; + f_a = e->l->f; + f_b = e->l->radial_next->f; if (do_sharp && !BM_elem_flag_test(e, BM_ELEM_SMOOTH)) continue; - if (do_mat && f1->mat_nr != f2->mat_nr) + if (do_mat && f_a->mat_nr != f_b->mat_nr) continue; if ((do_uv || do_tf || do_vcol) && (bm_edge_faces_cmp(bm, e, do_uv, do_tf, do_vcol) == false)) continue; + v1 = e->l->v; + v2 = e->l->prev->v; + v3 = e->l->next->v; + v4 = e->l->radial_next->prev->v; + measure = measure_facepair(v1->co, v2->co, v3->co, v4->co, limit); if (measure < limit) { - BLI_array_grow_one(jedges); - jedges[i].e = e; jedges[i].weight = measure; - i++; } } - if (!jedges) - return; - - qsort(jedges, BLI_array_count(jedges), sizeof(JoinEdge), fplcmp); + totedge = i; + qsort(jedges, totedge, sizeof(JoinEdge), fplcmp); - totedge = BLI_array_count(jedges); for (i = 0; i < totedge; i++) { - BMFace *f1, *f2; + BMFace *f_a, *f_b; e = jedges[i].e; - f1 = e->l->f; - f2 = e->l->radial_next->f; - - if (BMO_elem_flag_test(bm, f1, FACE_MARK) || BMO_elem_flag_test(bm, f2, FACE_MARK)) - continue; + f_a = e->l->f; + f_b = e->l->radial_next->f; - BMO_elem_flag_enable(bm, f1, FACE_MARK); - BMO_elem_flag_enable(bm, f2, FACE_MARK); - BMO_elem_flag_enable(bm, e, EDGE_CHOSEN); + /* check if another edge already claimed this face */ + if ((BMO_elem_flag_test(bm, f_a, FACE_MARK) == false) || + (BMO_elem_flag_test(bm, f_b, FACE_MARK) == false)) + { + BMO_elem_flag_enable(bm, f_a, FACE_MARK); + BMO_elem_flag_enable(bm, f_b, FACE_MARK); + BMO_elem_flag_enable(bm, e, EDGE_CHOSEN); + } } + MEM_freeN(jedges); + + /* join best weighted */ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - BMFace *f1, *f2; + BMFace *f_new; + BMFace *f_a, *f_b; if (!BMO_elem_flag_test(bm, e, EDGE_CHOSEN)) continue; - - BM_edge_face_pair(e, &f1, &f2); /* checked above */ - BM_faces_join_pair(bm, f1, f2, e, true); + BM_edge_face_pair(e, &f_a, &f_b); /* checked above */ + if ((f_a->len == 3 && f_b->len == 3)) { + f_new = BM_faces_join_pair(bm, f_a, f_b, e, true); + if (f_new) { + BMO_elem_flag_enable(bm, f_new, FACE_OUT); + } + } } + /* join 2-tri islands */ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { if (BMO_elem_flag_test(bm, e, EDGE_MARK)) { - BMFace *f1, *f2; + BMLoop *l_a, *l_b; + BMFace *f_a, *f_b; /* ok, this edge wasn't merged, check if it's - * in a 2-tri-pair island, and if so merg */ + * in a 2-tri-pair island, and if so merge */ + l_a = e->l; + l_b = e->l->radial_next; - f1 = e->l->f; - f2 = e->l->radial_next->f; + f_a = l_a->f; + f_b = l_b->f; - if (f1->len != 3 || f2->len != 3) - continue; - - for (i = 0; i < 2; i++) { - BM_ITER_ELEM (l, &liter, i ? f2 : f1, BM_LOOPS_OF_FACE) { - if (l->e != e && BMO_elem_flag_test(bm, l->e, EDGE_MARK)) { - break; - } - } - - /* if l isn't NULL, we broke out of the loop */ - if (l) { - break; + /* check the other 2 edges in both tris are untagged */ + if ((f_a->len == 3 && f_b->len == 3) && + (BMO_elem_flag_test(bm, l_a->next->e, EDGE_MARK) == false) && + (BMO_elem_flag_test(bm, l_a->prev->e, EDGE_MARK) == false) && + (BMO_elem_flag_test(bm, l_b->next->e, EDGE_MARK) == false) && + (BMO_elem_flag_test(bm, l_b->prev->e, EDGE_MARK) == false)) + { + BMFace *f_new; + f_new = BM_faces_join_pair(bm, f_a, f_b, e, true); + if (f_new) { + BMO_elem_flag_enable(bm, f_new, FACE_OUT); } } - - /* if i isn't 2, we broke out of that loop */ - if (i != 2) { - continue; - } - - BM_faces_join_pair(bm, f1, f2, e, true); } } - BLI_array_free(jedges); + BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_OUT); } diff --git a/source/blender/bmesh/operators/bmo_normals.c b/source/blender/bmesh/operators/bmo_normals.c index 9d86e7ab275..025b8557331 100644 --- a/source/blender/bmesh/operators/bmo_normals.c +++ b/source/blender/bmesh/operators/bmo_normals.c @@ -146,14 +146,15 @@ static void bmo_recalc_face_normals_array(BMesh *bm, BMFace **faces, const int f void bmo_recalc_face_normals_exec(BMesh *bm, BMOperator *op) { - int *groups_array = MEM_mallocN(sizeof(groups_array) * bm->totface, __func__); + int *groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totface, __func__); int faces_len; BMFace **faces_arr = BM_iter_as_arrayN(bm, BM_FACES_OF_MESH, NULL, &faces_len, NULL, 0); - BMFace **faces_grp = MEM_mallocN(sizeof(faces_grp) * bm->totface, __func__); + BMFace **faces_grp = MEM_mallocN(sizeof(*faces_grp) * bm->totface, __func__); int (*group_index)[2]; const int group_tot = BM_mesh_calc_face_groups(bm, groups_array, &group_index, - bmo_recalc_normal_edge_filter_cb, NULL, BM_EDGE); + bmo_recalc_normal_edge_filter_cb, NULL, + 0, BM_EDGE); int i; diff --git a/source/blender/bmesh/operators/bmo_smooth_laplacian.c b/source/blender/bmesh/operators/bmo_smooth_laplacian.c index 91a52cdabef..3f04e23aa73 100644 --- a/source/blender/bmesh/operators/bmo_smooth_laplacian.c +++ b/source/blender/bmesh/operators/bmo_smooth_laplacian.c @@ -220,7 +220,7 @@ static void init_laplacian_matrix(LaplacianSystem *sys) v1 = vf[0]->co; v2 = vf[1]->co; v3 = vf[2]->co; - v4 = has_4_vert ? vf[3]->co : 0; + v4 = has_4_vert ? vf[3]->co : NULL; if (has_4_vert) { areaf = area_quad_v3(v1, v2, v3, v4); diff --git a/source/blender/bmesh/operators/bmo_split_edges.c b/source/blender/bmesh/operators/bmo_split_edges.c index c0847930422..7eea4c4878d 100644 --- a/source/blender/bmesh/operators/bmo_split_edges.c +++ b/source/blender/bmesh/operators/bmo_split_edges.c @@ -29,7 +29,6 @@ #include "BLI_utildefines.h" #include "bmesh.h" -#include "tools/bmesh_edgesplit.h" #include "intern/bmesh_operators_private.h" /* own include */ @@ -48,7 +47,7 @@ void bmo_split_edges_exec(BMesh *bm, BMOperator *op) } /* this is where everything happens */ - BM_mesh_edgesplit(bm, use_verts, true); + BM_mesh_edgesplit(bm, use_verts, true, false); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_INTERNAL_TAG); } diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index 6b55d5ea877..e669585a857 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -593,7 +593,7 @@ static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts } for (i = 1; i < numcuts + 2; i++) { - for (j = 1; j < numcuts + 1; j++) { + for (j = 1; j <= numcuts; j++) { a = i * s + j; b = (i - 1) * s + j; e = connect_smallest_face(bm, lines[a], lines[b], &f_new); @@ -710,7 +710,7 @@ static void tri_3edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, * s s * </pre> */ - for (i = 1; i < numcuts + 1; i++) { + for (i = 1; i <= numcuts; i++) { for (j = 0; j < i; j++) { e = connect_smallest_face(bm, lines[i][j], lines[i + 1][j + 1], &f_new); @@ -1203,24 +1203,22 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag, BMO_op_exec(bm, &op); - if (seltype == SUBDIV_SELECT_INNER) { - BMOIter iter; - BMElem *ele; - - for (ele = BMO_iter_new(&iter, op.slots_out, "geom_inner.out", BM_EDGE | BM_VERT); ele; ele = BMO_iter_step(&iter)) { - BM_elem_select_set(bm, ele, true); - } - } - else if (seltype == SUBDIV_SELECT_LOOPCUT) { - BMOIter iter; - BMElem *ele; - - /* deselect input */ - BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false); - - for (ele = BMO_iter_new(&iter, op.slots_out, "geom_inner.out", BM_EDGE); ele; ele = BMO_iter_step(&iter)) { - BM_edge_select_set(bm, (BMEdge *)ele, true); - } + switch (seltype) { + case SUBDIV_SELECT_NONE: + break; + case SUBDIV_SELECT_ORIG: + /* set the newly created data to be selected */ + BMO_slot_buffer_hflag_enable(bm, op.slots_out, "geom_inner.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, true); + BM_mesh_select_flush(bm); + break; + case SUBDIV_SELECT_INNER: + BMO_slot_buffer_hflag_enable(bm, op.slots_out, "geom_inner.out", BM_EDGE | BM_VERT, BM_ELEM_SELECT, true); + break; + case SUBDIV_SELECT_LOOPCUT: + /* deselect input */ + BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false); + BMO_slot_buffer_hflag_enable(bm, op.slots_out, "geom_inner.out", BM_EDGE, BM_ELEM_SELECT, true); + break; } BMO_op_finish(bm, &op); diff --git a/source/blender/bmesh/operators/bmo_subdivide_edgering.c b/source/blender/bmesh/operators/bmo_subdivide_edgering.c index 44d4b63f5c4..fa39ae68cdf 100644 --- a/source/blender/bmesh/operators/bmo_subdivide_edgering.c +++ b/source/blender/bmesh/operators/bmo_subdivide_edgering.c @@ -40,14 +40,13 @@ #include "MEM_guardedalloc.h" #include "BLI_utildefines.h" -#include "BLI_array.h" +#include "BLI_alloca.h" #include "BLI_math.h" #include "BLI_listbase.h" #include "BKE_curve.h" #include "bmesh.h" -#include "tools/bmesh_edgesplit.h" #include "intern/bmesh_operators_private.h" /* own include */ @@ -1167,6 +1166,7 @@ void bmo_subdivide_edgering_exec(BMesh *bm, BMOperator *op) bm_edgering_pair_ringsubd(bm, lpair, el_store_a, el_store_b, interp_mode, cuts, smooth, falloff_cache); bm_edgering_pair_store_free(lpair, interp_mode); + change = true; } else { BMO_error_raise(bm, op, BMERR_INVALID_SELECTION, @@ -1217,6 +1217,7 @@ void bmo_subdivide_edgering_exec(BMesh *bm, BMOperator *op) bm_edgering_pair_ringsubd(bm, lpair, el_store_a, el_store_b, interp_mode, cuts, smooth, falloff_cache); bm_edgering_pair_store_free(lpair, interp_mode); + change = true; } BLI_assert(bm_verts_tag_count(bm) == 0); @@ -1229,6 +1230,6 @@ cleanup: /* flag output */ if (change) { - BMO_slot_buffer_flag_enable(bm, op->slots_out, "faces.out", BM_FACE, FACE_OUT); + BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_OUT); } } diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index 2a0a7864499..8b8cab9d881 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -32,8 +32,8 @@ #include "DNA_meshdata_types.h" #include "BLI_math.h" -#include "BLI_array.h" #include "BLI_heap.h" +#include "BLI_alloca.h" #include "BKE_customdata.h" @@ -55,9 +55,15 @@ void bmo_transform_exec(BMesh *UNUSED(bm), BMOperator *op) { BMOIter iter; BMVert *v; - float mat[4][4]; + float mat[4][4], mat_space[4][4], imat_space[4][4]; BMO_slot_mat4_get(op->slots_in, "matrix", mat); + BMO_slot_mat4_get(op->slots_in, "space", mat_space); + + if (!is_zero_m4(mat_space)) { + invert_m4_m4(imat_space, mat_space); + mul_serie_m4(mat, imat_space, mat, mat_space, NULL, NULL, NULL, NULL, NULL); + } BMO_ITER (v, &iter, op->slots_in, "verts", BM_VERT) { mul_m4_v3(mat, v->co); @@ -73,7 +79,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 matrix=%m4 verts=%s", mat, op, "verts"); + BMO_op_callf(bm, op->flag, "transform matrix=%m4 space=%s verts=%s", mat, op, "space", op, "verts"); } void bmo_scale_exec(BMesh *bm, BMOperator *op) @@ -87,25 +93,19 @@ 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 matrix=%m3 verts=%s", mat, op, "verts"); + BMO_op_callf(bm, op->flag, "transform matrix=%m3 space=%s verts=%s", mat, op, "space", op, "verts"); } void bmo_rotate_exec(BMesh *bm, BMOperator *op) { - float vec[3]; - - BMO_slot_vec_get(op->slots_in, "cent", vec); - - /* there has to be a proper matrix way to do this, but - * this is how editmesh did it and I'm too tired to think - * through the math right now. */ - mul_v3_fl(vec, -1.0f); - BMO_op_callf(bm, op->flag, "translate verts=%s vec=%v", op, "verts", vec); + float center[3]; + float mat[4][4]; - BMO_op_callf(bm, op->flag, "transform matrix=%s verts=%s", op, "matrix", op, "verts"); + BMO_slot_vec_get(op->slots_in, "cent", center); + BMO_slot_mat4_get(op->slots_in, "matrix", mat); + transform_pivot_set_m4(mat, center); - 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 matrix=%m4 space=%s verts=%s", mat, op, "space", op, "verts"); } void bmo_reverse_faces_exec(BMesh *bm, BMOperator *op) diff --git a/source/blender/bmesh/operators/bmo_wireframe.c b/source/blender/bmesh/operators/bmo_wireframe.c index fc2e1bbaf3e..c07e2c3bbf2 100644 --- a/source/blender/bmesh/operators/bmo_wireframe.c +++ b/source/blender/bmesh/operators/bmo_wireframe.c @@ -177,7 +177,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op) /* will over-alloc, but makes for easy lookups by index to keep aligned */ BMVert **verts_boundary = use_boundary ? - MEM_mallocN(sizeof(BMVert **) * totvert_orig, __func__) : NULL; + MEM_mallocN(sizeof(BMVert *) * totvert_orig, __func__) : NULL; float *verts_relfac = use_relative_offset ? MEM_mallocN(sizeof(float) * totvert_orig, __func__) : NULL; @@ -250,7 +250,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op) BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false); } - verts_loop = MEM_mallocN(sizeof(BMVert **) * verts_loop_tot, __func__); + verts_loop = MEM_mallocN(sizeof(BMVert *) * verts_loop_tot, __func__); verts_loop_tot = 0; /* count up again */ BMO_ITER (f_src, &oiter, op->slots_in, "faces", BM_FACE) { diff --git a/source/blender/bmesh/tools/BME_bevel.c b/source/blender/bmesh/tools/BME_bevel.c deleted file mode 100644 index ba553e2f763..00000000000 --- a/source/blender/bmesh/tools/BME_bevel.c +++ /dev/null @@ -1,1160 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2004 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Geoffrey Bantle and Levi Schooley. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include <math.h> - -#include "MEM_guardedalloc.h" - -#include "DNA_listBase.h" -#include "DNA_meshdata_types.h" -#include "DNA_mesh_types.h" - -#include "BLI_math.h" -#include "BLI_blenlib.h" -#include "BLI_ghash.h" -#include "BLI_memarena.h" - -#include "BKE_editmesh.h" -#include "BKE_bmesh.h" - -#include "bmesh.h" -#include "intern/bmesh_private.h" - -/* BMESH_TODO - * - * Date: 2011-11-24 06:25 - * Sender: Andrew Wiggin - * Status update: I have code changes to actually make basic bevel modifier work. The things that still need to be done: - * - clean up the changes - * - get bevel by weight and bevel by angles working for vertex only bevel. - * - the code uses adaptations of a couple of bmesh APIs, - * that work a little differently. for example, a join faces that doesn't just create a new face and then delete the - * original two faces and all associated loops, it extends one of the original faces to cover all the original loops - * (except for the loop on the join edge which is of course deleted). the bevel code currently requires this because it - * expects to be able to continue walking loop lists and doesn't like for loops to be deleted out from under it - * while working... - * but bmesh APIs don't do it this way because it makes it trickier to manage the interp during these operations, - * so I need to decide what to do in these cases. - */ - -/* BMESH_TODO - resolve this */ -#define BMESH_263_VERT_BEVEL_WORKAROUND - -/* ------- Bevel code starts here -------- */ - -static BME_TransData_Head *BME_init_transdata(int bufsize) -{ - BME_TransData_Head *td; - - td = MEM_callocN(sizeof(BME_TransData_Head), "BM transdata header"); - td->gh = BLI_ghash_ptr_new("BME_init_transdata gh"); - td->ma = BLI_memarena_new(bufsize, "BME_TransData arena"); - BLI_memarena_use_calloc(td->ma); - - return td; -} - -void BME_free_transdata(BME_TransData_Head *td) -{ - BLI_ghash_free(td->gh, NULL, NULL); - BLI_memarena_free(td->ma); - MEM_freeN(td); -} - -static BME_TransData *BME_assign_transdata(BME_TransData_Head *td, BMesh *bm, BMVert *v, - float *co, float *org, float *vec, float *loc, - float factor, float weight, float maxfactor, float *max) -{ - BME_TransData *vtd; - int is_new = false; - - if (v == NULL) { - return NULL; - } - - if ((vtd = BLI_ghash_lookup(td->gh, v)) == NULL && bm != NULL) { - vtd = BLI_memarena_alloc(td->ma, sizeof(*vtd)); - BLI_ghash_insert(td->gh, v, vtd); - td->len++; - is_new = true; - } - - vtd->bm = bm; - vtd->v = v; - - if (co != NULL) { - copy_v3_v3(vtd->co, co); - } - - if (org == NULL && is_new) { - copy_v3_v3(vtd->org, v->co); /* default */ - } - else if (org != NULL) { - copy_v3_v3(vtd->org, org); - } - - if (vec != NULL) { - copy_v3_v3(vtd->vec, vec); - normalize_v3(vtd->vec); - } - - vtd->loc = loc; - - vtd->factor = factor; - vtd->weight = weight; - vtd->maxfactor = maxfactor; - vtd->max = max; - - return vtd; -} - -BME_TransData *BME_get_transdata(BME_TransData_Head *td, BMVert *v) -{ - BME_TransData *vtd; - vtd = BLI_ghash_lookup(td->gh, v); - return vtd; -} - -/* a hack (?) to use the transdata memarena to allocate floats for use with the max limits */ -static float *BME_new_transdata_float(BME_TransData_Head *td) -{ - return BLI_memarena_alloc(td->ma, sizeof(float)); -} - -/* ported from before bmesh merge into trunk (was called) - * problem with this is it creates 2 vert faces */ -static void BME_Bevel_Dissolve_Disk(BMesh *bm, BMVert *v) -{ - BMFace *f; - BMEdge *e; - bool done; - - if (v->e) { - done = false; - while (!done) { - done = true; - e = v->e; /*loop the edge looking for a edge to dissolve*/ - do { - f = NULL; - if (BM_edge_is_manifold(e)) { - f = bmesh_jfke(bm, e->l->f, e->l->radial_next->f, e); - } - if (f) { - done = false; - break; - } - e = bmesh_disk_edge_next(e, v); - } while (e != v->e); - } - BM_vert_collapse_edge(bm, v->e, v, true); - // bmesh_jekv(bm, v->e, v, false); - } -} - -static int BME_bevel_is_split_vert(BMesh *bm, BMLoop *l) -{ - /* look for verts that have already been added to the edge when - * beveling other polys; this can be determined by testing the - * vert and the edges around it for originality - */ - if (!BMO_elem_flag_test(bm, l->v, BME_BEVEL_ORIG) && - BMO_elem_flag_test(bm, l->e, BME_BEVEL_ORIG) && - BMO_elem_flag_test(bm, l->prev->e, BME_BEVEL_ORIG)) - { - return 1; - } - return 0; -} - -/* get a vector, vec, that points from v1->co to wherever makes sense to - * the bevel operation as a whole based on the relationship between v1 and v2 - * (won't necessarily be a vec from v1->co to v2->co, though it probably will be); - * the return value is -1 for failure, 0 if we used vert co's, and 1 if we used transform origins */ -static int BME_bevel_get_vec(float vec[3], BMVert *v1, BMVert *v2, BME_TransData_Head *td) -{ - BME_TransData *vtd1, *vtd2; - - vtd1 = BME_get_transdata(td, v1); - vtd2 = BME_get_transdata(td, v2); - if (!vtd1 || !vtd2) { - //printf("BME_bevel_get_vec() got called without proper BME_TransData\n"); - return -1; - } - - /* compare the transform origins to see if we can use the vert co's; - * if they belong to different origins, then we will use the origins to determine - * the vector */ - if (compare_v3v3(vtd1->org, vtd2->org, 0.000001f)) { - sub_v3_v3v3(vec, v2->co, v1->co); - if (len_v3(vec) < 0.000001f) { - zero_v3(vec); - } - return 0; - } - else { - sub_v3_v3v3(vec, vtd2->org, vtd1->org); - if (len_v3(vec) < 0.000001f) { - zero_v3(vec); - } - return 1; - } -} - -/* "Projects" a vector perpendicular to vec2 against vec1, such that - * the projected vec1 + vec2 has a min distance of 1 from the "edge" defined by vec2. - * note: the direction, is_forward, is used in conjunction with up_vec to determine - * whether this is a convex or concave corner. If it is a concave corner, it will - * be projected "backwards." If vec1 is before vec2, is_forward should be 0 (we are projecting backwards). - * vec1 is the vector to project onto (expected to be normalized) - * vec2 is the direction of projection (pointing away from vec1) - * up_vec is used for orientation (expected to be normalized) - * returns the length of the projected vector that lies along vec1 */ -static float BME_bevel_project_vec(float *vec1, float *vec2, float *up_vec, - int is_forward, BME_TransData_Head *UNUSED(td)) -{ - float factor, vec3[3], tmp[3], c1, c2; - - cross_v3_v3v3(tmp, vec1, vec2); - normalize_v3(tmp); - factor = dot_v3v3(up_vec, tmp); - if ((factor > 0 && is_forward) || (factor < 0 && !is_forward)) { - cross_v3_v3v3(vec3, vec2, tmp); /* hmm, maybe up_vec should be used instead of tmp */ - } - else { - cross_v3_v3v3(vec3, tmp, vec2); /* hmm, maybe up_vec should be used instead of tmp */ - } - normalize_v3(vec3); - c1 = dot_v3v3(vec3, vec1); - c2 = dot_v3v3(vec1, vec1); - if (fabsf(c1) < 0.000001f || fabsf(c2) < 0.000001f) { - factor = 0.0f; - } - else { - factor = c2 / c1; - } - - return factor; -} - -/* BME_bevel_split_edge() is the main math work-house; its responsibilities are: - * using the vert and the loop passed, get or make the split vert, set its coordinates - * and transform properties, and set the max limits. - * Finally, return the split vert. */ -static BMVert *BME_bevel_split_edge(BMesh *bm, BMVert *v, BMVert *v1, BMLoop *l, - float *up_vec, float value, BME_TransData_Head *td) -{ - BME_TransData *vtd, *vtd1, *vtd2; - BMVert *sv, *v2, *v3, *ov; - BMLoop *lv1, *lv2; - BMEdge *ne, *e1, *e2; - float maxfactor, scale, len, dis, vec1[3], vec2[3], t_up_vec[3]; - int is_edge, forward, is_split_vert; - - /* ov, vtd2, and is_split_vert are set but UNUSED */ - (void)ov, (void)vtd2, (void)is_split_vert; - - if (l == NULL) { - /* what you call operator overloading in C :) - * I wanted to use the same function for both wire edges and poly loops - * so... here we walk around edges to find the needed verts */ - forward = 1; - is_split_vert = 0; - if (v->e == NULL) { - //printf("We can't split a loose vert's edge!\n"); - return NULL; - } - e1 = v->e; /* we just use the first two edges */ - e2 = bmesh_disk_edge_next(v->e, v); - if (e1 == e2) { - //printf("You need at least two edges to use BME_bevel_split_edge()\n"); - return NULL; - } - v2 = BM_edge_other_vert(e1, v); - v3 = BM_edge_other_vert(e2, v); - if (v1 != v2 && v1 != v3) { - //printf("Error: more than 2 edges in v's disk cycle, or v1 does not share an edge with v\n"); - return NULL; - } - if (v1 == v2) { - v2 = v3; - } - else { - e1 = e2; - } - ov = BM_edge_other_vert(e1, v); - sv = BM_edge_split(bm, e1, v, &ne, 0.0f); - //BME_data_interp_from_verts(bm, v, ov, sv, 0.25); /* this is technically wrong.. */ - //BME_data_interp_from_faceverts(bm, v, ov, sv, 0.25); - //BME_data_interp_from_faceverts(bm, ov, v, sv, 0.25); - BME_assign_transdata(td, bm, sv, sv->co, sv->co, NULL, sv->co, 0, -1, -1, NULL); /* quick default */ - BMO_elem_flag_enable(bm, sv, BME_BEVEL_BEVEL); - BMO_elem_flag_enable(bm, ne, BME_BEVEL_ORIG); /* mark edge as original, even though it isn't */ - BME_bevel_get_vec(vec1, v1, v, td); - BME_bevel_get_vec(vec2, v2, v, td); - cross_v3_v3v3(t_up_vec, vec1, vec2); - normalize_v3(t_up_vec); - up_vec = t_up_vec; - } - else { - /* establish loop direction */ - if (l->v == v) { - forward = 1; - lv1 = l->next; - lv2 = l->prev; - v1 = l->next->v; - v2 = l->prev->v; - } - else if (l->next->v == v) { - forward = 0; - lv1 = l; - lv2 = l->next->next; - v1 = l->v; - v2 = l->next->next->v; - } - else { - //printf("ERROR: BME_bevel_split_edge() - v must be adjacent to l\n"); - return NULL; - } - - if (BME_bevel_is_split_vert(bm, lv1)) { - is_split_vert = 1; - sv = v1; - v1 = forward ? l->next->next->v : l->prev->v; - } - else { - is_split_vert = 0; - ov = BM_edge_other_vert(l->e, v); - sv = BM_edge_split(bm, l->e, v, &ne, 0.0f); - //BME_data_interp_from_verts(bm, v, ov, sv, 0.25); /* this is technically wrong.. */ - //BME_data_interp_from_faceverts(bm, v, ov, sv, 0.25); - //BME_data_interp_from_faceverts(bm, ov, v, sv, 0.25); - BME_assign_transdata(td, bm, sv, sv->co, sv->co, NULL, sv->co, 0, -1, -1, NULL); /* quick default */ - BMO_elem_flag_enable(bm, sv, BME_BEVEL_BEVEL); - BMO_elem_flag_enable(bm, ne, BME_BEVEL_ORIG); /* mark edge as original, even though it isn't */ - } - - if (BME_bevel_is_split_vert(bm, lv2)) { - v2 = forward ? lv2->prev->v : lv2->next->v; - } - } - - is_edge = BME_bevel_get_vec(vec1, v, v1, td); /* get the vector we will be projecting onto */ - BME_bevel_get_vec(vec2, v, v2, td); /* get the vector we will be projecting parallel to */ - len = normalize_v3(vec1); - - vtd = BME_get_transdata(td, sv); - vtd1 = BME_get_transdata(td, v); - vtd2 = BME_get_transdata(td, v1); - - if (vtd1->loc == NULL) { - /* this is a vert with data only for calculating initial weights */ - if (vtd1->weight < 0.0f) { - vtd1->weight = 0.0f; - } - scale = vtd1->weight / vtd1->factor; - if (!vtd1->max) { - vtd1->max = BME_new_transdata_float(td); - *vtd1->max = -1; - } - } - else { - scale = vtd1->weight; - } - vtd->max = vtd1->max; - - if (is_edge && vtd1->loc != NULL) { - maxfactor = vtd1->maxfactor; - } - else { - maxfactor = scale * BME_bevel_project_vec(vec1, vec2, up_vec, forward, td); - if (vtd->maxfactor > 0 && vtd->maxfactor < maxfactor) { - maxfactor = vtd->maxfactor; - } - } - - dis = BMO_elem_flag_test(bm, v1, BME_BEVEL_ORIG) ? len / 3 : len / 2; - if (is_edge || dis > maxfactor * value) { - dis = maxfactor * value; - } - madd_v3_v3v3fl(sv->co, v->co, vec1, dis); - sub_v3_v3v3(vec1, sv->co, vtd1->org); - dis = normalize_v3(vec1); - BME_assign_transdata(td, bm, sv, vtd1->org, vtd1->org, vec1, sv->co, dis, scale, maxfactor, vtd->max); - - return sv; -} - -#if 0 /* UNUSED */ -static float BME_bevel_set_max(BMVert *v1, BMVert *v2, float value, BME_TransData_Head *td) -{ - BME_TransData *vtd1, *vtd2; - float max, fac1, fac2, vec1[3], vec2[3], vec3[3]; - - BME_bevel_get_vec(vec1, v1, v2, td); - vtd1 = BME_get_transdata(td, v1); - vtd2 = BME_get_transdata(td, v2); - - if (vtd1->loc == NULL) { - fac1 = 0; - } - else { - copy_v3_v3(vec2, vtd1->vec); - mul_v3_fl(vec2, vtd1->factor); - if (dot_v3v3(vec1, vec1)) { - project_v3_v3v3(vec2, vec2, vec1); - fac1 = len_v3(vec2) / value; - } - else { - fac1 = 0; - } - } - - if (vtd2->loc == NULL) { - fac2 = 0; - } - else { - copy_v3_v3(vec3, vtd2->vec); - mul_v3_fl(vec3, vtd2->factor); - if (dot_v3v3(vec1, vec1)) { - project_v3_v3v3(vec2, vec3, vec1); - fac2 = len_v3(vec2) / value; - } - else { - fac2 = 0; - } - } - - if (fac1 || fac2) { - max = len_v3(vec1) / (fac1 + fac2); - if (vtd1->max && (*vtd1->max < 0 || max < *vtd1->max)) { - *vtd1->max = max; - } - if (vtd2->max && (*vtd2->max < 0 || max < *vtd2->max)) { - *vtd2->max = max; - } - } - else { - max = -1; - } - - return max; -} -#endif - -#if 0 /* UNUSED */ -static BMVert *BME_bevel_wire(BMesh *bm, BMVert *v, float value, int res, int UNUSED(options), BME_TransData_Head *td) -{ - BMVert *ov1, *ov2, *v1, *v2; - - ov1 = BM_edge_other_vert(v->e, v); - ov2 = BM_edge_other_vert(bmesh_disk_edge_next(v->e, v), v); - - /* split the edges */ - v1 = BME_bevel_split_edge(bm, v, ov1, NULL, NULL, value, td); - BMO_elem_flag_enable(bm, v1, BME_BEVEL_NONMAN); - v2 = BME_bevel_split_edge(bm, v, ov2, NULL, NULL, value, td); - BMO_elem_flag_enable(bm, v2, BME_BEVEL_NONMAN); - - if (value > 0.5) { - BME_bevel_set_max(v1, ov1, value, td); - BME_bevel_set_max(v2, ov2, value, td); - } - - /* remove the original vert */ - if (res) { - /* bmesh_jekv; */ - - //void BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, int calcnorm) { - //hrm, why is there a fac here? it just removes a vert - BM_vert_collapse_edge(bm, v->e, v); - } - - return v1; -} -#endif - -static BMLoop *BME_bevel_edge(BMesh *bm, BMLoop *l, float value, int UNUSED(options), - float *up_vec, BME_TransData_Head *td) -{ - BMVert *v1, *v2, *kv; - BMLoop *kl = NULL, *nl; - BMEdge *e, *ke, *se; - BMFace *f, *jf; - - f = l->f; - e = l->e; - - /* sanity check */ - if (!BMO_elem_flag_test(bm, l->e, BME_BEVEL_BEVEL) && - (BMO_elem_flag_test(bm, l->v, BME_BEVEL_BEVEL) || BMO_elem_flag_test(bm, l->next->v, BME_BEVEL_BEVEL))) - { - return l; - } - - /* checks and operations for prev edge */ - /* first, check to see if this edge was inset previously */ - if (!BMO_elem_flag_test(bm, l->prev->e, BME_BEVEL_ORIG) && - !BMO_elem_flag_test(bm, l->v, BME_BEVEL_NONMAN)) - { - kl = l->prev->radial_next; - kl = (kl->v == l->v) ? kl->prev : kl->next; - kv = l->v; - } - else { - kv = NULL; - } - /* get/make the first vert to be used in SFME */ - if (BMO_elem_flag_test(bm, l->v, BME_BEVEL_NONMAN)) { - v1 = l->v; - } - else { /* we'll need to split the previous edge */ - v1 = BME_bevel_split_edge(bm, l->v, NULL, l->prev, up_vec, value, td); - } - /* if we need to clean up geometry... */ - if (kv) { - se = l->next->e; - jf = NULL; - if (kl->v == kv) { - BM_face_split(bm, kl->f, kl->prev->v, kl->next->v, &nl, kl->prev->e, true); - ke = kl->e; - /* BMESH-TODO: jfke doesn't handle customdata */ - jf = bmesh_jfke(bm, kl->prev->radial_next->f, kl->f, kl->prev->e); - BM_vert_collapse_edge(bm, ke, kv, false); - } - else { - BM_face_split(bm, kl->f, kl->next->next->v, kl->v, &nl, kl->next->e, true); - ke = kl->e; - /* BMESH-TODO: jfke doesn't handle customdata */ - jf = bmesh_jfke(bm, kl->next->radial_next->f, kl->f, kl->next->e); - BM_vert_collapse_edge(bm, ke, kv, false); - } - /* find saved loop pointer */ - l = se->l; - while (l->f != jf) { - l = l->radial_next; - BLI_assert(l != se->l); - } - l = l->prev; - } - - /* checks and operations for the next edge */ - /* first, check to see if this edge was inset previously */ - if (!BMO_elem_flag_test(bm, l->next->e, BME_BEVEL_ORIG) && - !BMO_elem_flag_test(bm, l->next->v, BME_BEVEL_NONMAN)) - { - kl = l->next->radial_next; - kl = (kl->v == l->next->v) ? kl->prev : kl->next; - kv = l->next->v; - } - else { - kv = NULL; - } - /* get/make the second vert to be used in SFME */ - if (BMO_elem_flag_test(bm, l->next->v, BME_BEVEL_NONMAN)) { - v2 = l->next->v; - } - else { /* we'll need to split the next edge */ - v2 = BME_bevel_split_edge(bm, l->next->v, NULL, l->next, up_vec, value, td); - } - /* if we need to clean up geometry... */ - if (kv) { - se = l->e; - jf = NULL; - if (kl->v == kv) { - BM_face_split(bm, kl->f, kl->prev->v, kl->next->v, &nl, kl->prev->e, true); - ke = kl->e; - /* BMESH-TODO: jfke doesn't handle customdata */ - jf = bmesh_jfke(bm, kl->prev->radial_next->f, kl->f, kl->prev->e); - BM_vert_collapse_edge(bm, ke, kv, false); - } - else { - BM_face_split(bm, kl->f, kl->next->next->v, kl->v, &nl, kl->next->e, true); - ke = kl->e; - /* BMESH-TODO: jfke doesn't handle customdata */ - jf = bmesh_jfke(bm, kl->next->radial_next->f, kl->f, kl->next->e); - BM_vert_collapse_edge(bm, ke, kv, false); - } - /* find saved loop pointer */ - l = se->l; - while (l->f != jf) { - l = l->radial_next; - BLI_assert(l != se->l); - } - } - - if (!BMO_elem_flag_test(bm, v1, BME_BEVEL_NONMAN) || !BMO_elem_flag_test(bm, v2, BME_BEVEL_NONMAN)) { - BM_face_split(bm, f, v2, v1, &l, e, true); - BMO_elem_flag_enable(bm, l->e, BME_BEVEL_BEVEL); - l = l->radial_next; - } - - if (l->f != f) { - //printf("Whoops! You got something out of order in BME_bevel_edge()!\n"); - } - - return l; -} - -static BMLoop *BME_bevel_vert(BMesh *bm, BMLoop *l, float value, int UNUSED(options), - float up_vec[3], BME_TransData_Head *td) -{ - BMVert *v1, *v2; - /* BMFace *f; */ /* UNUSED */ - - /* get/make the first vert to be used in SFME */ - /* may need to split the previous edge */ - v1 = BME_bevel_split_edge(bm, l->v, NULL, l->prev, up_vec, value, td); - - /* get/make the second vert to be used in SFME */ - /* may need to split this edge (so move l) */ - l = l->prev; - v2 = BME_bevel_split_edge(bm, l->next->v, NULL, l->next, up_vec, value, td); - l = l->next->next; - - /* "cut off" this corner */ - /* f = */ BM_face_split(bm, l->f, v2, v1, NULL, l->e, true); - - return l; -} - -/* - * BME_bevel_poly - * - * Polygon inset tool: - * - * Insets a polygon/face based on the flagss of its vertices - * and edges. Used by the bevel tool only, for now. - * The parameter "value" is the distance to inset (should be negative). - * The parameter "options" is not currently used. - * - * Returns - - * A BMFace pointer to the resulting inner face. - */ -static BMFace *BME_bevel_poly(BMesh *bm, BMFace *f, float value, int options, BME_TransData_Head *td) -{ - BMLoop *l /*, *o */; - BME_TransData *vtd1, *vtd2; - float up_vec[3], vec1[3], vec2[3], vec3[3], fac1, fac2, max = -1; - int len, i; - BMIter iter; - - zero_v3(up_vec); - - /* find a good normal for this face (there's better ways, I'm sure) */ - BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) { -#ifdef BMESH_263_VERT_BEVEL_WORKAROUND - add_newell_cross_v3_v3v3(up_vec, l->prev->v->co, l->v->co); -#else - BME_bevel_get_vec(vec1, l->v, l->next->v, td); - BME_bevel_get_vec(vec2, l->prev->v, l->v, td); - cross_v3_v3v3(vec3, vec2, vec1); - add_v3_v3(up_vec, vec3); - -#endif - } - normalize_v3(up_vec); - - /* Can't use a BM_LOOPS_OF_FACE iterator here, because the loops are being modified - * and so the end condition will never hi */ - for (l = BM_FACE_FIRST_LOOP(f)->prev, i = 0, len = f->len; i < len; i++, l = l->next) { - if (BMO_elem_flag_test(bm, l->e, BME_BEVEL_BEVEL) && BMO_elem_flag_test(bm, l->e, BME_BEVEL_ORIG)) { - max = 1.0f; - l = BME_bevel_edge(bm, l, value, options, up_vec, td); - } - else if (BMO_elem_flag_test(bm, l->v, BME_BEVEL_BEVEL) && - BMO_elem_flag_test(bm, l->v, BME_BEVEL_ORIG) && - !BMO_elem_flag_test(bm, l->prev->e, BME_BEVEL_BEVEL)) - { - /* avoid making double vertices [#33438] */ - BME_TransData *vtd; - vtd = BME_get_transdata(td, l->v); - if (vtd->weight == 0.0f) { - BMO_elem_flag_disable(bm, l->v, BME_BEVEL_BEVEL); - } - else { - max = 1.0f; - l = BME_bevel_vert(bm, l, value, options, up_vec, td); - } - } - } - - f = l->f; - - /* max pass */ - if (value > 0.5f && max > 0.0f) { - max = -1; - BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) { - if (BMO_elem_flag_test(bm, l->e, BME_BEVEL_BEVEL) || BMO_elem_flag_test(bm, l->e, BME_BEVEL_ORIG)) { - BME_bevel_get_vec(vec1, l->v, l->next->v, td); - vtd1 = BME_get_transdata(td, l->v); - vtd2 = BME_get_transdata(td, l->next->v); - if (vtd1->loc == NULL) { - fac1 = 0; - } - else { - copy_v3_v3(vec2, vtd1->vec); - mul_v3_fl(vec2, vtd1->factor); - if (dot_v3v3(vec1, vec1)) { - project_v3_v3v3(vec2, vec2, vec1); - fac1 = len_v3(vec2) / value; - } - else { - fac1 = 0; - } - } - if (vtd2->loc == NULL) { - fac2 = 0; - } - else { - copy_v3_v3(vec3, vtd2->vec); - mul_v3_fl(vec3, vtd2->factor); - if (dot_v3v3(vec1, vec1)) { - project_v3_v3v3(vec2, vec3, vec1); - fac2 = len_v3(vec2) / value; - } - else { - fac2 = 0; - } - } - if (fac1 || fac2) { - max = len_v3(vec1) / (fac1 + fac2); - if (vtd1->max && (*vtd1->max < 0 || max < *vtd1->max)) { - *vtd1->max = max; - } - if (vtd2->max && (*vtd2->max < 0 || max < *vtd2->max)) { - *vtd2->max = max; - } - } - } - } - } - - /* return l->f; */ - return NULL; -} - -static float BME_bevel_get_angle(BMEdge *e, BMVert *v) -{ - BMVert *v1, *v2; - BMLoop *l1, *l2; - float vec1[3], vec2[3], vec3[3], vec4[3]; - - l1 = e->l; - l2 = e->l->radial_next; - if (l1->v == v) { - v1 = l1->prev->v; - v2 = l1->next->v; - } - else { - v1 = l1->next->next->v; - v2 = l1->v; - } - sub_v3_v3v3(vec1, v1->co, v->co); - sub_v3_v3v3(vec2, v2->co, v->co); - cross_v3_v3v3(vec3, vec1, vec2); - - l1 = l2; - if (l1->v == v) { - v1 = l1->prev->v; - v2 = l1->next->v; - } - else { - v1 = l1->next->next->v; - v2 = l1->v; - } - sub_v3_v3v3(vec1, v1->co, v->co); - sub_v3_v3v3(vec2, v2->co, v->co); - cross_v3_v3v3(vec4, vec2, vec1); - - normalize_v3(vec3); - normalize_v3(vec4); - - return dot_v3v3(vec3, vec4); -} - -static float BME_bevel_get_angle_vert(BMVert *v) -{ - BMIter iter; - BMLoop *l; - float n[3]; - float n_tmp[3]; - float angle_diff = 0.0f; - float tot_angle = 0.0f; - - - BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) { - const float angle = BM_loop_calc_face_angle(l); - tot_angle += angle; - BM_loop_calc_face_normal(l, n_tmp); - madd_v3_v3fl(n, n_tmp, angle); - } - normalize_v3(n); - - BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) { - /* could cache from before */ - BM_loop_calc_face_normal(l, n_tmp); - angle_diff += angle_normalized_v3v3(n, n_tmp) * BM_loop_calc_face_angle(l); - } - - /* return cosf(angle_diff + 0.001f); */ /* compare with dot product */ - return (angle_diff / tot_angle) * (float)(M_PI / 2.0); -} - -static void BME_bevel_add_vweight(BME_TransData_Head *td, BMesh *bm, BMVert *v, float weight, float factor, int options) -{ - BME_TransData *vtd; - - if (BMO_elem_flag_test(bm, v, BME_BEVEL_NONMAN)) { - return; - } - - BMO_elem_flag_enable(bm, v, BME_BEVEL_BEVEL); - if ((vtd = BME_get_transdata(td, v))) { - if (options & BME_BEVEL_EMIN) { - vtd->factor = 1.0; - if (vtd->weight < 0 || weight < vtd->weight) { - vtd->weight = weight; - } - } - else if (options & BME_BEVEL_EMAX) { - vtd->factor = 1.0; - if (weight > vtd->weight) { - vtd->weight = weight; - } - } - else if (vtd->weight < 0.0f) { - vtd->factor = factor; - vtd->weight = weight; - } - else { - vtd->factor += factor; /* increment number of edges with weights (will be averaged) */ - vtd->weight += weight; /* accumulate all the weights */ - } - } - else { - /* we'll use vtd->loc == NULL to mark that this vert is not moving */ - vtd = BME_assign_transdata(td, bm, v, v->co, NULL, NULL, NULL, factor, weight, -1, NULL); - } -} - -static void bevel_init_verts(BMesh *bm, int options, float angle, BME_TransData_Head *td) -{ - BMVert *v; - BMIter iter; - float weight; - /* const float threshold = (options & BME_BEVEL_ANGLE) ? cosf(angle + 0.001) : 0.0f; */ /* UNUSED */ - - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - weight = 0.0f; - if (!BMO_elem_flag_test(bm, v, BME_BEVEL_NONMAN)) { - /* modifiers should not use selection */ - if (options & BME_BEVEL_SELECT) { - if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { - weight = 1.0f; - } - } - /* bevel weight NYI */ - else if (options & BME_BEVEL_WEIGHT) { - weight = BM_elem_float_data_get(&bm->vdata, v, CD_BWEIGHT); - } - else if (options & BME_BEVEL_ANGLE) { - /* dont set weight_v1/weight_v2 here, add direct */ - if (BME_bevel_get_angle_vert(v) > angle) { - weight = 1.0f; - } - } - else { - weight = 1.0f; - } - - if (weight > 0.0f) { - BMO_elem_flag_enable(bm, v, BME_BEVEL_BEVEL); - BME_assign_transdata(td, bm, v, v->co, v->co, NULL, NULL, 1.0, weight, -1, NULL); - } - } - } -} - -static void bevel_init_edges(BMesh *bm, int options, float angle, BME_TransData_Head *td) -{ - BMEdge *e; - int count; - float weight; - BMIter iter; - const float threshold = (options & BME_BEVEL_ANGLE) ? cosf(angle + 0.001f) : 0.0f; - - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - weight = 0.0f; - if (!BMO_elem_flag_test(bm, e, BME_BEVEL_NONMAN)) { - if (options & BME_BEVEL_SELECT) { - if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { - weight = 1.0f; - } - } - else if (options & BME_BEVEL_WEIGHT) { - weight = BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT); - } - else if (options & BME_BEVEL_ANGLE) { - /* dont set weight_v1/weight_v2 here, add direct */ - if (!BMO_elem_flag_test(bm, e->v1, BME_BEVEL_NONMAN) && BME_bevel_get_angle(e, e->v1) < threshold) { - BMO_elem_flag_enable(bm, e, BME_BEVEL_BEVEL); - BME_bevel_add_vweight(td, bm, e->v1, 1.0, 1.0, options); - } - else { - BME_bevel_add_vweight(td, bm, e->v1, 0.0, 1.0, options); - } - if (!BMO_elem_flag_test(bm, e->v2, BME_BEVEL_NONMAN) && BME_bevel_get_angle(e, e->v2) < threshold) { - BMO_elem_flag_enable(bm, e, BME_BEVEL_BEVEL); - BME_bevel_add_vweight(td, bm, e->v2, 1.0, 1.0, options); - } - else { - BME_bevel_add_vweight(td, bm, e->v2, 0.0, 1.0, options); - } - } - else { - weight = 1.0f; - } - - if (weight > 0.0f) { - BMO_elem_flag_enable(bm, e, BME_BEVEL_BEVEL); - BME_bevel_add_vweight(td, bm, e->v1, weight, 1.0, options); - BME_bevel_add_vweight(td, bm, e->v2, weight, 1.0, options); - } - } - } - - /* clean up edges with 2 faces that share more than one edg */ - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - if (BMO_elem_flag_test(bm, e, BME_BEVEL_BEVEL)) { - count = BM_face_share_edge_count(e->l->f, e->l->radial_next->f); - if (count > 1) BMO_elem_flag_disable(bm, e, BME_BEVEL_BEVEL); - } - } -} - -static BMesh *BME_bevel_initialize(BMesh *bm, int options, - int UNUSED(defgrp_index), float angle, BME_TransData_Head *td) -{ - BMVert *v /*, *v2 */; - BMEdge *e /*, *curedg */; - BMFace *f; - BMIter iter; - int /* wire, */ len; - - /* tag non-manifold geometry */ - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - BMO_elem_flag_enable(bm, v, BME_BEVEL_ORIG); - if (v->e) { - BME_assign_transdata(td, bm, v, v->co, v->co, NULL, NULL, 0, -1, -1, NULL); - if (!BM_vert_is_manifold(v)) { - BMO_elem_flag_enable(bm, v, BME_BEVEL_NONMAN); - } - - /* test wire ver */ - len = BM_vert_edge_count(v); - if (len == 2 && BM_vert_is_wire(v)) - BMO_elem_flag_disable(bm, v, BME_BEVEL_NONMAN); - } - else { - BMO_elem_flag_enable(bm, v, BME_BEVEL_NONMAN); - } - } - - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - BMO_elem_flag_enable(bm, e, BME_BEVEL_ORIG); - if (!(BM_edge_is_boundary(e) || BM_edge_is_manifold(e))) { - BMO_elem_flag_enable(bm, e->v1, BME_BEVEL_NONMAN); - BMO_elem_flag_enable(bm, e->v2, BME_BEVEL_NONMAN); - BMO_elem_flag_enable(bm, e, BME_BEVEL_NONMAN); - } - if (BMO_elem_flag_test(bm, e->v1, BME_BEVEL_NONMAN) || BMO_elem_flag_test(bm, e->v2, BME_BEVEL_NONMAN)) { - BMO_elem_flag_enable(bm, e, BME_BEVEL_NONMAN); - } - } - - BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { - BMO_elem_flag_enable(bm, f, BME_BEVEL_ORIG); - } - - if (options & BME_BEVEL_VERT) { - bevel_init_verts(bm, options, angle, td); - } - else { - bevel_init_edges(bm, options, angle, td); - } - - return bm; - -} - -#if 0 - -static BMesh *BME_bevel_reinitialize(BMesh *bm) -{ - BMVert *v; - BMEdge *e; - BMFace *f; - BMIter iter; - - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - BMO_elem_flag_enable(bm, v, BME_BEVEL_ORIG); - } - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - BMO_elem_flag_enable(bm, e, BME_BEVEL_ORIG); - } - BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { - BMO_elem_flag_enable(bm, f, BME_BEVEL_ORIG); - } - return bm; - -} - -#endif - -/** - * BME_bevel_mesh - * - * Mesh beveling tool: - * - * Bevels an entire mesh. It currently uses the flags of - * its vertices and edges to track topological changes. - * The parameter "value" is the distance to inset (should be negative). - * The parameter "options" is not currently used. - * - * \return A BMesh pointer to the BM passed as a parameter. - */ - -static BMesh *BME_bevel_mesh(BMesh *bm, float value, int UNUSED(res), int options, - int UNUSED(defgrp_index), BME_TransData_Head *td) -{ - BMVert *v; - BMEdge *e, *curedge; - BMLoop *l, *l2; - BMFace *f; - BMIter iter; - - /* unsigned int i, len; */ - - /* bevel poly */ - BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { - if (BMO_elem_flag_test(bm, f, BME_BEVEL_ORIG)) { - BME_bevel_poly(bm, f, value, options, td); - } - } - - /* get rid of beveled edge */ - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - if (BMO_elem_flag_test(bm, e, BME_BEVEL_BEVEL) && BMO_elem_flag_test(bm, e, BME_BEVEL_ORIG)) { - BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, true); - } - } - - /* link up corners and cli */ - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - if (BMO_elem_flag_test(bm, v, BME_BEVEL_ORIG) && BMO_elem_flag_test(bm, v, BME_BEVEL_BEVEL)) { - curedge = v->e; - do { - l = curedge->l; - l2 = l->radial_next; - if (l->v != v) l = l->next; - if (l2->v != v) l2 = l2->next; - if (l->f->len > 3) - BM_face_split(bm, l->f, l->next->v, l->prev->v, &l, l->e, true); /* clip this corner off */ - if (l2->f->len > 3) - BM_face_split(bm, l2->f, l2->next->v, l2->prev->v, &l, l2->e, true); /* clip this corner off */ - curedge = bmesh_disk_edge_next(curedge, v); - } while (curedge != v->e); - BME_Bevel_Dissolve_Disk(bm, v); - } - } - -#ifdef DEBUG - /* Debug print, remov */ - BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { - if (f->len == 2) { - printf("%s: warning, 2 edge face\n", __func__); - } - } -#endif - - return bm; -} - -BMesh *BME_bevel(BMesh *bm, float value, int res, int options, int defgrp_index, float angle, - BME_TransData_Head **rtd) -{ - BMVert *v; - BMIter iter; - - BME_TransData_Head *td; - BME_TransData *vtd; - int i; - double fac = 1.0, d; - - td = BME_init_transdata(BLI_MEMARENA_STD_BUFSIZE); - /* recursion math courtesy of Martin Poirier (theeth) */ - for (i = 0; i < res - 1; i++) { - if (i == 0) fac += 1.0 / 3.0; - else fac += 1.0 / (3.0 * i * 2.0); - } - d = 1.0 / fac; - - BM_mesh_elem_toolflags_ensure(bm); - - for (i = 0; i < res || (res == 0 && i == 0); i++) { - BMO_push(bm, NULL); - BME_bevel_initialize(bm, options, defgrp_index, angle, td); - //if (i != 0) BME_bevel_reinitialize(bm); - bmesh_edit_begin(bm, 0); - BME_bevel_mesh(bm, (float)d, res, options, defgrp_index, td); - bmesh_edit_end(bm, 0); - d /= (i == 0) ? 3.0 : 2.0; - BMO_pop(bm); - } - - /* interactive preview? */ - if (rtd) { - *rtd = td; - return bm; - } - - /* otherwise apply transforms */ - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - if ((vtd = BME_get_transdata(td, v))) { - if (vtd->max && (*vtd->max > 0 && value > *vtd->max)) { - d = *vtd->max; - } - else { - d = value; - } - madd_v3_v3v3fl(v->co, vtd->org, vtd->vec, vtd->factor * (float)d); - } - } - - BME_free_transdata(td); - return bm; -} diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 6431b6b7cf5..02f0251bff2 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -34,6 +34,7 @@ #include "DNA_meshdata_types.h" #include "BLI_array.h" +#include "BLI_alloca.h" #include "BLI_math.h" #include "BLI_memarena.h" diff --git a/source/blender/bmesh/tools/bmesh_decimate.h b/source/blender/bmesh/tools/bmesh_decimate.h index c77cb18c518..a1b26990587 100644 --- a/source/blender/bmesh/tools/bmesh_decimate.h +++ b/source/blender/bmesh/tools/bmesh_decimate.h @@ -35,7 +35,8 @@ void BM_mesh_decimate_unsubdivide(BMesh *bm, const int iterations); void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries, const BMO_Delimit delimit, BMVert **vinput_arr, const int vinput_len, - BMEdge **einput_arr, const int einput_len); + BMEdge **einput_arr, const int einput_len, + const short oflag_out); void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries, const BMO_Delimit delimit); diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c index d3ffc348539..4b6835a81fe 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c +++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c @@ -345,7 +345,7 @@ static bool bm_decim_triangulate_begin(BMesh *bm) } #ifdef USE_SAFETY_CHECKS - if (BM_edge_exists(l_a->v, l_b->v) == false) + if (BM_edge_exists(l_a->v, l_b->v) == NULL) #endif { BMFace *f_new; diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c index 9d4e01d19cd..310357453a3 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c +++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c @@ -30,18 +30,22 @@ #include "MEM_guardedalloc.h" #include "BLI_math.h" +#include "BLI_heap.h" #include "bmesh.h" #include "bmesh_decimate.h" /* own include */ -#define UNIT_TO_ANGLE DEG2RADF(90.0f) -#define ANGLE_TO_UNIT (1.0f / UNIT_TO_ANGLE) +#define COST_INVALID FLT_MAX + /* multiply vertex edge angle by face angle * this means we are not left with sharp corners between _almost_ planer faces * convert angles [0-PI/2] -> [0-1], multiply together, then convert back to radians. */ static float bm_vert_edge_face_angle(BMVert *v) { +#define UNIT_TO_ANGLE DEG2RADF(90.0f) +#define ANGLE_TO_UNIT (1.0f / UNIT_TO_ANGLE) + const float angle = BM_vert_calc_edge_angle(v); /* note: could be either edge, it doesn't matter */ if (v->e && BM_edge_is_manifold(v->e)) { @@ -50,163 +54,184 @@ static float bm_vert_edge_face_angle(BMVert *v) else { return angle; } -} #undef UNIT_TO_ANGLE #undef ANGLE_TO_UNIT - -typedef struct DissolveElemWeight { - BMHeader *ele; - float weight; -} DissolveElemWeight; - -static int dissolve_elem_cmp(const void *a1, const void *a2) -{ - const struct DissolveElemWeight *d1 = a1, *d2 = a2; - - if (d1->weight > d2->weight) return 1; - else if (d1->weight < d2->weight) return -1; - return 0; } -void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries, - const BMO_Delimit delimit, - BMVert **vinput_arr, const int vinput_len, - BMEdge **einput_arr, const int einput_len) +static float bm_edge_calc_dissolve_error(const BMEdge *e, const BMO_Delimit delimit) { - const float angle_max = (float)M_PI / 2.0f; - DissolveElemWeight *weight_elems = MEM_mallocN(max_ii(einput_len, vinput_len) * - sizeof(DissolveElemWeight), __func__); - int i, tot_found; - BMIter iter; - BMEdge *e_iter; - BMEdge **earray; - - int *vert_reverse_lookup; + const bool is_contig = BM_edge_is_contiguous(e); + float angle; - /* --- first edges --- */ + if (!BM_edge_is_manifold(e)) { + goto fail; + } - /* wire -> tag */ - BM_ITER_MESH (e_iter, &iter, bm, BM_EDGES_OF_MESH) { - BM_elem_flag_set(e_iter, BM_ELEM_TAG, BM_edge_is_wire(e_iter)); + if ((delimit & BMO_DELIM_SEAM) && + (BM_elem_flag_test(e, BM_ELEM_SEAM))) + { + goto fail; } - /* go through and split edge */ - for (i = 0, tot_found = 0; i < einput_len; i++) { - BMEdge *e = einput_arr[i]; - const bool is_contig = BM_edge_is_contiguous(e); - float angle; + if ((delimit & BMO_DELIM_MATERIAL) && + (e->l->f->mat_nr != e->l->radial_next->f->mat_nr)) + { + goto fail; + } - angle = BM_edge_calc_face_angle(e); - if (is_contig == false) { - angle = (float)M_PI - angle; - } + if ((delimit & BMO_DELIM_NORMAL) && + (is_contig == false)) + { + goto fail; + } - if (angle < angle_limit) { - tot_found++; - } - weight_elems[i].ele = (BMHeader *)e; - weight_elems[i].weight = angle; + angle = BM_edge_calc_face_angle(e); + if (is_contig == false) { + angle = (float)M_PI - angle; } - if (tot_found != 0) { - qsort(weight_elems, einput_len, sizeof(DissolveElemWeight), dissolve_elem_cmp); + return angle; - for (i = 0; i < tot_found; i++) { - BMEdge *e = (BMEdge *)weight_elems[i].ele; - const bool is_contig = BM_edge_is_contiguous(e); - float angle; +fail: + return COST_INVALID; +} - /* may have become non-manifold */ - if (!BM_edge_is_manifold(e)) { - continue; - } - if ((delimit & BMO_DELIM_SEAM) && - (BM_elem_flag_test(e, BM_ELEM_SEAM))) - { - continue; - } +void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries, + const BMO_Delimit delimit, + BMVert **vinput_arr, const int vinput_len, + BMEdge **einput_arr, const int einput_len, + const short oflag_out) +{ + const int eheap_table_len = do_dissolve_boundaries ? einput_len : max_ii(einput_len, vinput_len); + void *_heap_table = MEM_mallocN(sizeof(HeapNode *) * eheap_table_len, __func__); - if ((delimit & BMO_DELIM_MATERIAL) && - (e->l->f->mat_nr != e->l->radial_next->f->mat_nr)) - { - continue; - } + int i; - if ((delimit & BMO_DELIM_NORMAL) && - (is_contig == false)) - { - continue; - } + /* --- first edges --- */ + if (1) { + BMEdge **earray; + Heap *eheap; + HeapNode **eheap_table = _heap_table; + HeapNode *enode_top; + int *vert_reverse_lookup; + BMIter iter; + BMEdge *e_iter; + + /* --- setup heap --- */ + eheap = BLI_heap_new_ex(einput_len); + eheap_table = _heap_table; + + /* wire -> tag */ + BM_ITER_MESH (e_iter, &iter, bm, BM_EDGES_OF_MESH) { + BM_elem_flag_set(e_iter, BM_ELEM_TAG, BM_edge_is_wire(e_iter)); + BM_elem_index_set(e_iter, -1); /* set dirty */ + } + bm->elem_index_dirty |= BM_EDGE; + + /* build heap */ + for (i = 0; i < einput_len; i++) { + BMEdge *e = einput_arr[i]; + const float cost = bm_edge_calc_dissolve_error(e, delimit); + eheap_table[i] = BLI_heap_insert(eheap, cost, e); + BM_elem_index_set(e, i); /* set dirty */ + } - /* check twice because cumulative effect could dissolve over angle limit */ - angle = BM_edge_calc_face_angle(e); - if (is_contig == false) { - angle = (float)M_PI - angle; - } + while ((BLI_heap_is_empty(eheap) == false) && + (BLI_heap_node_value((enode_top = BLI_heap_top(eheap))) < angle_limit)) + { + BMFace *f_new = NULL; + BMEdge *e; + + e = BLI_heap_node_ptr(enode_top); + i = BM_elem_index_get(e); - if (angle < angle_limit) { - BMFace *f_new = BM_faces_join_pair(bm, e->l->f, - e->l->radial_next->f, - e, - false); /* join faces */ + if (BM_edge_is_manifold(e)) { + f_new = BM_faces_join_pair(bm, e->l->f, + e->l->radial_next->f, e, + false); /* join faces */ - /* there may be some errors, we don't mind, just move on */ if (f_new) { + BMLoop *l_first, *l_iter; + + BLI_heap_remove(eheap, enode_top); + eheap_table[i] = NULL; + + /* update normal */ BM_face_normal_update(f_new); + if (oflag_out) { + BMO_elem_flag_enable(bm, f_new, oflag_out); + } + + /* re-calculate costs */ + l_iter = l_first = BM_FACE_FIRST_LOOP(f_new); + do { + const int j = BM_elem_index_get(l_iter->e); + if (j != -1 && eheap_table[j]) { + const float cost = bm_edge_calc_dissolve_error(l_iter->e, delimit); + BLI_heap_remove(eheap, eheap_table[j]); + eheap_table[j] = BLI_heap_insert(eheap, cost, l_iter->e); + } + } while ((l_iter = l_iter->next) != l_first); } else { BMO_error_clear(bm); } } + + if (UNLIKELY(f_new == NULL)) { + BLI_heap_remove(eheap, enode_top); + eheap_table[i] = BLI_heap_insert(eheap, COST_INVALID, e); + } } - } - /* prepare for cleanup */ - BM_mesh_elem_index_ensure(bm, BM_VERT); - vert_reverse_lookup = MEM_mallocN(sizeof(int) * bm->totvert, __func__); - fill_vn_i(vert_reverse_lookup, bm->totvert, -1); - for (i = 0, tot_found = 0; i < vinput_len; i++) { - BMVert *v = vinput_arr[i]; - vert_reverse_lookup[BM_elem_index_get(v)] = i; - } + /* prepare for cleanup */ + BM_mesh_elem_index_ensure(bm, BM_VERT); + vert_reverse_lookup = MEM_mallocN(sizeof(int) * bm->totvert, __func__); + fill_vn_i(vert_reverse_lookup, bm->totvert, -1); + for (i = 0; i < vinput_len; i++) { + BMVert *v = vinput_arr[i]; + vert_reverse_lookup[BM_elem_index_get(v)] = i; + } - /* --- cleanup --- */ - earray = MEM_mallocN(sizeof(BMEdge *) * bm->totedge, __func__); - BM_ITER_MESH_INDEX (e_iter, &iter, bm, BM_EDGES_OF_MESH, i) { - earray[i] = e_iter; - } - /* remove all edges/verts left behind from dissolving, NULL'ing the vertex array so we dont re-use */ - for (i = bm->totedge - 1; i != -1; i--) { - e_iter = earray[i]; - - if (BM_edge_is_wire(e_iter) && (BM_elem_flag_test(e_iter, BM_ELEM_TAG) == false)) { - /* edge has become wire */ - int vidx_reverse; - BMVert *v1 = e_iter->v1; - BMVert *v2 = e_iter->v2; - BM_edge_kill(bm, e_iter); - if (v1->e == NULL) { - vidx_reverse = vert_reverse_lookup[BM_elem_index_get(v1)]; - if (vidx_reverse != -1) vinput_arr[vidx_reverse] = NULL; - BM_vert_kill(bm, v1); - } - if (v2->e == NULL) { - vidx_reverse = vert_reverse_lookup[BM_elem_index_get(v2)]; - if (vidx_reverse != -1) vinput_arr[vidx_reverse] = NULL; - BM_vert_kill(bm, v2); + /* --- cleanup --- */ + earray = MEM_mallocN(sizeof(BMEdge *) * bm->totedge, __func__); + BM_ITER_MESH_INDEX (e_iter, &iter, bm, BM_EDGES_OF_MESH, i) { + earray[i] = e_iter; + } + /* remove all edges/verts left behind from dissolving, NULL'ing the vertex array so we dont re-use */ + for (i = bm->totedge - 1; i != -1; i--) { + e_iter = earray[i]; + + if (BM_edge_is_wire(e_iter) && (BM_elem_flag_test(e_iter, BM_ELEM_TAG) == false)) { + /* edge has become wire */ + int vidx_reverse; + BMVert *v1 = e_iter->v1; + BMVert *v2 = e_iter->v2; + BM_edge_kill(bm, e_iter); + if (v1->e == NULL) { + vidx_reverse = vert_reverse_lookup[BM_elem_index_get(v1)]; + if (vidx_reverse != -1) vinput_arr[vidx_reverse] = NULL; + BM_vert_kill(bm, v1); + } + if (v2->e == NULL) { + vidx_reverse = vert_reverse_lookup[BM_elem_index_get(v2)]; + if (vidx_reverse != -1) vinput_arr[vidx_reverse] = NULL; + BM_vert_kill(bm, v2); + } } } - } - MEM_freeN(vert_reverse_lookup); + MEM_freeN(vert_reverse_lookup); + MEM_freeN(earray); - MEM_freeN(earray); + BLI_heap_free(eheap, NULL); + } /* --- second verts --- */ if (do_dissolve_boundaries) { - /* simple version of the branch below, sincve we will dissolve _all_ verts that use 2 edges */ + /* simple version of the branch below, since we will dissolve _all_ verts that use 2 edges */ for (i = 0; i < vinput_len; i++) { BMVert *v = vinput_arr[i]; if (LIKELY(v != NULL) && @@ -217,43 +242,78 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool } } else { - for (i = 0, tot_found = 0; i < vinput_len; i++) { - BMVert *v = vinput_arr[i]; - const float angle = v ? bm_vert_edge_face_angle(v) : angle_limit; + Heap *vheap; + HeapNode **vheap_table = _heap_table; + HeapNode *vnode_top; - if (angle < angle_limit) { - weight_elems[i].ele = (BMHeader *)v; - weight_elems[i].weight = angle; - tot_found++; - } - else { - weight_elems[i].ele = NULL; - weight_elems[i].weight = angle_max; + BMVert *v_iter; + BMIter iter; + + BM_ITER_MESH (v_iter, &iter, bm, BM_VERTS_OF_MESH) { + BM_elem_index_set(v_iter, -1); /* set dirty */ + } + bm->elem_index_dirty |= BM_VERT; + + vheap = BLI_heap_new_ex(vinput_len); + + for (i = 0; i < vinput_len; i++) { + BMVert *v = vinput_arr[i]; + if (LIKELY(v != NULL)) { + const float cost = bm_vert_edge_face_angle(v); + vheap_table[i] = BLI_heap_insert(vheap, cost, v); + BM_elem_index_set(v, i); /* set dirty */ } } - if (tot_found != 0) { - qsort(weight_elems, vinput_len, sizeof(DissolveElemWeight), dissolve_elem_cmp); - - for (i = 0; i < tot_found; i++) { - BMVert *v = (BMVert *)weight_elems[i].ele; - if (LIKELY(v != NULL) && - /* topology changes may cause this to be un-collapsable */ - (BM_vert_edge_count(v) == 2) && - /* check twice because cumulative effect could dissolve over angle limit */ - bm_vert_edge_face_angle(v) < angle_limit) - { - BMEdge *e_new = BM_vert_collapse_edge(bm, v->e, v, true); /* join edges */ - - if (e_new && e_new->l) { - BM_edge_normals_update(e_new); + while ((BLI_heap_is_empty(vheap) == false) && + (BLI_heap_node_value((vnode_top = BLI_heap_top(vheap))) < angle_limit)) + { + BMEdge *e_new = NULL; + BMVert *v; + + v = BLI_heap_node_ptr(vnode_top); + i = BM_elem_index_get(v); + + if (BM_vert_edge_count(v) == 2) { + e_new = BM_vert_collapse_edge(bm, v->e, v, true); /* join edges */ + + if (e_new) { + + BLI_heap_remove(vheap, vnode_top); + vheap_table[i] = NULL; + + /* update normal */ + if (e_new->l) { + BMLoop *l_first, *l_iter; + l_iter = l_first = e_new->l; + do { + BM_face_normal_update(l_iter->f); + } while ((l_iter = l_iter->radial_next) != l_first); + + } + + /* re-calculate costs */ + BM_ITER_ELEM(v_iter, &iter, e_new, BM_VERTS_OF_EDGE) { + const int j = BM_elem_index_get(v_iter); + if (j != -1 && vheap_table[j]) { + const float cost = bm_vert_edge_face_angle(v_iter); + BLI_heap_remove(vheap, vheap_table[j]); + vheap_table[j] = BLI_heap_insert(vheap, cost, v_iter); + } } } } + + if (UNLIKELY(e_new == NULL)) { + BLI_heap_remove(vheap, vnode_top); + vheap_table[i] = BLI_heap_insert(vheap, COST_INVALID, v); + } } + + BLI_heap_free(vheap, NULL); } - MEM_freeN(weight_elems); + MEM_freeN(_heap_table); } void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries, @@ -269,7 +329,8 @@ void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const bool do BM_mesh_decimate_dissolve_ex(bm, angle_limit, do_dissolve_boundaries, delimit, vinput_arr, vinput_len, - einput_arr, einput_len); + einput_arr, einput_len, + 0); MEM_freeN(vinput_arr); MEM_freeN(einput_arr); diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.c b/source/blender/bmesh/tools/bmesh_edgesplit.c index 3ae5c712f0a..aad600d13fa 100644 --- a/source/blender/bmesh/tools/bmesh_edgesplit.c +++ b/source/blender/bmesh/tools/bmesh_edgesplit.c @@ -98,11 +98,26 @@ static void bm_edgesplit_validate_seams(BMesh *bm) MEM_freeN(vtouch); } -void BM_mesh_edgesplit(BMesh *bm, const bool use_verts, const bool tag_only) +void BM_mesh_edgesplit(BMesh *bm, const bool use_verts, const bool tag_only, const bool copy_select) { BMIter iter; BMEdge *e; + bool use_ese = false; + GHash *ese_gh = NULL; + + if (copy_select && bm->selected.first) { + BMEditSelection *ese; + + ese_gh = BLI_ghash_ptr_new(__func__); + for (ese = bm->selected.first; ese; ese = ese->next) { + if (ese->htype != BM_FACE) { + BLI_ghash_insert(ese_gh, ese->ele, ese); + } + } + + use_ese = true; + } if (tag_only == false) { BM_mesh_elem_hflag_enable_all(bm, BM_EDGE | (use_verts ? BM_VERT : 0), BM_ELEM_TAG, false); @@ -135,9 +150,18 @@ void BM_mesh_edgesplit(BMesh *bm, const bool use_verts, const bool tag_only) BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG); /* keep splitting until each loop has its own edge */ - do { - bmesh_edge_separate(bm, e, e->l); - } while (!BM_edge_is_boundary(e)); + while (!BM_edge_is_boundary(e)) { + BMLoop *l_sep = e->l; + bmesh_edge_separate(bm, e, l_sep, copy_select); + BLI_assert(l_sep->e != e); + + if (use_ese) { + BMEditSelection *ese = BLI_ghash_lookup(ese_gh, e); + if (UNLIKELY(ese)) { + BM_select_history_store_after_notest(bm, ese, l_sep->e); + } + } + } BM_elem_flag_enable(e->v1, BM_ELEM_TAG); BM_elem_flag_enable(e->v2, BM_ELEM_TAG); @@ -157,14 +181,39 @@ void BM_mesh_edgesplit(BMesh *bm, const bool use_verts, const bool tag_only) BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(e, BM_ELEM_TAG)) { - if (BM_elem_flag_test(e->v1, BM_ELEM_TAG)) { - BM_elem_flag_disable(e->v1, BM_ELEM_TAG); - bmesh_vert_separate(bm, e->v1, NULL, NULL); - } - if (BM_elem_flag_test(e->v2, BM_ELEM_TAG)) { - BM_elem_flag_disable(e->v2, BM_ELEM_TAG); - bmesh_vert_separate(bm, e->v2, NULL, NULL); + unsigned int i; + for (i = 0; i < 2; i++) { + BMVert *v = ((&e->v1)[i]); + if (BM_elem_flag_test(v, BM_ELEM_TAG)) { + BM_elem_flag_disable(v, BM_ELEM_TAG); + + if (use_ese) { + BMVert **vtar; + int vtar_len; + + bmesh_vert_separate(bm, v, &vtar, &vtar_len, copy_select); + + if (vtar_len) { + BMEditSelection *ese = BLI_ghash_lookup(ese_gh, v); + if (UNLIKELY(ese)) { + int j; + for (j = 0; j < vtar_len; j++) { + BLI_assert(v != vtar[j]); + BM_select_history_store_after_notest(bm, ese, vtar[j]); + } + } + } + MEM_freeN(vtar); + } + else { + bmesh_vert_separate(bm, v, NULL, NULL, copy_select); + } + } } } } + + if (use_ese) { + BLI_ghash_free(ese_gh, NULL, NULL); + } } diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.h b/source/blender/bmesh/tools/bmesh_edgesplit.h index 8c1231dd794..bd66f6a9e2f 100644 --- a/source/blender/bmesh/tools/bmesh_edgesplit.h +++ b/source/blender/bmesh/tools/bmesh_edgesplit.h @@ -27,6 +27,6 @@ * \ingroup bmesh */ -void BM_mesh_edgesplit(BMesh *bm, const bool use_verts, const bool tag_only); +void BM_mesh_edgesplit(BMesh *bm, const bool use_verts, const bool tag_only, const bool copy_select); #endif /* __BMESH_EDGESPLIT_H__ */ diff --git a/source/blender/bmesh/tools/bmesh_triangulate.c b/source/blender/bmesh/tools/bmesh_triangulate.c index 79f6c76afc7..2eacf62d68a 100644 --- a/source/blender/bmesh/tools/bmesh_triangulate.c +++ b/source/blender/bmesh/tools/bmesh_triangulate.c @@ -30,7 +30,7 @@ #include "MEM_guardedalloc.h" #include "BLI_utildefines.h" -#include "BLI_array.h" +#include "BLI_alloca.h" #include "bmesh.h" diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index eb92b089f48..5d47ce155c8 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -50,7 +50,11 @@ static const char *bc_get_joint_name(T *node) } ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Scene *sce) : - TransformReader(conv), scene(sce), empty(NULL), mesh_importer(mesh) { + unit_converter(conv), + TransformReader(conv), + scene(sce), + empty(NULL), + mesh_importer(mesh) { } ArmatureImporter::~ArmatureImporter() @@ -82,17 +86,15 @@ JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node); void ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBone *parent, int totchild, float parent_mat[4][4], bArmature *arm) { + float mat[4][4]; + float joint_inv_bind_mat[4][4]; + //Checking if bone is already made. std::vector<COLLADAFW::Node *>::iterator it; it = std::find(finished_joints.begin(), finished_joints.end(), node); if (it != finished_joints.end()) return; - float joint_inv_bind_mat[4][4]; - // JointData* jd = get_joint_data(node); - - float mat[4][4]; - float obmat[4][4]; // TODO rename from Node "name" attrs later EditBone *bone = ED_armature_edit_bone_add(arm, (char *)bc_get_joint_name(node)); @@ -101,9 +103,18 @@ void ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBo if (skin && skin->get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) { // get original world-space matrix invert_m4_m4(mat, joint_inv_bind_mat); + + // And make local to armature + Object *ob_arm = skin->BKE_armature_from_object(); + if (ob_arm) { + float invmat[4][4]; + invert_m4_m4(invmat, ob_arm->obmat); + mul_m4_m4m4(mat, invmat, mat); + } } // create a bone even if there's no joint data for it (i.e. it has no influence) else { + float obmat[4][4]; // bone-space get_node_mat(obmat, node, NULL, NULL); @@ -204,16 +215,21 @@ void ArmatureImporter::add_leaf_bone(float mat[4][4], EditBone *bone, COLLADAFW void ArmatureImporter::fix_leaf_bones( ) { + // Collada only knows Joints, Here we guess a reasonable + // leaf bone length + float leaf_length = (leaf_bone_length == FLT_MAX) ? 1.0:leaf_bone_length; + // just setting tail for leaf bones here std::vector<LeafBone>::iterator it; for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) { + LeafBone& leaf = *it; // pointing up float vec[3] = {0.0f, 0.0f, 0.1f}; sub_v3_v3v3(vec, leaf.bone->tail , leaf.bone->head); - mul_v3_fl(vec, leaf_bone_length); + mul_v3_fl(vec, leaf_length); add_v3_v3v3(leaf.bone->tail, leaf.bone->head , vec); } diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index 80bde1842dd..c6337e27218 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -185,6 +185,9 @@ void DocumentImporter::finish() Main *bmain = CTX_data_main(mContext); // TODO: create a new scene except the selected <visual_scene> - use current blender scene for it Scene *sce = CTX_data_scene(mContext); + unit_converter.calculate_scale(*sce); + + std::vector<Object *> *objects_to_scale = new std::vector<Object *>(); /** TODO Break up and put into 2-pass parsing of DAE */ std::vector<const COLLADAFW::VisualScene *>::iterator it; @@ -221,13 +224,8 @@ void DocumentImporter::finish() // Write nodes to scene const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes(); for (unsigned int i = 0; i < roots.getCount(); i++) { - std::vector<Object *> *objects_done; - objects_done = write_node(roots[i], NULL, sce, NULL, false); - - if (!this->import_settings->import_units) { - // Match incoming scene with current unit settings - bc_match_scale(objects_done, *sce, unit_converter); - } + std::vector<Object *> *objects_done = write_node(roots[i], NULL, sce, NULL, false); + objects_to_scale->insert(objects_to_scale->end(), objects_done->begin(), objects_done->end()); } // update scene @@ -278,6 +276,8 @@ void DocumentImporter::finish() DAG_relations_tag_update(bmain); } + + bc_match_scale(objects_to_scale, unit_converter, !this->import_settings->import_units); } @@ -461,6 +461,7 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA std::string name = node->getName(); std::vector<Object *> *objects_done = new std::vector<Object *>(); + std::vector<Object *> *root_objects = new std::vector<Object *>(); fprintf(stderr, "Writing node id='%s', name='%s'\n", @@ -473,6 +474,7 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA // Here we add the armature "on the fly": par = bc_add_object(sce, OB_ARMATURE, std::string("Armature").c_str()); objects_done->push_back(par); + root_objects->push_back(par); object_map.insert(std::pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), par)); node_map[node->getUniqueId()] = node; } @@ -483,7 +485,7 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA if (parent_node == NULL) { // for skeletons without root node all has been done above. // Skeletons with root node are handled further down. - return objects_done; + return root_objects; } } else { @@ -512,6 +514,9 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA } else { objects_done->push_back(ob); + if (parent_node == NULL) { + root_objects->push_back(ob); + } } ++geom_done; } @@ -522,19 +527,29 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA std::string name = node->getName(); fprintf(stderr, "<node id=\"%s\", name=\"%s\" >...contains a reference to an unknown instance_camera.\n", id.c_str(), name.c_str()); } - else + else { objects_done->push_back(ob); + if (parent_node == NULL) { + root_objects->push_back(ob); + } + } ++camera_done; } while (lamp_done < lamp.getCount()) { ob = create_lamp_object(lamp[lamp_done], sce); objects_done->push_back(ob); + if (parent_node == NULL) { + root_objects->push_back(ob); + } ++lamp_done; } while (controller_done < controller.getCount()) { COLLADAFW::InstanceGeometry *geom = (COLLADAFW::InstanceGeometry *)controller[controller_done]; ob = mesh_importer.create_mesh_object(node, geom, true, uid_material_map, material_texture_mapping_map); objects_done->push_back(ob); + if (parent_node == NULL) { + root_objects->push_back(ob); + } ++controller_done; } // XXX instance_node is not supported yet @@ -550,9 +565,12 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA Object *source_ob = (Object *)it2->second; COLLADAFW::Node *source_node = node_map[node_id]; ob = create_instance_node(source_ob, source_node, node, sce, is_library_node); + objects_done->push_back(ob); + if (parent_node == NULL) { + root_objects->push_back(ob); + } } } - if (ob != NULL) objects_done->push_back(ob); ++inst_done; read_transform = false; @@ -569,12 +587,14 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA ob = bc_add_object(sce, OB_EMPTY, NULL); } objects_done->push_back(ob); - + if (parent_node == NULL) { + root_objects->push_back(ob); + } } // XXX: if there're multiple instances, only one is stored - if (!ob) return objects_done; + if (!ob) return root_objects; for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end(); ++it) { ob = *it; @@ -623,7 +643,7 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA write_node(child_nodes[i], node, sce, ob, is_library_node); } - return objects_done; + return root_objects; } /** When this method is called, the writer must write the entire visual scene. diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp index 1e0f0244072..8aa68ed9d04 100644 --- a/source/blender/collada/MeshImporter.cpp +++ b/source/blender/collada/MeshImporter.cpp @@ -618,13 +618,10 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me) set_poly_indices(mpoly, mloop, loop_index, position_indices, vcount); - for (unsigned int l = 0; l < index_list_array.getCount(); l++) { - int uvset_index = index_list_array[l]->getSetIndex(); - + for (unsigned int uvset_index = 0; uvset_index < index_list_array.getCount(); uvset_index++) { // get mtface by face index and uv set index MLoopUV *mloopuv = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, uvset_index); - - set_face_uv(mloopuv+loop_index, uvs, start_index, *index_list_array[l], vcount); + set_face_uv(mloopuv+loop_index, uvs, start_index, *index_list_array[uvset_index], vcount); } if (mp_has_normals) { diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp index c2770dc3dc5..7ae1750d2ca 100644 --- a/source/blender/collada/SkinInfo.cpp +++ b/source/blender/collada/SkinInfo.cpp @@ -226,8 +226,6 @@ void SkinInfo::link_armature(bContext *C, Object *ob, std::map<COLLADAFW::Unique ArmatureModifierData *amd = (ArmatureModifierData *)md; amd->object = ob_arm; - copy_m4_m4(ob->obmat, bind_shape_matrix); - BKE_object_apply_mat4(ob, ob->obmat, 0, 0); #if 1 bc_set_parent(ob, ob_arm, C); #else @@ -243,6 +241,8 @@ void SkinInfo::link_armature(bContext *C, Object *ob, std::map<COLLADAFW::Unique DAG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); #endif + copy_m4_m4(ob->obmat, bind_shape_matrix); + BKE_object_apply_mat4(ob, ob->obmat, 0, 0); amd->deformflag = ARM_DEF_VGROUP; diff --git a/source/blender/collada/TransformReader.cpp b/source/blender/collada/TransformReader.cpp index 43faa15b4bb..f8f31304d28 100644 --- a/source/blender/collada/TransformReader.cpp +++ b/source/blender/collada/TransformReader.cpp @@ -48,7 +48,9 @@ void TransformReader::get_node_mat(float mat[4][4], COLLADAFW::Node *node, std:: switch (type) { case COLLADAFW::Transformation::MATRIX: - // XXX why does this return and discard all following transformations? + // When matrix AND Trans/Rot/Scale are defined for a node, + // then this is considered as redundant information. + // So if we find a Matrix we use that and return. dae_matrix_to_mat4(tm, mat); return; case COLLADAFW::Transformation::TRANSLATE: diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp index 069419f938b..567ee22b3d6 100644 --- a/source/blender/collada/collada_internal.cpp +++ b/source/blender/collada/collada_internal.cpp @@ -27,7 +27,7 @@ /* COLLADABU_ASSERT, may be able to remove later */ #include "COLLADABUPlatform.h" -#include "collada_internal.h" +#include "collada_utils.h" #include "BLI_linklist.h" @@ -40,7 +40,7 @@ UnitConverter::UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP) rotate_m4(y_up_mat4, 'X', 0.5 * M_PI); unit_m4(z_up_mat4); - + unit_m4(scale_mat4); } void UnitConverter::read_asset(const COLLADAFW::FileInfo *asset) @@ -124,6 +124,48 @@ float(&UnitConverter::get_rotation())[4][4] } } + +float(&UnitConverter::get_scale())[4][4] +{ + return scale_mat4; +} + +void UnitConverter::calculate_scale(Scene &sce) +{ + PointerRNA scene_ptr, unit_settings; + PropertyRNA *system_ptr, *scale_ptr; + RNA_id_pointer_create(&sce.id, &scene_ptr); + + unit_settings = RNA_pointer_get(&scene_ptr, "unit_settings"); + system_ptr = RNA_struct_find_property(&unit_settings, "system"); + scale_ptr = RNA_struct_find_property(&unit_settings, "scale_length"); + + int type = RNA_property_enum_get(&unit_settings, system_ptr); + + float bl_scale; + + switch (type) { + case USER_UNIT_NONE: + bl_scale = 1.0; // map 1 Blender unit to 1 Meter + break; + + case USER_UNIT_METRIC: + bl_scale = RNA_property_float_get(&unit_settings, scale_ptr); + break; + + default : + bl_scale = RNA_property_float_get(&unit_settings, scale_ptr); + // it looks like the conversion to Imperial is done implicitly. + // So nothing to do here. + break; + } + + float rescale[3]; + rescale[0] = rescale[1] = rescale[2] = getLinearMeter() / bl_scale; + + size_to_mat4(scale_mat4, rescale); +} + void TransformBase::decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size) { mat4_to_size(size, mat); diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h index 2e855764f4b..4aa637a6876 100644 --- a/source/blender/collada/collada_internal.h +++ b/source/blender/collada/collada_internal.h @@ -50,7 +50,8 @@ private: float x_up_mat4[4][4]; float y_up_mat4[4][4]; float z_up_mat4[4][4]; - + float scale_mat4[4][4]; + public: enum UnitSystem { @@ -79,7 +80,8 @@ public: void mat4_to_dae_double(double out[4][4], float in[4][4]); float(&get_rotation())[4][4]; - + float(&get_scale())[4][4]; + void calculate_scale(Scene &sce); }; diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index d4196bacf0d..3e17472e9c2 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -324,65 +324,30 @@ std::string bc_replace_string(std::string data, const std::string& pattern, * Calculate a rescale factor such that the imported scene's scale * is preserved. I.e. 1 meter in the import will also be * 1 meter in the current scene. - * XXX : I am not sure if it is correct to map 1 Blender Unit - * to 1 Meter for unit type NONE. But it looks reasonable to me. */ -void bc_match_scale(std::vector<Object *> *objects_done, - Scene &sce, - UnitConverter &bc_unit) -{ - Object *ob = NULL; - - PointerRNA scene_ptr, unit_settings; - PropertyRNA *system_ptr, *scale_ptr; - RNA_id_pointer_create(&sce.id, &scene_ptr); - - unit_settings = RNA_pointer_get(&scene_ptr, "unit_settings"); - system_ptr = RNA_struct_find_property(&unit_settings, "system"); - scale_ptr = RNA_struct_find_property(&unit_settings, "scale_length"); - - int type = RNA_property_enum_get(&unit_settings, system_ptr); - float bl_scale; - - switch (type) { - case USER_UNIT_NONE: - bl_scale = 1.0; // map 1 Blender unit to 1 Meter - break; - - case USER_UNIT_METRIC: - bl_scale = RNA_property_float_get(&unit_settings, scale_ptr); - break; - - default : - bl_scale = RNA_property_float_get(&unit_settings, scale_ptr); - // it looks like the conversion to Imperial is done implicitly. - // So nothing to do here. - break; +void bc_match_scale(Object *ob, UnitConverter &bc_unit, bool scale_to_scene) +{ + if (scale_to_scene) { + mul_m4_m4m4(ob->obmat, bc_unit.get_scale(), ob->obmat); } - - float scale_conv = bc_unit.getLinearMeter() / bl_scale; - - float rescale[3]; - rescale[0] = rescale[1] = rescale[2] = scale_conv; - - float size_mat4[4][4]; - - float axis_mat4[4][4]; - unit_m4(axis_mat4); - - size_to_mat4(size_mat4, rescale); + mul_m4_m4m4(ob->obmat, bc_unit.get_rotation(), ob->obmat); + BKE_object_apply_mat4(ob, ob->obmat, 0, 0); +} +void bc_match_scale(std::vector<Object *> *objects_done, + UnitConverter &bc_unit, + bool scale_to_scene) +{ for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end(); ++it) { - ob = *it; - mul_m4_m4m4(ob->obmat, size_mat4, ob->obmat); - mul_m4_m4m4(ob->obmat, bc_unit.get_rotation(), ob->obmat); - BKE_object_apply_mat4(ob, ob->obmat, 0, 0); + Object *ob = *it; + if (ob -> parent == NULL) { + bc_match_scale(*it, bc_unit, scale_to_scene); + } } - } void bc_triangulate_mesh(Mesh *me) diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h index f8e6f09e498..4bc2f55cf33 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -83,7 +83,8 @@ extern int bc_get_active_UVLayer(Object *ob); extern std::string bc_replace_string(std::string data, const std::string& pattern, const std::string& replacement); extern std::string bc_url_encode(std::string data); -extern void bc_match_scale(std::vector<Object *> *objects_done, Scene &sce, UnitConverter &unit_converter); +extern void bc_match_scale(Object *ob, UnitConverter &bc_unit, bool scale_to_scene); +extern void bc_match_scale(std::vector<Object *> *objects_done, UnitConverter &unit_converter, bool scale_to_scene); extern void bc_triangulate_mesh(Mesh *me); diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index b3ec7c78808..c1b99274bed 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -425,14 +425,12 @@ set(SRC operations/COM_CompositorOperation.cpp operations/COM_OutputFileOperation.h operations/COM_OutputFileOperation.cpp - operations/COM_ViewerBaseOperation.h - operations/COM_ViewerBaseOperation.cpp operations/COM_ViewerOperation.h operations/COM_ViewerOperation.cpp operations/COM_PreviewOperation.h operations/COM_PreviewOperation.cpp - operations/COM_SplitViewerOperation.h - operations/COM_SplitViewerOperation.cpp + operations/COM_SplitOperation.h + operations/COM_SplitOperation.cpp operations/COM_ConvertValueToColorProg.h operations/COM_ConvertValueToColorProg.cpp operations/COM_ConvertColorToValueProg.h diff --git a/source/blender/compositor/COM_compositor.h b/source/blender/compositor/COM_compositor.h index fc546188816..204c3237e65 100644 --- a/source/blender/compositor/COM_compositor.h +++ b/source/blender/compositor/COM_compositor.h @@ -107,7 +107,7 @@ extern "C" { * - [@ref ChunkExecutionState.COM_ES_EXECUTED]: Chunk is finished * * @see ExecutionGroup.execute - * @see ViewerBaseOperation.getChunkOrder + * @see ViewerOperation.getChunkOrder * @see OrderOfChunks * * @section interest Area of interest diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp index 51eaffaa31c..827b93c350e 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp @@ -248,7 +248,7 @@ void ExecutionGroup::execute(ExecutionSystem *graph) OrderOfChunks chunkorder = COM_ORDER_OF_CHUNKS_DEFAULT; if (operation->isViewerOperation()) { - ViewerBaseOperation *viewer = (ViewerBaseOperation *)operation; + ViewerOperation *viewer = (ViewerOperation *)operation; centerX = viewer->getCenterX(); centerY = viewer->getCenterY(); chunkorder = viewer->getChunkOrder(); diff --git a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp index 9f0a943c8a2..9024cd33745 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp @@ -36,7 +36,7 @@ #include "COM_GroupNode.h" #include "COM_WriteBufferOperation.h" #include "COM_ReadBufferOperation.h" -#include "COM_ViewerBaseOperation.h" +#include "COM_ViewerOperation.h" extern "C" { #include "BKE_node.h" @@ -212,7 +212,7 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system) printf("|"); } if (operation->isViewerOperation()) { - ViewerBaseOperation *viewer = (ViewerBaseOperation *)operation; + ViewerOperation *viewer = (ViewerOperation *)operation; if (viewer->isActiveViewerOutput()) { printf("Active viewer"); } diff --git a/source/blender/compositor/intern/COM_SocketReader.h b/source/blender/compositor/intern/COM_SocketReader.h index 88b018ef8ba..b7aae8b92f0 100644 --- a/source/blender/compositor/intern/COM_SocketReader.h +++ b/source/blender/compositor/intern/COM_SocketReader.h @@ -91,13 +91,13 @@ protected: virtual void executePixel(float output[4], float x, float y, float dx, float dy, PixelSampler sampler) {} public: - inline void read(float *result, float x, float y, PixelSampler sampler) { + inline void read(float result[4], float x, float y, PixelSampler sampler) { executePixel(result, x, y, sampler); } - inline void read(float *result, int x, int y, void *chunkData) { + inline void read(float result[4], int x, int y, void *chunkData) { executePixel(result, x, y, chunkData); } - inline void read(float *result, float x, float y, float dx, float dy, PixelSampler sampler) { + inline void read(float result[4], float x, float y, float dx, float dy, PixelSampler sampler) { executePixel(result, x, y, dx, dy, sampler); } diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp index e0ac767b628..1bac06fc4ab 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.cpp +++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp @@ -81,6 +81,7 @@ int g_highlightIndex; void **g_highlightedNodes; void **g_highlightedNodesRead; +#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE #define HIGHLIGHT(wp) \ { \ ExecutionGroup *group = wp->getExecutionGroup(); \ @@ -103,6 +104,7 @@ void **g_highlightedNodesRead; } \ } \ } +#endif /* COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE */ void COM_startReadHighlights() { diff --git a/source/blender/compositor/nodes/COM_RenderLayersNode.cpp b/source/blender/compositor/nodes/COM_RenderLayersNode.cpp index 5259fbc7dc5..74e557c77ce 100644 --- a/source/blender/compositor/nodes/COM_RenderLayersNode.cpp +++ b/source/blender/compositor/nodes/COM_RenderLayersNode.cpp @@ -114,4 +114,7 @@ void RenderLayersNode::convertToOperations(ExecutionSystem *graph, CompositorCon testSocketConnection(graph, context, 25, new RenderLayersCyclesOperation(SCE_PASS_TRANSM_DIRECT)); testSocketConnection(graph, context, 26, new RenderLayersCyclesOperation(SCE_PASS_TRANSM_INDIRECT)); testSocketConnection(graph, context, 27, new RenderLayersCyclesOperation(SCE_PASS_TRANSM_COLOR)); + testSocketConnection(graph, context, 28, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_DIRECT)); + testSocketConnection(graph, context, 29, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_INDIRECT)); + testSocketConnection(graph, context, 30, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_COLOR)); } diff --git a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp index 0293f4926db..81c0744564f 100644 --- a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp +++ b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp @@ -23,7 +23,8 @@ #include "COM_SplitViewerNode.h" #include "BKE_global.h" -#include "COM_SplitViewerOperation.h" +#include "COM_SplitOperation.h" +#include "COM_ViewerOperation.h" #include "COM_ExecutionSystem.h" SplitViewerNode::SplitViewerNode(bNode *editorNode) : Node(editorNode) @@ -42,29 +43,31 @@ void SplitViewerNode::convertToOperations(ExecutionSystem *graph, CompositorCont InputSocket *image2Socket = this->getInputSocket(1); Image *image = (Image *)this->getbNode()->id; ImageUser *imageUser = (ImageUser *) this->getbNode()->storage; - if (image1Socket->isConnected() && image2Socket->isConnected()) { - SplitViewerOperation *splitViewerOperation = new SplitViewerOperation(); - splitViewerOperation->setImage(image); - splitViewerOperation->setImageUser(imageUser); - splitViewerOperation->setActive(is_active); - splitViewerOperation->setSplitPercentage(this->getbNode()->custom1); - splitViewerOperation->setViewSettings(context->getViewSettings()); - splitViewerOperation->setDisplaySettings(context->getDisplaySettings()); + SplitOperation *splitViewerOperation = new SplitOperation(); + splitViewerOperation->setSplitPercentage(this->getbNode()->custom1); + splitViewerOperation->setXSplit(!this->getbNode()->custom2); - /* defaults - the viewer node has these options but not exposed for split view - * we could use the split to define an area of interest on one axis at least */ - splitViewerOperation->setChunkOrder(COM_ORDER_OF_CHUNKS_DEFAULT); - splitViewerOperation->setCenterX(0.5f); - splitViewerOperation->setCenterY(0.5f); + image1Socket->relinkConnections(splitViewerOperation->getInputSocket(0), 0, graph); + image2Socket->relinkConnections(splitViewerOperation->getInputSocket(1), 1, graph); - splitViewerOperation->setXSplit(!this->getbNode()->custom2); - image1Socket->relinkConnections(splitViewerOperation->getInputSocket(0), 0, graph); - image2Socket->relinkConnections(splitViewerOperation->getInputSocket(1), 1, graph); + ViewerOperation *viewerOperation = new ViewerOperation(); + viewerOperation->setImage(image); + viewerOperation->setImageUser(imageUser); + viewerOperation->setActive(is_active); + viewerOperation->setViewSettings(context->getViewSettings()); + viewerOperation->setDisplaySettings(context->getDisplaySettings()); - if (is_active) - addPreviewOperation(graph, context, splitViewerOperation->getInputSocket(0)); + /* defaults - the viewer node has these options but not exposed for split view + * we could use the split to define an area of interest on one axis at least */ + viewerOperation->setChunkOrder(COM_ORDER_OF_CHUNKS_DEFAULT); + viewerOperation->setCenterX(0.5f); + viewerOperation->setCenterY(0.5f); - graph->addOperation(splitViewerOperation); - } + addLink(graph, splitViewerOperation->getOutputSocket(), viewerOperation->getInputSocket(0)); + + addPreviewOperation(graph, context, viewerOperation->getInputSocket(0)); + + graph->addOperation(splitViewerOperation); + graph->addOperation(viewerOperation); } diff --git a/source/blender/compositor/operations/COM_ConvertColorToBWOperation.cpp b/source/blender/compositor/operations/COM_ConvertColorToBWOperation.cpp index 9cff5e8eaa6..3b5aa8cd755 100644 --- a/source/blender/compositor/operations/COM_ConvertColorToBWOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertColorToBWOperation.cpp @@ -37,7 +37,7 @@ void ConvertColorToBWOperation::initExecution() void ConvertColorToBWOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) { float inputColor[4]; - this->m_inputOperation->read(&inputColor[0], x, y, sampler); + this->m_inputOperation->read(inputColor, x, y, sampler); output[0] = rgb_to_bw(inputColor); } diff --git a/source/blender/compositor/operations/COM_ConvertColorToValueProg.cpp b/source/blender/compositor/operations/COM_ConvertColorToValueProg.cpp index 3a65519864a..44e751d1cae 100644 --- a/source/blender/compositor/operations/COM_ConvertColorToValueProg.cpp +++ b/source/blender/compositor/operations/COM_ConvertColorToValueProg.cpp @@ -37,7 +37,7 @@ void ConvertColorToValueProg::initExecution() void ConvertColorToValueProg::executePixel(float output[4], float x, float y, PixelSampler sampler) { float inputColor[4]; - this->m_inputOperation->read(&inputColor[0], x, y, sampler); + this->m_inputOperation->read(inputColor, x, y, sampler); output[0] = (inputColor[0] + inputColor[1] + inputColor[2]) / 3.0f; } diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.cpp b/source/blender/compositor/operations/COM_MathBaseOperation.cpp index 3749bcf42d8..fa0c480eb70 100644 --- a/source/blender/compositor/operations/COM_MathBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_MathBaseOperation.cpp @@ -77,8 +77,8 @@ void MathAddOperation::executePixel(float output[4], float x, float y, PixelSamp float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler); - this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler); + this->m_inputValue1Operation->read(inputValue1, x, y, sampler); + this->m_inputValue2Operation->read(inputValue2, x, y, sampler); output[0] = inputValue1[0] + inputValue2[0]; @@ -90,8 +90,8 @@ void MathSubtractOperation::executePixel(float output[4], float x, float y, Pixe float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler); - this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler); + this->m_inputValue1Operation->read(inputValue1, x, y, sampler); + this->m_inputValue2Operation->read(inputValue2, x, y, sampler); output[0] = inputValue1[0] - inputValue2[0]; @@ -103,8 +103,8 @@ void MathMultiplyOperation::executePixel(float output[4], float x, float y, Pixe float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler); - this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler); + this->m_inputValue1Operation->read(inputValue1, x, y, sampler); + this->m_inputValue2Operation->read(inputValue2, x, y, sampler); output[0] = inputValue1[0] * inputValue2[0]; @@ -116,8 +116,8 @@ void MathDivideOperation::executePixel(float output[4], float x, float y, PixelS float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler); - this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler); + this->m_inputValue1Operation->read(inputValue1, x, y, sampler); + this->m_inputValue2Operation->read(inputValue2, x, y, sampler); if (inputValue2[0] == 0) /* We don't want to divide by zero. */ output[0] = 0.0; @@ -132,8 +132,8 @@ void MathSineOperation::executePixel(float output[4], float x, float y, PixelSam float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler); - this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler); + this->m_inputValue1Operation->read(inputValue1, x, y, sampler); + this->m_inputValue2Operation->read(inputValue2, x, y, sampler); output[0] = sin(inputValue1[0]); @@ -145,8 +145,8 @@ void MathCosineOperation::executePixel(float output[4], float x, float y, PixelS float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler); - this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler); + this->m_inputValue1Operation->read(inputValue1, x, y, sampler); + this->m_inputValue2Operation->read(inputValue2, x, y, sampler); output[0] = cos(inputValue1[0]); @@ -158,8 +158,8 @@ void MathTangentOperation::executePixel(float output[4], float x, float y, Pixel float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler); - this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler); + this->m_inputValue1Operation->read(inputValue1, x, y, sampler); + this->m_inputValue2Operation->read(inputValue2, x, y, sampler); output[0] = tan(inputValue1[0]); @@ -171,8 +171,8 @@ void MathArcSineOperation::executePixel(float output[4], float x, float y, Pixel float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler); - this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler); + this->m_inputValue1Operation->read(inputValue1, x, y, sampler); + this->m_inputValue2Operation->read(inputValue2, x, y, sampler); if (inputValue1[0] <= 1 && inputValue1[0] >= -1) output[0] = asin(inputValue1[0]); @@ -187,8 +187,8 @@ void MathArcCosineOperation::executePixel(float output[4], float x, float y, Pix float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler); - this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler); + this->m_inputValue1Operation->read(inputValue1, x, y, sampler); + this->m_inputValue2Operation->read(inputValue2, x, y, sampler); if (inputValue1[0] <= 1 && inputValue1[0] >= -1) output[0] = acos(inputValue1[0]); @@ -203,8 +203,8 @@ void MathArcTangentOperation::executePixel(float output[4], float x, float y, Pi float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler); - this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler); + this->m_inputValue1Operation->read(inputValue1, x, y, sampler); + this->m_inputValue2Operation->read(inputValue2, x, y, sampler); output[0] = atan(inputValue1[0]); @@ -216,8 +216,8 @@ void MathPowerOperation::executePixel(float output[4], float x, float y, PixelSa float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler); - this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler); + this->m_inputValue1Operation->read(inputValue1, x, y, sampler); + this->m_inputValue2Operation->read(inputValue2, x, y, sampler); if (inputValue1[0] >= 0) { output[0] = pow(inputValue1[0], inputValue2[0]); @@ -241,8 +241,8 @@ void MathLogarithmOperation::executePixel(float output[4], float x, float y, Pix float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler); - this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler); + this->m_inputValue1Operation->read(inputValue1, x, y, sampler); + this->m_inputValue2Operation->read(inputValue2, x, y, sampler); if (inputValue1[0] > 0 && inputValue2[0] > 0) output[0] = log(inputValue1[0]) / log(inputValue2[0]); @@ -257,8 +257,8 @@ void MathMinimumOperation::executePixel(float output[4], float x, float y, Pixel float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler); - this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler); + this->m_inputValue1Operation->read(inputValue1, x, y, sampler); + this->m_inputValue2Operation->read(inputValue2, x, y, sampler); output[0] = min(inputValue1[0], inputValue2[0]); @@ -270,8 +270,8 @@ void MathMaximumOperation::executePixel(float output[4], float x, float y, Pixel float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler); - this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler); + this->m_inputValue1Operation->read(inputValue1, x, y, sampler); + this->m_inputValue2Operation->read(inputValue2, x, y, sampler); output[0] = max(inputValue1[0], inputValue2[0]); @@ -283,8 +283,8 @@ void MathRoundOperation::executePixel(float output[4], float x, float y, PixelSa float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler); - this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler); + this->m_inputValue1Operation->read(inputValue1, x, y, sampler); + this->m_inputValue2Operation->read(inputValue2, x, y, sampler); output[0] = round(inputValue1[0]); @@ -296,8 +296,8 @@ void MathLessThanOperation::executePixel(float output[4], float x, float y, Pixe float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler); - this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler); + this->m_inputValue1Operation->read(inputValue1, x, y, sampler); + this->m_inputValue2Operation->read(inputValue2, x, y, sampler); output[0] = inputValue1[0] < inputValue2[0] ? 1.0f : 0.0f; @@ -309,8 +309,8 @@ void MathGreaterThanOperation::executePixel(float output[4], float x, float y, P float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler); - this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler); + this->m_inputValue1Operation->read(inputValue1, x, y, sampler); + this->m_inputValue2Operation->read(inputValue2, x, y, sampler); output[0] = inputValue1[0] > inputValue2[0] ? 1.0f : 0.0f; @@ -322,8 +322,8 @@ void MathModuloOperation::executePixel(float output[4], float x, float y, PixelS float inputValue1[4]; float inputValue2[4]; - this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler); - this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler); + this->m_inputValue1Operation->read(inputValue1, x, y, sampler); + this->m_inputValue2Operation->read(inputValue2, x, y, sampler); if (inputValue2[0] == 0) output[0] = 0.0; diff --git a/source/blender/compositor/operations/COM_MixAddOperation.cpp b/source/blender/compositor/operations/COM_MixAddOperation.cpp index be737f22280..4e0876439c0 100644 --- a/source/blender/compositor/operations/COM_MixAddOperation.cpp +++ b/source/blender/compositor/operations/COM_MixAddOperation.cpp @@ -37,7 +37,6 @@ void MixAddOperation::executePixel(float output[4], float x, float y, PixelSampl this->m_inputColor1Operation->read(inputColor1, x, y, sampler); this->m_inputColor2Operation->read(inputColor2, x, y, sampler); - float value = inputValue[0]; if (this->useValueAlphaMultiply()) { value *= inputColor2[3]; diff --git a/source/blender/compositor/operations/COM_MixBurnOperation.cpp b/source/blender/compositor/operations/COM_MixBurnOperation.cpp index 5cfe38766bc..d4422c6cc6a 100644 --- a/source/blender/compositor/operations/COM_MixBurnOperation.cpp +++ b/source/blender/compositor/operations/COM_MixBurnOperation.cpp @@ -31,13 +31,14 @@ void MixBurnOperation::executePixel(float output[4], float x, float y, PixelSamp { float inputColor1[4]; float inputColor2[4]; - float value; + float inputValue[4]; float tmp; - this->m_inputValueOperation->read(&value, x, y, sampler); - this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler); - this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler); + this->m_inputValueOperation->read(inputValue, x, y, sampler); + this->m_inputColor1Operation->read(inputColor1, x, y, sampler); + this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + float value = inputValue[0]; if (this->useValueAlphaMultiply()) { value *= inputColor2[3]; } diff --git a/source/blender/compositor/operations/COM_MixColorOperation.cpp b/source/blender/compositor/operations/COM_MixColorOperation.cpp index 56aca27eaef..6919a636aeb 100644 --- a/source/blender/compositor/operations/COM_MixColorOperation.cpp +++ b/source/blender/compositor/operations/COM_MixColorOperation.cpp @@ -35,12 +35,13 @@ void MixColorOperation::executePixel(float output[4], float x, float y, PixelSam { float inputColor1[4]; float inputColor2[4]; - float value; + float inputValue[4]; - this->m_inputValueOperation->read(&value, x, y, sampler); - this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler); - this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler); + this->m_inputValueOperation->read(inputValue, x, y, sampler); + this->m_inputColor1Operation->read(inputColor1, x, y, sampler); + this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + float value = inputValue[0]; if (this->useValueAlphaMultiply()) { value *= inputColor2[3]; } diff --git a/source/blender/compositor/operations/COM_MixDarkenOperation.cpp b/source/blender/compositor/operations/COM_MixDarkenOperation.cpp index 5b79f4c95ac..d56d9fdf122 100644 --- a/source/blender/compositor/operations/COM_MixDarkenOperation.cpp +++ b/source/blender/compositor/operations/COM_MixDarkenOperation.cpp @@ -31,12 +31,13 @@ void MixDarkenOperation::executePixel(float output[4], float x, float y, PixelSa { float inputColor1[4]; float inputColor2[4]; - float value; + float inputValue[4]; - this->m_inputValueOperation->read(&value, x, y, sampler); - this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler); - this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler); + this->m_inputValueOperation->read(inputValue, x, y, sampler); + this->m_inputColor1Operation->read(inputColor1, x, y, sampler); + this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + float value = inputValue[0]; if (this->useValueAlphaMultiply()) { value *= inputColor2[3]; } diff --git a/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp b/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp index d2c1e5e428f..13494401c60 100644 --- a/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp +++ b/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp @@ -32,12 +32,13 @@ void MixDifferenceOperation::executePixel(float output[4], float x, float y, Pix { float inputColor1[4]; float inputColor2[4]; - float value; - - this->m_inputValueOperation->read(&value, x, y, sampler); - this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler); - this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler); + float inputValue[4]; + this->m_inputValueOperation->read(inputValue, x, y, sampler); + this->m_inputColor1Operation->read(inputColor1, x, y, sampler); + this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + + float value = inputValue[0]; if (this->useValueAlphaMultiply()) { value *= inputColor2[3]; } diff --git a/source/blender/compositor/operations/COM_MixDivideOperation.cpp b/source/blender/compositor/operations/COM_MixDivideOperation.cpp index fdb1618b6e6..3e0eb66565c 100644 --- a/source/blender/compositor/operations/COM_MixDivideOperation.cpp +++ b/source/blender/compositor/operations/COM_MixDivideOperation.cpp @@ -31,12 +31,13 @@ void MixDivideOperation::executePixel(float output[4], float x, float y, PixelSa { float inputColor1[4]; float inputColor2[4]; - float value; - - this->m_inputValueOperation->read(&value, x, y, sampler); - this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler); - this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler); + float inputValue[4]; + this->m_inputValueOperation->read(inputValue, x, y, sampler); + this->m_inputColor1Operation->read(inputColor1, x, y, sampler); + this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + + float value = inputValue[0]; if (this->useValueAlphaMultiply()) { value *= inputColor2[3]; } diff --git a/source/blender/compositor/operations/COM_MixDodgeOperation.cpp b/source/blender/compositor/operations/COM_MixDodgeOperation.cpp index 87f60df8e1b..acb39f665ff 100644 --- a/source/blender/compositor/operations/COM_MixDodgeOperation.cpp +++ b/source/blender/compositor/operations/COM_MixDodgeOperation.cpp @@ -31,13 +31,14 @@ void MixDodgeOperation::executePixel(float output[4], float x, float y, PixelSam { float inputColor1[4]; float inputColor2[4]; - float value; + float inputValue[4]; float tmp; - this->m_inputValueOperation->read(&value, x, y, sampler); - this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler); - this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler); + this->m_inputValueOperation->read(inputValue, x, y, sampler); + this->m_inputColor1Operation->read(inputColor1, x, y, sampler); + this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + float value = inputValue[0]; if (this->useValueAlphaMultiply()) { value *= inputColor2[3]; } diff --git a/source/blender/compositor/operations/COM_MixHueOperation.cpp b/source/blender/compositor/operations/COM_MixHueOperation.cpp index 12cd16bb73b..64c88592b93 100644 --- a/source/blender/compositor/operations/COM_MixHueOperation.cpp +++ b/source/blender/compositor/operations/COM_MixHueOperation.cpp @@ -35,12 +35,13 @@ void MixHueOperation::executePixel(float output[4], float x, float y, PixelSampl { float inputColor1[4]; float inputColor2[4]; - float value; + float inputValue[4]; - this->m_inputValueOperation->read(&value, x, y, sampler); - this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler); - this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler); + this->m_inputValueOperation->read(inputValue, x, y, sampler); + this->m_inputColor1Operation->read(inputColor1, x, y, sampler); + this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + float value = inputValue[0]; if (this->useValueAlphaMultiply()) { value *= inputColor2[3]; } diff --git a/source/blender/compositor/operations/COM_MixLightenOperation.cpp b/source/blender/compositor/operations/COM_MixLightenOperation.cpp index 9eb45a783f8..a468fb39442 100644 --- a/source/blender/compositor/operations/COM_MixLightenOperation.cpp +++ b/source/blender/compositor/operations/COM_MixLightenOperation.cpp @@ -31,12 +31,13 @@ void MixLightenOperation::executePixel(float output[4], float x, float y, PixelS { float inputColor1[4]; float inputColor2[4]; - float value; - - this->m_inputValueOperation->read(&value, x, y, sampler); - this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler); - this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler); + float inputValue[4]; + this->m_inputValueOperation->read(inputValue, x, y, sampler); + this->m_inputColor1Operation->read(inputColor1, x, y, sampler); + this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + + float value = inputValue[0]; if (this->useValueAlphaMultiply()) { value *= inputColor2[3]; } diff --git a/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp b/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp index ee7dcc9fe28..e1b5e040f0f 100644 --- a/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp +++ b/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp @@ -31,12 +31,13 @@ void MixLinearLightOperation::executePixel(float output[4], float x, float y, Pi { float inputColor1[4]; float inputColor2[4]; - float value; - - this->m_inputValueOperation->read(&value, x, y, sampler); - this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler); - this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler); - + float inputValue[4]; + + this->m_inputValueOperation->read(inputValue, x, y, sampler); + this->m_inputColor1Operation->read(inputColor1, x, y, sampler); + this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + + float value = inputValue[0]; if (this->useValueAlphaMultiply()) { value *= inputColor2[3]; } diff --git a/source/blender/compositor/operations/COM_MixOverlayOperation.cpp b/source/blender/compositor/operations/COM_MixOverlayOperation.cpp index 09a9d3cbc4f..d5e1c6d1167 100644 --- a/source/blender/compositor/operations/COM_MixOverlayOperation.cpp +++ b/source/blender/compositor/operations/COM_MixOverlayOperation.cpp @@ -31,12 +31,13 @@ void MixOverlayOperation::executePixel(float output[4], float x, float y, PixelS { float inputColor1[4]; float inputColor2[4]; - float value; + float inputValue[4]; - this->m_inputValueOperation->read(&value, x, y, sampler); - this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler); - this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler); + this->m_inputValueOperation->read(inputValue, x, y, sampler); + this->m_inputColor1Operation->read(inputColor1, x, y, sampler); + this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + float value = inputValue[0]; if (this->useValueAlphaMultiply()) { value *= inputColor2[3]; } diff --git a/source/blender/compositor/operations/COM_MixSaturationOperation.cpp b/source/blender/compositor/operations/COM_MixSaturationOperation.cpp index 3ab19748458..ca45a1c703a 100644 --- a/source/blender/compositor/operations/COM_MixSaturationOperation.cpp +++ b/source/blender/compositor/operations/COM_MixSaturationOperation.cpp @@ -35,12 +35,13 @@ void MixSaturationOperation::executePixel(float output[4], float x, float y, Pix { float inputColor1[4]; float inputColor2[4]; - float value; + float inputValue[4]; - this->m_inputValueOperation->read(&value, x, y, sampler); - this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler); - this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler); + this->m_inputValueOperation->read(inputValue, x, y, sampler); + this->m_inputColor1Operation->read(inputColor1, x, y, sampler); + this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + float value = inputValue[0]; if (this->useValueAlphaMultiply()) { value *= inputColor2[3]; } diff --git a/source/blender/compositor/operations/COM_MixScreenOperation.cpp b/source/blender/compositor/operations/COM_MixScreenOperation.cpp index 671ffd3303c..511768a49ad 100644 --- a/source/blender/compositor/operations/COM_MixScreenOperation.cpp +++ b/source/blender/compositor/operations/COM_MixScreenOperation.cpp @@ -31,13 +31,13 @@ void MixScreenOperation::executePixel(float output[4], float x, float y, PixelSa { float inputColor1[4]; float inputColor2[4]; - float valuev[4]; + float inputValue[4]; - this->m_inputValueOperation->read(valuev, x, y, sampler); - this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler); - this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler); + this->m_inputValueOperation->read(inputValue, x, y, sampler); + this->m_inputColor1Operation->read(inputColor1, x, y, sampler); + this->m_inputColor2Operation->read(inputColor2, x, y, sampler); - float value = valuev[0]; + float value = inputValue[0]; if (this->useValueAlphaMultiply()) { value *= inputColor2[3]; } diff --git a/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp b/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp index 604881ae47f..71d83ce54ea 100644 --- a/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp +++ b/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp @@ -31,12 +31,13 @@ void MixSoftLightOperation::executePixel(float output[4], float x, float y, Pixe { float inputColor1[4]; float inputColor2[4]; - float value; + float inputValue[4]; - this->m_inputValueOperation->read(&value, x, y, sampler); - this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler); - this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler); + this->m_inputValueOperation->read(inputValue, x, y, sampler); + this->m_inputColor1Operation->read(inputColor1, x, y, sampler); + this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + float value = inputValue[0]; if (this->useValueAlphaMultiply()) { value *= inputColor2[3]; } diff --git a/source/blender/compositor/operations/COM_MixSubtractOperation.cpp b/source/blender/compositor/operations/COM_MixSubtractOperation.cpp index a446dfe4e54..e6efe0f62f3 100644 --- a/source/blender/compositor/operations/COM_MixSubtractOperation.cpp +++ b/source/blender/compositor/operations/COM_MixSubtractOperation.cpp @@ -31,12 +31,13 @@ void MixSubtractOperation::executePixel(float output[4], float x, float y, Pixel { float inputColor1[4]; float inputColor2[4]; - float value; + float inputValue[4]; - this->m_inputValueOperation->read(&value, x, y, sampler); - this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler); - this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler); + this->m_inputValueOperation->read(inputValue, x, y, sampler); + this->m_inputColor1Operation->read(inputColor1, x, y, sampler); + this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + float value = inputValue[0]; if (this->useValueAlphaMultiply()) { value *= inputColor2[3]; } diff --git a/source/blender/compositor/operations/COM_MixValueOperation.cpp b/source/blender/compositor/operations/COM_MixValueOperation.cpp index caefdf024cc..553041e39bf 100644 --- a/source/blender/compositor/operations/COM_MixValueOperation.cpp +++ b/source/blender/compositor/operations/COM_MixValueOperation.cpp @@ -35,12 +35,13 @@ void MixValueOperation::executePixel(float output[4], float x, float y, PixelSam { float inputColor1[4]; float inputColor2[4]; - float value; + float inputValue[4]; - this->m_inputValueOperation->read(&value, x, y, sampler); - this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler); - this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler); + this->m_inputValueOperation->read(inputValue, x, y, sampler); + this->m_inputColor1Operation->read(inputColor1, x, y, sampler); + this->m_inputColor2Operation->read(inputColor2, x, y, sampler); + float value = inputValue[0]; if (this->useValueAlphaMultiply()) { value *= inputColor2[3]; } diff --git a/source/blender/compositor/operations/COM_SplitViewerOperation.cpp b/source/blender/compositor/operations/COM_SplitOperation.cpp index 7325e32a863..a7dbccfc2f7 100644 --- a/source/blender/compositor/operations/COM_SplitViewerOperation.cpp +++ b/source/blender/compositor/operations/COM_SplitOperation.cpp @@ -20,7 +20,7 @@ * Monique Dewanchand */ -#include "COM_SplitViewerOperation.h" +#include "COM_SplitOperation.h" #include "COM_SocketConnection.h" #include "BLI_listbase.h" #include "BKE_image.h" @@ -35,58 +35,47 @@ extern "C" { } -SplitViewerOperation::SplitViewerOperation() : ViewerBaseOperation() +SplitOperation::SplitOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); this->m_image1Input = NULL; this->m_image2Input = NULL; } -void SplitViewerOperation::initExecution() +void SplitOperation::initExecution() { // When initializing the tree during initial load the width and height can be zero. this->m_image1Input = getInputSocketReader(0); this->m_image2Input = getInputSocketReader(1); - ViewerBaseOperation::initExecution(); } -void SplitViewerOperation::deinitExecution() +void SplitOperation::deinitExecution() { this->m_image1Input = NULL; this->m_image2Input = NULL; - ViewerBaseOperation::deinitExecution(); } - -void SplitViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber) +void SplitOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) { - float *buffer = this->m_outputBuffer; - - if (!buffer) return; - int x1 = rect->xmin; - int y1 = rect->ymin; - int x2 = rect->xmax; - int y2 = rect->ymax; - int offset = (y1 * this->getWidth() + x1) * 4; - int x; - int y; int perc = this->m_xSplit ? this->m_splitPercentage * this->getWidth() / 100.0f : this->m_splitPercentage * this->getHeight() / 100.0f; - for (y = y1; y < y2; y++) { - for (x = x1; x < x2; x++) { - bool image1; - image1 = this->m_xSplit ? x > perc : y > perc; - if (image1) { - this->m_image1Input->read(&(buffer[offset]), x, y, COM_PS_NEAREST); - } - else { - this->m_image2Input->read(&(buffer[offset]), x, y, COM_PS_NEAREST); - } - - offset += 4; - } - offset += (this->getWidth() - (x2 - x1)) * 4; + bool image1 = this->m_xSplit ? x > perc : y > perc; + if (image1) { + this->m_image1Input->read(output, x, y, COM_PS_NEAREST); + } + else { + this->m_image2Input->read(output, x, y, COM_PS_NEAREST); } - updateImage(rect); } +void SplitOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) +{ + unsigned int tempPreferredResolution[2] = {0, 0}; + unsigned int tempResolution[2]; + + this->getInputSocket(0)->determineResolution(tempResolution, tempPreferredResolution); + this->setResolutionInputSocketIndex((tempResolution[0] && tempResolution[1]) ? 0 : 1); + + NodeOperation::determineResolution(resolution, preferredResolution); +} diff --git a/source/blender/compositor/operations/COM_SplitViewerOperation.h b/source/blender/compositor/operations/COM_SplitOperation.h index c759e14e1dd..5a042b789d8 100644 --- a/source/blender/compositor/operations/COM_SplitViewerOperation.h +++ b/source/blender/compositor/operations/COM_SplitOperation.h @@ -20,13 +20,11 @@ * Monique Dewanchand */ -#ifndef _COM_SplitViewerOperation_h -#define _COM_SplitViewerOperation_h -#include "COM_ViewerBaseOperation.h" -#include "DNA_image_types.h" -#include "BLI_rect.h" +#ifndef _COM_SplitOperation_h +#define _COM_SplitOperation_h +#include "COM_NodeOperation.h" -class SplitViewerOperation : public ViewerBaseOperation { +class SplitOperation : public NodeOperation { private: SocketReader *m_image1Input; SocketReader *m_image2Input; @@ -34,10 +32,11 @@ private: float m_splitPercentage; bool m_xSplit; public: - SplitViewerOperation(); - void executeRegion(rcti *rect, unsigned int tileNumber); + SplitOperation(); void initExecution(); void deinitExecution(); + void executePixel(float output[4], float x, float y, PixelSampler sampler); + void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); void setSplitPercentage(float splitPercentage) { this->m_splitPercentage = splitPercentage; } void setXSplit(bool xsplit) { this->m_xSplit = xsplit; } }; diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp deleted file mode 100644 index 072246932db..00000000000 --- a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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. - * - * Contributor: - * Jeroen Bakker - * Monique Dewanchand - */ - -#include "COM_ViewerBaseOperation.h" -#include "COM_SocketConnection.h" -#include "BLI_listbase.h" -#include "BKE_image.h" -#include "WM_api.h" -#include "WM_types.h" -#include "PIL_time.h" -#include "BLI_utildefines.h" -#include "BLI_math_color.h" - -extern "C" { - #include "MEM_guardedalloc.h" - #include "IMB_imbuf.h" - #include "IMB_imbuf_types.h" - #include "IMB_colormanagement.h" -} - - -ViewerBaseOperation::ViewerBaseOperation() : NodeOperation() -{ - this->setImage(NULL); - this->setImageUser(NULL); - this->m_outputBuffer = NULL; - this->m_depthBuffer = NULL; - this->m_active = false; - this->m_doDepthBuffer = false; - this->m_viewSettings = NULL; - this->m_displaySettings = NULL; - this->m_ignoreAlpha = false; -} - -void ViewerBaseOperation::initExecution() -{ - if (isActiveViewerOutput()) { - initImage(); - } -} - -void ViewerBaseOperation::initImage() -{ - Image *anImage = this->m_image; - ImBuf *ibuf = BKE_image_acquire_ibuf(anImage, this->m_imageUser, &this->m_lock); - - if (!ibuf) return; - BLI_lock_thread(LOCK_DRAW_IMAGE); - if (ibuf->x != (int)getWidth() || ibuf->y != (int)getHeight()) { - - imb_freerectImBuf(ibuf); - imb_freerectfloatImBuf(ibuf); - IMB_freezbuffloatImBuf(ibuf); - ibuf->x = getWidth(); - ibuf->y = getHeight(); - imb_addrectfloatImBuf(ibuf); - anImage->ok = IMA_OK_LOADED; - - ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; - - BLI_unlock_thread(LOCK_DRAW_IMAGE); - } - - if (m_doDepthBuffer) { - addzbuffloatImBuf(ibuf); - } - BLI_unlock_thread(LOCK_DRAW_IMAGE); - - /* now we combine the input with ibuf */ - this->m_outputBuffer = ibuf->rect_float; - - /* needed for display buffer update */ - this->m_ibuf = ibuf; - - if (m_doDepthBuffer) { - this->m_depthBuffer = ibuf->zbuf_float; - } - - BKE_image_release_ibuf(this->m_image, this->m_ibuf, this->m_lock); -} - -void ViewerBaseOperation:: updateImage(rcti *rect) -{ - IMB_partial_display_buffer_update(this->m_ibuf, this->m_outputBuffer, NULL, getWidth(), 0, 0, - this->m_viewSettings, this->m_displaySettings, - rect->xmin, rect->ymin, rect->xmax, rect->ymax, FALSE); - - this->updateDraw(); -} - -void ViewerBaseOperation::deinitExecution() -{ - this->m_outputBuffer = NULL; -} - -const CompositorPriority ViewerBaseOperation::getRenderPriority() const -{ - if (this->isActiveViewerOutput()) { - return COM_PRIORITY_HIGH; - } - else { - return COM_PRIORITY_LOW; - } -} diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.h b/source/blender/compositor/operations/COM_ViewerBaseOperation.h deleted file mode 100644 index 7ead96b5c29..00000000000 --- a/source/blender/compositor/operations/COM_ViewerBaseOperation.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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. - * - * Contributor: - * Jeroen Bakker - * Monique Dewanchand - */ - -#ifndef _COM_ViewerBaseOperation_h -#define _COM_ViewerBaseOperation_h -#include "COM_NodeOperation.h" -#include "DNA_image_types.h" -#include "BLI_rect.h" -#include "BKE_global.h" - -class ViewerBaseOperation : public NodeOperation { -protected: - float *m_outputBuffer; - float *m_depthBuffer; - Image *m_image; - ImageUser *m_imageUser; - void *m_lock; - bool m_active; - float m_centerX; - float m_centerY; - OrderOfChunks m_chunkOrder; - bool m_doDepthBuffer; - ImBuf *m_ibuf; - bool m_ignoreAlpha; - - const ColorManagedViewSettings *m_viewSettings; - const ColorManagedDisplaySettings *m_displaySettings; - -public: - bool isOutputOperation(bool rendering) const { if (G.background) return false; return isActiveViewerOutput(); } - void initExecution(); - void deinitExecution(); - void setImage(Image *image) { this->m_image = image; } - void setImageUser(ImageUser *imageUser) { this->m_imageUser = imageUser; } - const bool isActiveViewerOutput() const { return this->m_active; } - void setActive(bool active) { this->m_active = active; } - void setCenterX(float centerX) { this->m_centerX = centerX;} - void setCenterY(float centerY) { this->m_centerY = centerY;} - void setChunkOrder(OrderOfChunks tileOrder) { this->m_chunkOrder = tileOrder; } - float getCenterX() { return this->m_centerX; } - float getCenterY() { return this->m_centerY; } - OrderOfChunks getChunkOrder() { return this->m_chunkOrder; } - const CompositorPriority getRenderPriority() const; - bool isViewerOperation() { return true; } - void setIgnoreAlpha(bool value) { this->m_ignoreAlpha = value; } - - void setViewSettings(const ColorManagedViewSettings *viewSettings) { this->m_viewSettings = viewSettings; } - void setDisplaySettings(const ColorManagedDisplaySettings *displaySettings) { this->m_displaySettings = displaySettings; } -protected: - ViewerBaseOperation(); - void updateImage(rcti *rect); - -private: - void initImage(); -}; -#endif diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cpp b/source/blender/compositor/operations/COM_ViewerOperation.cpp index 4d10e49aeeb..e9f083178e4 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.cpp +++ b/source/blender/compositor/operations/COM_ViewerOperation.cpp @@ -35,11 +35,22 @@ extern "C" { #include "MEM_guardedalloc.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" + #include "IMB_colormanagement.h" } -ViewerOperation::ViewerOperation() : ViewerBaseOperation() +ViewerOperation::ViewerOperation() : NodeOperation() { + this->setImage(NULL); + this->setImageUser(NULL); + this->m_outputBuffer = NULL; + this->m_depthBuffer = NULL; + this->m_active = false; + this->m_doDepthBuffer = false; + this->m_viewSettings = NULL; + this->m_displaySettings = NULL; + this->m_ignoreAlpha = false; + this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_VALUE); @@ -56,7 +67,10 @@ void ViewerOperation::initExecution() this->m_alphaInput = getInputSocketReader(1); this->m_depthInput = getInputSocketReader(2); this->m_doDepthBuffer = (this->m_depthInput != NULL); - ViewerBaseOperation::initExecution(); + + if (isActiveViewerOutput()) { + initImage(); + } } void ViewerOperation::deinitExecution() @@ -64,10 +78,9 @@ void ViewerOperation::deinitExecution() this->m_imageInput = NULL; this->m_alphaInput = NULL; this->m_depthInput = NULL; - ViewerBaseOperation::deinitExecution(); + this->m_outputBuffer = NULL; } - void ViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber) { float *buffer = this->m_outputBuffer; @@ -114,3 +127,63 @@ void ViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber) } updateImage(rect); } + +void ViewerOperation::initImage() +{ + Image *ima = this->m_image; + void *lock; + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, this->m_imageUser, &lock); + + if (!ibuf) return; + BLI_lock_thread(LOCK_DRAW_IMAGE); + if (ibuf->x != (int)getWidth() || ibuf->y != (int)getHeight()) { + + imb_freerectImBuf(ibuf); + imb_freerectfloatImBuf(ibuf); + IMB_freezbuffloatImBuf(ibuf); + ibuf->x = getWidth(); + ibuf->y = getHeight(); + imb_addrectfloatImBuf(ibuf); + ima->ok = IMA_OK_LOADED; + + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; + + BLI_unlock_thread(LOCK_DRAW_IMAGE); + } + + if (m_doDepthBuffer) { + addzbuffloatImBuf(ibuf); + } + BLI_unlock_thread(LOCK_DRAW_IMAGE); + + /* now we combine the input with ibuf */ + this->m_outputBuffer = ibuf->rect_float; + + /* needed for display buffer update */ + this->m_ibuf = ibuf; + + if (m_doDepthBuffer) { + this->m_depthBuffer = ibuf->zbuf_float; + } + + BKE_image_release_ibuf(this->m_image, this->m_ibuf, lock); +} + +void ViewerOperation::updateImage(rcti *rect) +{ + IMB_partial_display_buffer_update(this->m_ibuf, this->m_outputBuffer, NULL, getWidth(), 0, 0, + this->m_viewSettings, this->m_displaySettings, + rect->xmin, rect->ymin, rect->xmax, rect->ymax, FALSE); + + this->updateDraw(); +} + +const CompositorPriority ViewerOperation::getRenderPriority() const +{ + if (this->isActiveViewerOutput()) { + return COM_PRIORITY_HIGH; + } + else { + return COM_PRIORITY_LOW; + } +} diff --git a/source/blender/compositor/operations/COM_ViewerOperation.h b/source/blender/compositor/operations/COM_ViewerOperation.h index 262efd87dba..0b8d08d3974 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.h +++ b/source/blender/compositor/operations/COM_ViewerOperation.h @@ -25,18 +25,54 @@ #include "COM_NodeOperation.h" #include "DNA_image_types.h" #include "BLI_rect.h" -#include "COM_ViewerBaseOperation.h" +#include "BKE_global.h" -class ViewerOperation : public ViewerBaseOperation { +class ViewerOperation : public NodeOperation { private: + float *m_outputBuffer; + float *m_depthBuffer; + Image *m_image; + ImageUser *m_imageUser; + bool m_active; + float m_centerX; + float m_centerY; + OrderOfChunks m_chunkOrder; + bool m_doDepthBuffer; + ImBuf *m_ibuf; + bool m_ignoreAlpha; + + const ColorManagedViewSettings *m_viewSettings; + const ColorManagedDisplaySettings *m_displaySettings; + SocketReader *m_imageInput; SocketReader *m_alphaInput; SocketReader *m_depthInput; public: ViewerOperation(); - void executeRegion(rcti *rect, unsigned int tileNumber); void initExecution(); void deinitExecution(); + void executeRegion(rcti *rect, unsigned int tileNumber); + bool isOutputOperation(bool rendering) const { if (G.background) return false; return isActiveViewerOutput(); } + void setImage(Image *image) { this->m_image = image; } + void setImageUser(ImageUser *imageUser) { this->m_imageUser = imageUser; } + const bool isActiveViewerOutput() const { return this->m_active; } + void setActive(bool active) { this->m_active = active; } + void setCenterX(float centerX) { this->m_centerX = centerX;} + void setCenterY(float centerY) { this->m_centerY = centerY;} + void setChunkOrder(OrderOfChunks tileOrder) { this->m_chunkOrder = tileOrder; } + float getCenterX() const { return this->m_centerX; } + float getCenterY() const { return this->m_centerY; } + OrderOfChunks getChunkOrder() const { return this->m_chunkOrder; } + const CompositorPriority getRenderPriority() const; + bool isViewerOperation() { return true; } + void setIgnoreAlpha(bool value) { this->m_ignoreAlpha = value; } + + void setViewSettings(const ColorManagedViewSettings *viewSettings) { this->m_viewSettings = viewSettings; } + void setDisplaySettings(const ColorManagedDisplaySettings *displaySettings) { this->m_displaySettings = displaySettings; } + +private: + void updateImage(rcti *rect); + void initImage(); }; #endif diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h index 54c7f7ea30f..c571da1ba74 100644 --- a/source/blender/editors/animation/anim_intern.h +++ b/source/blender/editors/animation/anim_intern.h @@ -54,14 +54,14 @@ void ANIM_OT_keyframe_insert_menu(struct wmOperatorType *ot); void ANIM_OT_keyframe_delete_v3d(struct wmOperatorType *ot); void ANIM_OT_keyframe_clear_v3d(struct wmOperatorType *ot); -/* Keyframe managment operators for UI buttons (RMB menu). */ +/* Keyframe management operators for UI buttons (RMB menu). */ void ANIM_OT_keyframe_insert_button(struct wmOperatorType *ot); void ANIM_OT_keyframe_delete_button(struct wmOperatorType *ot); void ANIM_OT_keyframe_clear_button(struct wmOperatorType *ot); /* .......... */ -/* KeyingSet managment operators for UI buttons (RMB menu) */ +/* KeyingSet management operators for UI buttons (RMB menu) */ void ANIM_OT_keyingset_button_add(struct wmOperatorType *ot); void ANIM_OT_keyingset_button_remove(struct wmOperatorType *ot); diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index fe41a037fcb..3c8576be312 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -553,7 +553,7 @@ static int ed_markers_opwrap_invoke(bContext *C, wmOperator *op, const wmEvent * /* ************************** add markers *************************** */ /* add TimeMarker at curent frame */ -static int ed_marker_add(bContext *C, wmOperator *UNUSED(op)) +static int ed_marker_add_exec(bContext *C, wmOperator *UNUSED(op)) { ListBase *markers = ED_context_get_markers(C); TimeMarker *marker; @@ -593,7 +593,7 @@ static void MARKER_OT_add(wmOperatorType *ot) ot->idname = "MARKER_OT_add"; /* api callbacks */ - ot->exec = ed_marker_add; + ot->exec = ed_marker_add_exec; ot->invoke = ed_markers_opwrap_invoke; ot->poll = ED_operator_animview_active; diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 4e6cc53f962..db51e3c2398 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -793,7 +793,7 @@ void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos) { DLRBT_Tree keys, blocks; - short locked = (act && act->id.lib != 0); + short locked = (act && act->id.lib != NULL); BLI_dlrbTree_init(&keys); BLI_dlrbTree_init(&blocks); @@ -887,7 +887,7 @@ void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys, DLRBT_Tree bAnimListElem *ale; int filter; - bAnimListElem dummychan = {0}; + bAnimListElem dummychan = {NULL}; if (sce == NULL) return; @@ -920,8 +920,8 @@ void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, DLRBT_Tree *bl bAnimListElem *ale; int filter; - bAnimListElem dummychan = {0}; - Base dummybase = {0}; + bAnimListElem dummychan = {NULL}; + Base dummybase = {NULL}; if (ob == NULL) return; diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index 2cb2f6683ef..cfa5f9f032c 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -628,9 +628,8 @@ static tAnimCopybufItem *pastebuf_match_path_property(FCurve *fcu, const short f PropertyRNA *prop; RNA_id_pointer_create(aci->id, &id_ptr); - RNA_path_resolve(&id_ptr, aci->rna_path, &rptr, &prop); - if (prop) { + if (RNA_path_resolve_property(&id_ptr, aci->rna_path, &rptr, &prop)) { const char *identifier = RNA_property_identifier(prop); int len_id = strlen(identifier); int len_path = strlen(fcu->rna_path); diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c index 12602c10955..90c1a439a19 100644 --- a/source/blender/editors/armature/armature_edit.c +++ b/source/blender/editors/armature/armature_edit.c @@ -78,11 +78,10 @@ void ED_armature_apply_transform(Object *ob, float mat[4][4]) /* Do the rotations */ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - float delta[3], tmat[3][3]; + float tmat[3][3]; /* find the current bone's roll matrix */ - sub_v3_v3v3(delta, ebone->tail, ebone->head); - vec_roll_to_mat3(delta, ebone->roll, tmat); + ED_armature_ebone_to_mat3(ebone, tmat); /* transform the roll matrix */ mul_m3_m3m3(tmat, mat3, tmat); @@ -282,15 +281,14 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op) mul_m3_v3(imat, vec); } else if (type == CALC_ROLL_ACTIVE) { - float mat[3][3], nor[3]; + float mat[3][3]; ebone = (EditBone *)arm->act_edbone; if (ebone == NULL) { BKE_report(op->reports, RPT_ERROR, "No active bone set"); return OPERATOR_CANCELLED; } - sub_v3_v3v3(nor, ebone->tail, ebone->head); - vec_roll_to_mat3(nor, ebone->roll, mat); + ED_armature_ebone_to_mat3(ebone, mat); copy_v3_v3(vec, mat[2]); } else { /* Axis */ diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c index 289901076a1..79d75c9fcda 100644 --- a/source/blender/editors/armature/armature_relations.c +++ b/source/blender/editors/armature/armature_relations.c @@ -242,21 +242,18 @@ int join_armature_exec(bContext *C, wmOperator *op) float difmat[4][4]; float imat[4][4]; float temp[3][3]; - float delta[3]; /* Get the premat */ - sub_v3_v3v3(delta, curbone->tail, curbone->head); - vec_roll_to_mat3(delta, curbone->roll, temp); + ED_armature_ebone_to_mat3(curbone, temp); - unit_m4(premat); /* Mat4MulMat34 only sets 3x3 part */ + unit_m4(premat); /* mul_m4_m3m4 only sets 3x3 part */ mul_m4_m3m4(premat, temp, mat); mul_m4_v3(mat, curbone->head); mul_m4_v3(mat, curbone->tail); /* Get the postmat */ - sub_v3_v3v3(delta, curbone->tail, curbone->head); - vec_roll_to_mat3(delta, curbone->roll, temp); + ED_armature_ebone_to_mat3(curbone, temp); copy_m4_m3(postmat, temp); /* Find the roll */ diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index d05d309b201..fe1d2fa3765 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -244,7 +244,7 @@ void ARMATURE_OT_select_linked(wmOperatorType *ot) ot->description = "Select bones related to selected ones by parent/child relationships"; /* api callbacks */ - ot->exec = NULL; + /* leave 'exec' unset */ ot->invoke = armature_select_linked_invoke; ot->poll = armature_select_linked_poll; @@ -714,10 +714,10 @@ static void armature_select_less(bArmature *UNUSED(arm), EditBone *ebone) } } -static void armature_select_more_less(Object* ob, bool more) +static void armature_select_more_less(Object *ob, bool more) { - bArmature* arm = (bArmature *)ob->data; - EditBone* ebone; + bArmature *arm = (bArmature *)ob->data; + EditBone *ebone; /* XXX, eventually we shouldn't need this - campbell */ ED_armature_sync_selection(arm->edbo); diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c index 0a9cff3dc90..22bd22c8561 100644 --- a/source/blender/editors/armature/armature_skinning.c +++ b/source/blender/editors/armature/armature_skinning.c @@ -362,7 +362,7 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob, DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); if (dm->foreachMappedVert) { - dm->foreachMappedVert(dm, add_vgroups__mapFunc, (void *)verts); + dm->foreachMappedVert(dm, add_vgroups__mapFunc, (void *)verts, DM_FOREACH_NOP); vertsfilled = 1; } diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c index 0e93a00b01d..4991ef63cf5 100644 --- a/source/blender/editors/armature/armature_utils.c +++ b/source/blender/editors/armature/armature_utils.c @@ -156,6 +156,25 @@ bool ED_armature_ebone_is_child_recursive(EditBone *ebone_parent, EditBone *ebon return false; } +void ED_armature_ebone_to_mat3(EditBone *ebone, float mat[3][3]) +{ + float delta[3]; + + /* Find the current bone matrix */ + sub_v3_v3v3(delta, ebone->tail, ebone->head); + vec_roll_to_mat3(delta, ebone->roll, mat); +} + +void ED_armature_ebone_to_mat4(EditBone *ebone, float mat[4][4]) +{ + float m3[3][3]; + + ED_armature_ebone_to_mat3(ebone, m3); + + copy_m4_m3(mat, m3); + copy_v3_v3(mat[3], ebone->head); +} + /* *************************************************************** */ /* Mirroring */ @@ -389,7 +408,6 @@ static void fix_bonelist_roll(ListBase *bonelist, ListBase *editbonelist) float postmat[3][3]; float difmat[3][3]; float imat[3][3]; - float delta[3]; for (curBone = bonelist->first; curBone; curBone = curBone->next) { /* sets local matrix and arm_mat (restpos) */ @@ -402,8 +420,7 @@ static void fix_bonelist_roll(ListBase *bonelist, ListBase *editbonelist) if (ebone) { /* Get the ebone premat */ - sub_v3_v3v3(delta, ebone->tail, ebone->head); - vec_roll_to_mat3(delta, ebone->roll, premat); + ED_armature_ebone_to_mat3(ebone, premat); /* Get the bone postmat */ copy_m3_m4(postmat, curBone->arm_mat); @@ -503,11 +520,9 @@ void ED_armature_from_edit(Object *obedit) { float M_parentRest[3][3]; float iM_parentRest[3][3]; - float delta[3]; /* Get the parent's matrix (rotation only) */ - sub_v3_v3v3(delta, eBone->parent->tail, eBone->parent->head); - vec_roll_to_mat3(delta, eBone->parent->roll, M_parentRest); + ED_armature_ebone_to_mat3(eBone->parent, M_parentRest); /* Invert the parent matrix */ invert_m3_m3(iM_parentRest, M_parentRest); diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c index 40b96132699..e84008c3d15 100644 --- a/source/blender/editors/armature/pose_edit.c +++ b/source/blender/editors/armature/pose_edit.c @@ -487,6 +487,9 @@ static void pose_copy_menu(Scene *scene) break; case 8: /* Custom Bone Shape */ pchan->custom = pchanact->custom; + if (pchan->custom) { + id_us_plus(&pchan->custom->id); + } break; case 9: /* Visual Location */ BKE_armature_loc_pose_to_bone(pchan, pchanact->pose_mat[3], pchan->loc); diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c index c599e978e58..9449b5a49bf 100644 --- a/source/blender/editors/armature/pose_select.c +++ b/source/blender/editors/armature/pose_select.c @@ -271,7 +271,7 @@ void POSE_OT_select_linked(wmOperatorType *ot) ot->description = "Select bones related to selected ones by parent/child relationships"; /* api callbacks */ - ot->exec = NULL; + /* leave 'exec' unset */ ot->invoke = pose_select_connected_invoke; ot->poll = pose_select_linked_poll; diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c index c530faedd68..79ca70a6189 100644 --- a/source/blender/editors/armature/pose_transform.c +++ b/source/blender/editors/armature/pose_transform.c @@ -815,7 +815,7 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op) * just pose values should change, so this should be fine */ bPose *dummyPose = NULL; - Object workob = {{0}}; + Object workob = {{NULL}}; bPoseChannel *pchan; /* execute animation step for current frame using a dummy copy of the pose */ diff --git a/source/blender/editors/armature/pose_utils.c b/source/blender/editors/armature/pose_utils.c index a5e51ccf32a..014a64170db 100644 --- a/source/blender/editors/armature/pose_utils.c +++ b/source/blender/editors/armature/pose_utils.c @@ -239,7 +239,7 @@ void poseAnim_mapping_autoKeyframe(bContext *C, Scene *scene, Object *ob, ListBa * - only do this if keyframes should have been added * - do not calculate unless there are paths already to update... */ - if (C && (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) { + if (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) { //ED_pose_clear_paths(C, ob); // XXX for now, don't need to clear ED_pose_recalculate_paths(scene, ob); } diff --git a/source/blender/editors/curve/curve_intern.h b/source/blender/editors/curve/curve_intern.h index 0521297d049..d197697e60b 100644 --- a/source/blender/editors/curve/curve_intern.h +++ b/source/blender/editors/curve/curve_intern.h @@ -88,7 +88,9 @@ void CURVE_OT_shade_flat(struct wmOperatorType *ot); void CURVE_OT_tilt_clear(struct wmOperatorType *ot); void CURVE_OT_smooth(struct wmOperatorType *ot); +void CURVE_OT_smooth_weight(struct wmOperatorType *ot); void CURVE_OT_smooth_radius(struct wmOperatorType *ot); +void CURVE_OT_smooth_tilt(struct wmOperatorType *ot); void CURVE_OT_primitive_bezier_curve_add(struct wmOperatorType *ot); void CURVE_OT_primitive_bezier_circle_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c index 5b525a089b3..2452a5d1a4b 100644 --- a/source/blender/editors/curve/curve_ops.c +++ b/source/blender/editors/curve/curve_ops.c @@ -112,7 +112,9 @@ void ED_operatortypes_curve(void) WM_operatortype_append(SURFACE_OT_primitive_nurbs_surface_torus_add); WM_operatortype_append(CURVE_OT_smooth); + WM_operatortype_append(CURVE_OT_smooth_weight); WM_operatortype_append(CURVE_OT_smooth_radius); + WM_operatortype_append(CURVE_OT_smooth_tilt); WM_operatortype_append(CURVE_OT_de_select_first); WM_operatortype_append(CURVE_OT_de_select_last); diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 75de4e13707..660f8098a38 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -2260,29 +2260,33 @@ void CURVE_OT_smooth(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/**************** smooth curve radius operator *************/ +/* -------------------------------------------------------------------- */ +/* Smooth radius/weight/tilt + * + * TODO: make smoothing distance based + * TODO: support cyclic curves + */ -/* TODO, make smoothing distance based */ -static int smooth_radius_exec(bContext *C, wmOperator *UNUSED(op)) +static void curve_smooth_value(ListBase *editnurb, + const int bezt_offsetof, const int bp_offset) { - Object *obedit = CTX_data_edit_object(C); - ListBase *editnurb = object_editcurve_get(obedit); Nurb *nu; BezTriple *bezt; BPoint *bp; int a; - + /* use for smoothing */ int last_sel; int start_sel, end_sel; /* selection indices, inclusive */ float start_rad, end_rad, fac, range; - + for (nu = editnurb->first; nu; nu = nu->next) { if (nu->bezt) { - +#define BEZT_VALUE(bezt) (*((float *)((char *)bezt + bezt_offsetof))) + for (last_sel = 0; last_sel < nu->pntsu; last_sel++) { /* loop over selection segments of a curve, smooth each */ - + /* Start BezTriple code, this is duplicated below for points, make sure these functions stay in sync */ start_sel = -1; for (bezt = &nu->bezt[last_sel], a = last_sel; a < nu->pntsu; a++, bezt++) { @@ -2299,57 +2303,60 @@ static int smooth_radius_exec(bContext *C, wmOperator *UNUSED(op)) } end_sel = a; } - + if (start_sel == -1) { last_sel = nu->pntsu; /* next... */ } else { last_sel = end_sel; /* before we modify it */ - + /* now blend between start and end sel */ - start_rad = end_rad = -1.0; - + start_rad = end_rad = FLT_MAX; + if (start_sel == end_sel) { /* simple, only 1 point selected */ - if (start_sel > 0) start_rad = nu->bezt[start_sel - 1].radius; - if (end_sel != -1 && end_sel < nu->pntsu) end_rad = nu->bezt[start_sel + 1].radius; - - if (start_rad >= 0.0f && end_rad >= 0.0f) nu->bezt[start_sel].radius = (start_rad + end_rad) / 2.0f; - else if (start_rad >= 0.0f) nu->bezt[start_sel].radius = start_rad; - else if (end_rad >= 0.0f) nu->bezt[start_sel].radius = end_rad; + if (start_sel > 0) start_rad = BEZT_VALUE(&nu->bezt[start_sel - 1]); + if (end_sel != -1 && end_sel < nu->pntsu) end_rad = BEZT_VALUE(&nu->bezt[start_sel + 1]); + + if (start_rad != FLT_MAX && end_rad >= FLT_MAX) BEZT_VALUE(&nu->bezt[start_sel]) = (start_rad + end_rad) / 2.0f; + else if (start_rad != FLT_MAX) BEZT_VALUE(&nu->bezt[start_sel]) = start_rad; + else if (end_rad != FLT_MAX) BEZT_VALUE(&nu->bezt[start_sel]) = end_rad; } else { /* if endpoints selected, then use them */ if (start_sel == 0) { - start_rad = nu->bezt[start_sel].radius; + start_rad = BEZT_VALUE(&nu->bezt[start_sel]); start_sel++; /* we don't want to edit the selected endpoint */ } else { - start_rad = nu->bezt[start_sel - 1].radius; + start_rad = BEZT_VALUE(&nu->bezt[start_sel - 1]); } if (end_sel == nu->pntsu - 1) { - end_rad = nu->bezt[end_sel].radius; + end_rad = BEZT_VALUE(&nu->bezt[end_sel]); end_sel--; /* we don't want to edit the selected endpoint */ } else { - end_rad = nu->bezt[end_sel + 1].radius; + end_rad = BEZT_VALUE(&nu->bezt[end_sel + 1]); } - + /* Now Blend between the points */ range = (float)(end_sel - start_sel) + 2.0f; for (bezt = &nu->bezt[start_sel], a = start_sel; a <= end_sel; a++, bezt++) { fac = (float)(1 + a - start_sel) / range; - bezt->radius = start_rad * (1.0f - fac) + end_rad * fac; + BEZT_VALUE(bezt) = start_rad * (1.0f - fac) + end_rad * fac; } } } } +#undef BEZT_VALUE } else if (nu->bp) { +#define BP_VALUE(bp) (*((float *)((char *)bp + bp_offset))) + /* Same as above, keep these the same! */ for (last_sel = 0; last_sel < nu->pntsu; last_sel++) { /* loop over selection segments of a curve, smooth each */ - + /* Start BezTriple code, this is duplicated below for points, make sure these functions stay in sync */ start_sel = -1; for (bp = &nu->bp[last_sel], a = last_sel; a < nu->pntsu; a++, bp++) { @@ -2366,53 +2373,90 @@ static int smooth_radius_exec(bContext *C, wmOperator *UNUSED(op)) } end_sel = a; } - + if (start_sel == -1) { last_sel = nu->pntsu; /* next... */ } else { last_sel = end_sel; /* before we modify it */ - + /* now blend between start and end sel */ - start_rad = end_rad = -1.0; - + start_rad = end_rad = FLT_MAX; + if (start_sel == end_sel) { /* simple, only 1 point selected */ - if (start_sel > 0) start_rad = nu->bp[start_sel - 1].radius; - if (end_sel != -1 && end_sel < nu->pntsu) end_rad = nu->bp[start_sel + 1].radius; - - if (start_rad >= 0.0f && end_rad >= 0.0f) nu->bp[start_sel].radius = (start_rad + end_rad) / 2; - else if (start_rad >= 0.0f) nu->bp[start_sel].radius = start_rad; - else if (end_rad >= 0.0f) nu->bp[start_sel].radius = end_rad; + if (start_sel > 0) start_rad = BP_VALUE(&nu->bp[start_sel - 1]); + if (end_sel != -1 && end_sel < nu->pntsu) end_rad = BP_VALUE(&nu->bp[start_sel + 1]); + + if (start_rad != FLT_MAX && end_rad != FLT_MAX) BP_VALUE(&nu->bp[start_sel]) = (start_rad + end_rad) / 2; + else if (start_rad != FLT_MAX) BP_VALUE(&nu->bp[start_sel]) = start_rad; + else if (end_rad != FLT_MAX) BP_VALUE(&nu->bp[start_sel]) = end_rad; } else { /* if endpoints selected, then use them */ if (start_sel == 0) { - start_rad = nu->bp[start_sel].radius; + start_rad = BP_VALUE(&nu->bp[start_sel]); start_sel++; /* we don't want to edit the selected endpoint */ } else { - start_rad = nu->bp[start_sel - 1].radius; + start_rad = BP_VALUE(&nu->bp[start_sel - 1]); } if (end_sel == nu->pntsu - 1) { - end_rad = nu->bp[end_sel].radius; + end_rad = BP_VALUE(&nu->bp[end_sel]); end_sel--; /* we don't want to edit the selected endpoint */ } else { - end_rad = nu->bp[end_sel + 1].radius; + end_rad = BP_VALUE(&nu->bp[end_sel + 1]); } - + /* Now Blend between the points */ range = (float)(end_sel - start_sel) + 2.0f; for (bp = &nu->bp[start_sel], a = start_sel; a <= end_sel; a++, bp++) { fac = (float)(1 + a - start_sel) / range; - bp->radius = start_rad * (1.0f - fac) + end_rad * fac; + BP_VALUE(bp) = start_rad * (1.0f - fac) + end_rad * fac; } } } } +#undef BP_VALUE } } +} + +static int curve_smooth_weight_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + ListBase *editnurb = object_editcurve_get(obedit); + + curve_smooth_value(editnurb, offsetof(BezTriple, weight), offsetof(BPoint, weight)); + + WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); + DAG_id_tag_update(obedit->data, 0); + + return OPERATOR_FINISHED; +} + +void CURVE_OT_smooth_weight(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Smooth Curve Weight"; + ot->description = "Interpolate weight of selected points"; + ot->idname = "CURVE_OT_smooth_weight"; + + /* api clastbacks */ + ot->exec = curve_smooth_weight_exec; + ot->poll = ED_operator_editsurfcurve; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int curve_smooth_radius_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + ListBase *editnurb = object_editcurve_get(obedit); + + curve_smooth_value(editnurb, offsetof(BezTriple, radius), offsetof(BPoint, radius)); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); DAG_id_tag_update(obedit->data, 0); @@ -2424,17 +2468,45 @@ void CURVE_OT_smooth_radius(wmOperatorType *ot) { /* identifiers */ ot->name = "Smooth Curve Radius"; - ot->description = "Flatten radii of selected points"; + ot->description = "Interpolate radii of selected points"; ot->idname = "CURVE_OT_smooth_radius"; /* api clastbacks */ - ot->exec = smooth_radius_exec; + ot->exec = curve_smooth_radius_exec; ot->poll = ED_operator_editsurfcurve; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static int curve_smooth_tilt_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + ListBase *editnurb = object_editcurve_get(obedit); + + curve_smooth_value(editnurb, offsetof(BezTriple, alfa), offsetof(BPoint, alfa)); + + WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); + DAG_id_tag_update(obedit->data, 0); + + return OPERATOR_FINISHED; +} + +void CURVE_OT_smooth_tilt(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Smooth Curve Tilt"; + ot->description = "Interpolate tilt of selected points"; + ot->idname = "CURVE_OT_smooth_tilt"; + + /* api clastbacks */ + ot->exec = curve_smooth_tilt_exec; + ot->poll = ED_operator_editsurfcurve; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /***************** selection utility *************************/ /* next == 1 -> select next */ @@ -2833,44 +2905,6 @@ void CURVE_OT_reveal(wmOperatorType *ot) /********************** subdivide operator *********************/ -static BezTriple *next_spline_bezier_point_get(Nurb *nu, BezTriple *bezt) -{ - BezTriple *nextbezt; - - if (bezt == nu->bezt + nu->pntsu - 1) { - if (nu->flagu & CU_NURB_CYCLIC) { - nextbezt = nu->bezt; - } - else { - nextbezt = NULL; - } - } - else { - nextbezt = bezt + 1; - } - - return nextbezt; -} - -static BPoint *next_spline_bpoint_get(Nurb *nu, BPoint *bp) -{ - BPoint *nextbp; - - if (bp == nu->bp + nu->pntsu - 1) { - if (nu->flagu & CU_NURB_CYCLIC) { - nextbp = nu->bp; - } - else { - nextbp = NULL; - } - } - else { - nextbp = bp + 1; - } - - return nextbp; -} - /** Divide the line segments associated with the currently selected * curve nodes (Bezier or NURB). If there are no valid segment * selections within the current selection, nothing happens. @@ -2902,7 +2936,7 @@ static void subdividenurb(Object *obedit, int number_cuts) a = nu->pntsu; bezt = nu->bezt; while (a--) { - nextbezt = next_spline_bezier_point_get(nu, bezt); + nextbezt = BKE_nurb_bezt_get_next(nu, bezt); if (nextbezt == NULL) { break; } @@ -2924,7 +2958,7 @@ static void subdividenurb(Object *obedit, int number_cuts) keyIndex_updateBezt(editnurb, bezt, beztn, 1); beztn++; - nextbezt = next_spline_bezier_point_get(nu, bezt); + nextbezt = BKE_nurb_bezt_get_next(nu, bezt); if (nextbezt == NULL) { break; } @@ -2988,7 +3022,7 @@ static void subdividenurb(Object *obedit, int number_cuts) a = nu->pntsu; bp = nu->bp; while (a--) { - nextbp = next_spline_bpoint_get(nu, bp); + nextbp = BKE_nurb_bpoint_get_next(nu, bp); if (nextbp == NULL) { break; } @@ -3013,7 +3047,7 @@ static void subdividenurb(Object *obedit, int number_cuts) keyIndex_updateBP(editnurb, bp, bpn, 1); bpn++; - nextbp = next_spline_bpoint_get(nu, bp); + nextbp = BKE_nurb_bpoint_get_next(nu, bp); if (nextbp == NULL) { break; } @@ -5174,7 +5208,7 @@ static int select_more_exec(bContext *C, wmOperator *UNUSED(op)) /* may not be optimal always (example: end of NURBS sphere) */ if (obedit->type == OB_SURF) { for (nu = editnurb->first; nu; nu = nu->next) { - BLI_bitmap selbpoints; + BLI_bitmap *selbpoints; a = nu->pntsu * nu->pntsv; bp = nu->bp; selbpoints = BLI_BITMAP_NEW(a, "selectlist"); @@ -5260,7 +5294,7 @@ static int select_less_exec(bContext *C, wmOperator *UNUSED(op)) if (obedit->type == OB_SURF) { for (nu = editnurb->first; nu; nu = nu->next) { - BLI_bitmap selbpoints; + BLI_bitmap *selbpoints; a = nu->pntsu * nu->pntsv; bp = nu->bp; selbpoints = BLI_BITMAP_NEW(a, "selectlist"); diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index db4e4dc8500..b9759e16f20 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -446,7 +446,9 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, float Object *obedit; Base *base; struct TextLine *tmp; - int nchars = 0, a; + int nchars = 0, nbytes = 0; + char *s; + int a; float rot[3] = {0.f, 0.f, 0.f}; obedit = BKE_object_add(bmain, scene, OB_FONT); @@ -463,26 +465,38 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, float cu->vfont = BKE_vfont_builtin_get(); cu->vfont->id.us++; - for (tmp = firstline, a = 0; cu->len < MAXTEXT && a < totline; tmp = tmp->next, a++) - nchars += strlen(tmp->line) + 1; + for (tmp = firstline, a = 0; nbytes < MAXTEXT && a < totline; tmp = tmp->next, a++) { + size_t nchars_line, nbytes_line; + nchars_line = BLI_strlen_utf8_ex(tmp->line, &nbytes_line); + nchars += nchars_line + 1; + nbytes += nbytes_line + 1; + } if (cu->str) MEM_freeN(cu->str); if (cu->strinfo) MEM_freeN(cu->strinfo); - cu->str = MEM_callocN(nchars + 4, "str"); + cu->str = MEM_mallocN(nbytes + 4, "str"); cu->strinfo = MEM_callocN((nchars + 4) * sizeof(CharInfo), "strinfo"); - cu->str[0] = '\0'; cu->len = 0; cu->pos = 0; - + + s = cu->str; + *s = '\0'; + for (tmp = firstline, a = 0; cu->len < MAXTEXT && a < totline; tmp = tmp->next, a++) { - strcat(cu->str, tmp->line); - cu->len += strlen(tmp->line); + size_t nbytes_line; + + nbytes_line = BLI_strcpy_rlen(s, tmp->line); + + s += nbytes_line; + cu->len += nbytes_line; if (tmp->next) { - strcat(cu->str, "\n"); - cu->len++; + nbytes_line = BLI_strcpy_rlen(s, "\n"); + + s += nbytes_line; + cu->len += nbytes_line; } cu->pos = cu->len; diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h index dfb02fa9c1b..352a74cf172 100644 --- a/source/blender/editors/include/BIF_glutil.h +++ b/source/blender/editors/include/BIF_glutil.h @@ -55,7 +55,6 @@ void fdrawXORcirc(float xofs, float yofs, float rad); void fdrawcheckerboard(float x1, float y1, float x2, float y2); /* OpenGL stipple defines */ -/* OpenGL stipple defines */ extern const unsigned char stipple_halftone[128]; extern const unsigned char stipple_quarttone[128]; extern const unsigned char stipple_diag_stripes_pos[128]; diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 9b9a4c154db..fab179da7bc 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -135,8 +135,12 @@ void ED_armature_validate_active(struct bArmature *arm); void add_primitive_bone(struct Object *obedit_arm, bool view_aligned); struct EditBone *ED_armature_edit_bone_add(struct bArmature *arm, const char *name); void ED_armature_edit_bone_remove(struct bArmature *arm, EditBone *exBone); + bool ED_armature_ebone_is_child_recursive(EditBone *ebone_parent, EditBone *ebone_child); +void ED_armature_ebone_to_mat3(EditBone *ebone, float mat[3][3]); +void ED_armature_ebone_to_mat4(EditBone *ebone, float mat[4][4]); + void transform_armature_mirror_update(struct Object *obedit); void ED_armature_origin_set(struct Scene *scene, struct Object *ob, float cursor[3], int centermode, int around); diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index 423613fb780..81308dd84f2 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -90,16 +90,14 @@ enum TfmMode { /* TRANSFORM CONTEXTS */ #define CTX_NONE 0 -#define CTX_TEXTURE 1 -#define CTX_EDGE 2 -#define CTX_NO_PET 4 -#define CTX_TWEAK 8 -#define CTX_NO_MIRROR 16 -#define CTX_AUTOCONFIRM 32 -#define CTX_BMESH 64 -#define CTX_NDOF 128 -#define CTX_MOVIECLIP 256 -#define CTX_MASK 512 +#define CTX_TEXTURE (1 << 0) +#define CTX_EDGE (1 << 1) +#define CTX_NO_PET (1 << 2) +#define CTX_NO_MIRROR (1 << 3) +#define CTX_AUTOCONFIRM (1 << 4) +#define CTX_NDOF (1 << 5) +#define CTX_MOVIECLIP (1 << 6) +#define CTX_MASK (1 << 7) /* Standalone call to get the transformation center corresponding to the current situation * returns 1 if successful, 0 otherwise (usually means there's no selection) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index e5cc0dd8ea7..9a9cab9b46c 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -327,7 +327,11 @@ typedef void (*uiMenuHandleFunc)(struct bContext *C, void *arg, int event); typedef struct uiPopupMenu uiPopupMenu; -struct uiPopupMenu *uiPupMenuBegin(struct bContext *C, const char *title, int icon); +struct uiPopupMenu *uiPupMenuBegin(struct bContext *C, const char *title, int icon) +#ifdef __GNUC__ +__attribute__((nonnull)) +#endif +; void uiPupMenuEnd(struct bContext *C, struct uiPopupMenu *head); struct uiLayout *uiPupMenuLayout(uiPopupMenu *head); @@ -546,7 +550,11 @@ typedef struct uiStringInfo { /* Note: Expects pointers to uiStringInfo structs as parameters. * Will fill them with translated strings, when possible. * Strings in uiStringInfo must be MEM_freeN'ed by caller. */ -void uiButGetStrInfo(struct bContext *C, uiBut *but, ...); +void uiButGetStrInfo(struct bContext *C, uiBut *but, ...) +#ifdef __GNUC__ +__attribute__((sentinel)) +#endif +; /* Edit i18n stuff. */ /* Name of the main py op from i18n addon. */ diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 042ca942722..21a63183c1a 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -559,19 +559,19 @@ static void ui_draw_links(uiBlock *block) /* ************** BLOCK ENDING FUNCTION ************* */ /* NOTE: if but->poin is allocated memory for every defbut, things fail... */ -static bool ui_but_equals_old(uiBut *but, uiBut *oldbut) +static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut) { /* various properties are being compared here, hopefully sufficient * to catch all cases, but it is simple to add more checks later */ if (but->retval != oldbut->retval) return false; if (but->rnapoin.data != oldbut->rnapoin.data) return false; - if (but->rnaprop != oldbut->rnaprop) - if (but->rnaindex != oldbut->rnaindex) return false; + if (but->rnaprop != oldbut->rnaprop && but->rnaindex != oldbut->rnaindex) return false; if (but->func != oldbut->func) return false; if (but->funcN != oldbut->funcN) return false; if (oldbut->func_arg1 != oldbut && but->func_arg1 != oldbut->func_arg1) return false; if (oldbut->func_arg2 != oldbut && but->func_arg2 != oldbut->func_arg2) return false; - if (!but->funcN && ((but->poin != oldbut->poin && (uiBut *)oldbut->poin != oldbut) || but->pointype != oldbut->pointype)) return false; + if (!but->funcN && ((but->poin != oldbut->poin && (uiBut *)oldbut->poin != oldbut) || + (but->pointype != oldbut->pointype))) return false; if (but->optype != oldbut->optype) return false; return true; @@ -620,7 +620,7 @@ static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut return found; for (oldbut = oldblock->buttons.first; oldbut; oldbut = oldbut->next) { - if (ui_but_equals_old(oldbut, but)) { + if (ui_but_equals_old(but, oldbut)) { if (oldbut->active) { #if 0 // but->flag = oldbut->flag; @@ -2426,35 +2426,37 @@ void ui_check_but(uiBut *but) case NUM: case NUMSLI: - UI_GET_BUT_VALUE_INIT(but, value); + if (!but->editstr) { + UI_GET_BUT_VALUE_INIT(but, value); - if (ui_is_but_float(but)) { - if (value == (double) FLT_MAX) { - BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%sinf", but->str); - } - else if (value == (double) -FLT_MAX) { - BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s-inf", but->str); - } - /* support length type buttons */ - else if (ui_is_but_unit(but)) { - char new_str[sizeof(but->drawstr)]; - ui_get_but_string_unit(but, new_str, sizeof(new_str), value, TRUE, -1); - BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, new_str); + if (ui_is_but_float(but)) { + if (value == (double) FLT_MAX) { + BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%sinf", but->str); + } + else if (value == (double) -FLT_MAX) { + BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s-inf", but->str); + } + /* support length type buttons */ + else if (ui_is_but_unit(but)) { + char new_str[sizeof(but->drawstr)]; + ui_get_but_string_unit(but, new_str, sizeof(new_str), value, TRUE, -1); + BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, new_str); + } + else { + const int prec = ui_but_float_precision(but, value); + BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value); + } } else { - const int prec = ui_but_float_precision(but, value); - BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value); + BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%d", but->str, (int)value); + } + + if (but->rnaprop) { + PropertySubType pstype = RNA_property_subtype(but->rnaprop); + + if (pstype == PROP_PERCENTAGE) + strcat(but->drawstr, "%"); } - } - else { - BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%d", but->str, (int)value); - } - - if (but->rnaprop) { - PropertySubType pstype = RNA_property_subtype(but->rnaprop); - - if (pstype == PROP_PERCENTAGE) - strcat(but->drawstr, "%"); } break; @@ -2477,29 +2479,30 @@ void ui_check_but(uiBut *but) if (!but->editstr) { char str[UI_MAX_DRAW_STR]; - ui_get_but_string(but, str, UI_MAX_DRAW_STR - strlen(but->str)); - + ui_get_but_string(but, str, UI_MAX_DRAW_STR); BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, str); } break; case KEYEVT: - BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR); + { + const char *str; if (but->flag & UI_SELECT) { - strcat(but->drawstr, "Press a key"); + str = "Press a key"; } else { UI_GET_BUT_VALUE_INIT(but, value); - strcat(but->drawstr, WM_key_event_string((short)value)); + str = WM_key_event_string((short)value); } + BLI_snprintf(but->drawstr, UI_MAX_DRAW_STR, "%s%s", but->str, str); break; - + } case HOTKEYEVT: if (but->flag & UI_SELECT) { - but->drawstr[0] = '\0'; if (but->modifier_key) { char *str = but->drawstr; + but->drawstr[0] = '\0'; if (but->modifier_key & KM_SHIFT) str += BLI_strcpy_rlen(str, "Shift "); @@ -2512,8 +2515,9 @@ void ui_check_but(uiBut *but) (void)str; /* UNUSED */ } - else - strcat(but->drawstr, "Press a key "); + else { + BLI_strncpy(but->drawstr, "Press a key", UI_MAX_DRAW_STR); + } } else BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR); @@ -3960,7 +3964,8 @@ void uiButSetFocusOnEnter(wmWindow *win, uiBut *but) { wmEvent event; - event = *(win->eventstate); + wm_event_init_from_window(win, &event); + event.type = EVT_BUT_OPEN; event.val = KM_PRESS; event.customdata = but; diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index cbd1f6ccaaa..cd845da10c6 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -561,7 +561,7 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol) glColor4f(1.f, 1.f, 1.f, 0.08f); /* draw grid lines here */ - for (i = 1; i < (HISTOGRAM_TOT_GRID_LINES + 1); i++) { + for (i = 1; i <= HISTOGRAM_TOT_GRID_LINES; i++) { const float fac = (float)i / (float)HISTOGRAM_TOT_GRID_LINES; /* so we can tell the 1.0 color point */ diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index ee316e13dad..f9ee2b67e6b 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -228,10 +228,10 @@ typedef struct uiAfterFunc { bContextStore *context; char undostr[BKE_UNDO_STR_MAX]; - - int autokey; } uiAfterFunc; + + static bool ui_but_contains_pt(uiBut *but, int mx, int my); static bool ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y); static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state); @@ -2605,7 +2605,7 @@ static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, c static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { if (data->state == BUTTON_STATE_HIGHLIGHT) { - if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) { + if (ELEM4(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS) { if (but->dt == UI_EMBOSSN && !event->ctrl) { /* pass */ } @@ -2630,7 +2630,7 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { /* unlink icon is on right */ - if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) { + if (ELEM4(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS) { ARegion *ar = data->region; rcti rect; int x = event->x, y = event->y; @@ -4944,7 +4944,6 @@ static bool ui_but_menu(bContext *C, uiBut *but) uiPopupMenu *pup; uiLayout *layout; bool is_array, is_array_component; - const char *name; uiStringInfo label = {BUT_GET_LABEL, NULL}; /* if ((but->rnapoin.data && but->rnaprop) == 0 && but->optype == NULL)*/ @@ -4957,12 +4956,11 @@ static bool ui_but_menu(bContext *C, uiBut *but) button_timers_tooltip_remove(C, but); + /* highly unlikely getting the label ever fails */ uiButGetStrInfo(C, but, &label, NULL); - name = label.strinfo; - pup = uiPupMenuBegin(C, name, ICON_NONE); + pup = uiPupMenuBegin(C, label.strinfo ? label.strinfo : "", ICON_NONE); layout = uiPupMenuLayout(pup); - if (label.strinfo) MEM_freeN(label.strinfo); @@ -6195,7 +6193,7 @@ void ui_button_activate_do(bContext *C, ARegion *ar, uiBut *but) button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER); - event = *(win->eventstate); /* XXX huh huh? make api call */ + wm_event_init_from_window(win, &event); event.type = EVT_BUT_OPEN; event.val = KM_PRESS; event.customdata = but; @@ -6581,6 +6579,8 @@ static void ui_handle_button_return_submenu(bContext *C, const wmEvent *event, u static void ui_mouse_motion_towards_init_ex(uiPopupBlockHandle *menu, const int xy[2], const bool force) { + BLI_assert(((uiBlock *)menu->region->uiblocks.first)->flag & UI_BLOCK_MOVEMOUSE_QUIT); + if (!menu->dotowards || force) { menu->dotowards = true; menu->towards_xy[0] = xy[0]; @@ -6613,6 +6613,25 @@ static bool ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *me const float margin = MENU_TOWARDS_MARGIN; rctf rect_px; + BLI_assert(block->flag & UI_BLOCK_MOVEMOUSE_QUIT); + + + /* annoying fix for [#36269], this is a bit odd but in fact works quite well + * don't mouse-out of a menu if another menu has been created after it. + * if this causes problems we could remove it and check on a different fix - campbell */ + if (menu->region->next) { + /* am I the last menu (test) */ + ARegion *ar = menu->region->next; + do { + uiBlock *block_iter = ar->uiblocks.first; + if (block_iter && ui_block_is_menu(block_iter)) { + return true; + } + } while ((ar = ar->next)); + } + /* annoying fix end! */ + + if (!menu->dotowards) { return false; } @@ -6837,10 +6856,12 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH but = ui_but_find_activated(ar); if (but && button_modal_state(but->active->state)) { - /* if a button is activated modal, always reset the start mouse - * position of the towards mechanism to avoid loosing focus, - * and don't handle events */ - ui_mouse_motion_towards_reinit(menu, &event->x); + if (block->flag & UI_BLOCK_MOVEMOUSE_QUIT) { + /* if a button is activated modal, always reset the start mouse + * position of the towards mechanism to avoid loosing focus, + * and don't handle events */ + ui_mouse_motion_towards_reinit(menu, &event->x); + } } else if (event->type == TIMER) { if (event->customdata == menu->scrolltimer) @@ -6849,7 +6870,9 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH else { /* for ui_mouse_motion_towards_block */ if (event->type == MOUSEMOVE) { - ui_mouse_motion_towards_init(menu, &event->x); + if (block->flag & UI_BLOCK_MOVEMOUSE_QUIT) { + ui_mouse_motion_towards_init(menu, &event->x); + } /* add menu scroll timer, if needed */ if (ui_menu_scroll_test(block, my)) @@ -7154,11 +7177,12 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH menu->menuretval = UI_RETURN_CANCEL | UI_RETURN_POPUP_OK; } else { - ui_mouse_motion_towards_check(block, menu, &event->x, is_parent_inside == false); /* check mouse moving outside of the menu */ if (inside == 0 && (block->flag & UI_BLOCK_MOVEMOUSE_QUIT)) { uiSafetyRct *saferct; + + ui_mouse_motion_towards_check(block, menu, &event->x, is_parent_inside == false); /* check for all parent rects, enables arrowkeys to be used */ for (saferct = block->saferct.first; saferct; saferct = saferct->next) { @@ -7247,9 +7271,11 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo submenu->menuretval = 0; } - /* for cases where close does not cascade, allow the user to - * move the mouse back towards the menu without closing */ - ui_mouse_motion_towards_reinit(menu, &event->x); + if (block->flag & UI_BLOCK_MOVEMOUSE_QUIT) { + /* for cases where close does not cascade, allow the user to + * move the mouse back towards the menu without closing */ + ui_mouse_motion_towards_reinit(menu, &event->x); + } if (menu->menuretval) return WM_UI_HANDLER_CONTINUE; @@ -7304,12 +7330,16 @@ static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupB } if (do_but_search) { + uiBlock *block = menu->region->uiblocks.first; + retval = ui_handle_menu_button(C, event, menu); - /* when there is a active search button and we close it, - * we need to reinit the mouse coords [#35346] */ - if (ui_but_find_activated(menu->region) != but) { - do_towards_reinit = true; + if (block->flag & UI_BLOCK_MOVEMOUSE_QUIT) { + /* when there is a active search button and we close it, + * we need to reinit the mouse coords [#35346] */ + if (ui_but_find_activated(menu->region) != but) { + do_towards_reinit = true; + } } } else { diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 82352cee05e..d2a8c47b347 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -427,6 +427,8 @@ struct uiKeyNavLock { struct uiPopupBlockHandle { /* internal */ struct ARegion *region; + + /* use only for 'UI_BLOCK_MOVEMOUSE_QUIT' popups */ float towards_xy[2]; double towardstime; bool dotowards; diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 2e80af1b3ad..079ba97aa9d 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -355,7 +355,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in PropertyType type; PropertySubType subtype; uiLayout *sub; - int a, b; + unsigned int a, b; /* retrieve type and subtype */ type = RNA_property_type(prop); @@ -373,8 +373,8 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in /* special check for layer layout */ int butw, buth, unit; int cols = (len >= 20) ? 2 : 1; - int colbuts = len / (2 * cols); - int layer_used = 0; + const unsigned int colbuts = len / (2 * cols); + unsigned int layer_used = 0; uiBlockSetCurLayout(block, uiLayoutAbsolute(layout, FALSE)); diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 9f7d1435195..cfe6e313c58 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -148,7 +148,7 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int if (BLI_rcti_isect_pt(&sa->totrct, mx, my)) { if (sa->spacetype == SPACE_IMAGE) { ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); - if (BLI_rcti_isect_pt(&ar->winrct, mx, my)) { + if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) { SpaceImage *sima = sa->spacedata.first; int mval[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin}; @@ -160,7 +160,7 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int } else if (sa->spacetype == SPACE_NODE) { ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); - if (BLI_rcti_isect_pt(&ar->winrct, mx, my)) { + if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) { SpaceNode *snode = sa->spacedata.first; int mval[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin}; @@ -172,7 +172,7 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int } else if (sa->spacetype == SPACE_CLIP) { ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); - if (BLI_rcti_isect_pt(&ar->winrct, mx, my)) { + if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) { SpaceClip *sc = sa->spacedata.first; int mval[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin}; @@ -704,12 +704,12 @@ static void UI_OT_reports_to_textblock(wmOperatorType *ot) /* EditSource Utility funcs and operator, * note, this includes utility functions and button matching checks */ -struct uiEditSourceStore { +typedef struct uiEditSourceStore { uiBut but_orig; GHash *hash; } uiEditSourceStore; -struct uiEditSourceButStore { +typedef struct uiEditSourceButStore { char py_dbg_fn[FILE_MAX]; int py_dbg_ln; } uiEditSourceButStore; @@ -917,7 +917,7 @@ static void edittranslation_find_po_file(const char *root, const char *uilng, ch /* First, full lang code. */ BLI_snprintf(tstr, sizeof(tstr), "%s.po", uilng); BLI_join_dirfile(path, maxlen, root, uilng); - BLI_join_dirfile(path, maxlen, path, tstr); + BLI_path_append(path, maxlen, tstr); if (BLI_is_file(path)) return; @@ -941,7 +941,7 @@ static void edittranslation_find_po_file(const char *root, const char *uilng, ch BLI_join_dirfile(path, maxlen, root, tstr); strcat(tstr, ".po"); - BLI_join_dirfile(path, maxlen, path, tstr); + BLI_path_append(path, maxlen, tstr); if (BLI_is_file(path)) return; } diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 9c6a606333d..95f47be0b70 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -590,7 +590,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) /* never fails */ id_path = RNA_path_full_ID_py(id); - if (ptr->id.data && ptr->data && prop) { + if (ptr->data && prop) { data_path = RNA_path_from_ID_to_property(ptr, prop); } @@ -2268,10 +2268,8 @@ uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_ block = uiBeginBlock(C, handle->region, __func__, UI_EMBOSS); - if (but->rnaprop) { - if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) { - block->color_profile = FALSE; - } + if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) { + block->color_profile = false; } if (but->block) { @@ -2528,7 +2526,7 @@ uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon) uiStyle *style = UI_GetStyleDraw(); uiPopupMenu *pup = MEM_callocN(sizeof(uiPopupMenu), "popup menu"); uiBut *but; - + pup->block = uiBeginBlock(C, NULL, __func__, UI_EMBOSSP); pup->block->flag |= UI_BLOCK_POPUP_MEMORY; pup->block->puphash = ui_popup_menu_hash(title); @@ -2542,7 +2540,7 @@ uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon) pup->block->handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle"); /* create title button */ - if (title && title[0]) { + if (title[0]) { char titlestr[256]; if (icon) { diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index f45bd1c3463..61cc021800e 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -1147,7 +1147,7 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con) uiBlockSetEmboss(block, UI_EMBOSS); /* name */ - uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, xco + 10, yco, 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); + uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, xco + 0.5f*UI_UNIT_X, yco, 5 * UI_UNIT_X, 0.9f*UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, ""); if (con->flag & CONSTRAINT_DISABLE) uiLayoutSetRedAlert(row, TRUE); @@ -1165,9 +1165,9 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con) uiBlockSetEmboss(block, UI_EMBOSSN); /* draw a ghost icon (for proxy) and also a lock beside it, to show that constraint is "proxy locked" */ - uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_GHOST, xco + 244, yco, 19, 19, + uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_GHOST, xco + 12.2f * UI_UNIT_X, yco, 0.95f * UI_UNIT_X, 0.95f * UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Proxy Protected")); - uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_LOCKED, xco + 262, yco, 19, 19, + uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_LOCKED, xco + 13.1f * UI_UNIT_X, yco, 0.95f * UI_UNIT_X, 0.95f * UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Proxy Protected")); uiBlockSetEmboss(block, UI_EMBOSS); @@ -1226,7 +1226,7 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con) /* Draw constraint data */ if ((con->flag & CONSTRAINT_EXPAND) == 0) { - (yco) -= 21; + (yco) -= 10.5f * UI_UNIT_Y; } else { box = uiLayoutBox(col); diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index dc780d6a4f1..1ef4d43c9f3 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1953,7 +1953,7 @@ void init_userdef_do_versions(void) if (bmain->versionfile < 262 || (bmain->versionfile == 262 && bmain->subversionfile < 4)) { bTheme *btheme; for (btheme = U.themes.first; btheme; btheme = btheme->next) { - if (btheme->tseq.movieclip[0] == 0) { + if (btheme->tseq.movieclip[3] == 0) { rgba_char_args_set(btheme->tseq.movieclip, 32, 32, 143, 255); } } @@ -2002,7 +2002,7 @@ void init_userdef_do_versions(void) if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 11)) { bTheme *btheme; for (btheme = U.themes.first; btheme; btheme = btheme->next) { - if (btheme->tseq.movieclip[0] == 0) { + if (btheme->tseq.mask[3] == 0) { rgba_char_args_set(btheme->tseq.mask, 152, 78, 62, 255); } } diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 772bd6fe671..929b7ae2a5d 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -1288,7 +1288,7 @@ void UI_view2d_smooth_view(bContext *C, ARegion *ar, fac = smooth_view_rect_to_fac(&v2d->cur, cur); } - if (C && U.smooth_viewtx && fac > FLT_EPSILON) { + if (U.smooth_viewtx && fac > FLT_EPSILON) { int changed = FALSE; if (BLI_rctf_compare(&sms.new_cur, &v2d->cur, FLT_EPSILON) == FALSE) diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 924e25e4ef4..fec4ab87996 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -165,7 +165,7 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline int j; - for (j = 0; j < point->tot_uw + 1; j++) { + for (j = 0; j <= point->tot_uw; j++) { float feather_point[2]; int sel = FALSE; diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 5c2aacf0713..c9d3bd19941 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -197,7 +197,7 @@ int ED_mask_feather_find_nearest(const bContext *C, Mask *mask, float normal_co[ int j; MaskSplinePoint *cur_point = &spline->points[i]; - for (j = 0; j < cur_point->tot_uw + 1; j++) { + for (j = 0; j <= cur_point->tot_uw; j++) { float cur_len, vec[2]; vec[0] = (*fp)[0] * scalex; diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index c524aeb06ee..90796e9eb93 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -809,8 +809,9 @@ static int mask_select_more_less(bContext *C, bool more) } for (spline = masklay->splines.first; spline; spline = spline->next) { + const bool cyclic = (spline->flag & MASK_SPLINE_CYCLIC) != 0; + bool start_sel, end_sel, prev_sel, cur_sel; int i; - bool start_sel, end_sel, prev_sel, cur_sel, cyclic = spline->flag & MASK_SPLINE_CYCLIC; /* reselect point if any handle is selected to make the result more predictable */ for (i = 0; i < spline->tot_point; i++) { @@ -826,6 +827,10 @@ static int mask_select_more_less(bContext *C, bool more) start_sel = !!MASKPOINT_ISSEL_KNOT(spline->points); end_sel = !!MASKPOINT_ISSEL_KNOT(&spline->points[spline->tot_point - 1]); } + else { + start_sel = false; + end_sel = false; + } for (i = 0; i < spline->tot_point; i++) { if (i == 0 && !cyclic) { diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 6fd198d9ae6..902906fcf8a 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -198,8 +198,8 @@ static void select_linked_tfaces_with_seams(Mesh *me, const unsigned int index, bool do_it = true; bool mark = false; - BLI_bitmap edge_tag = BLI_BITMAP_NEW(me->totedge, __func__); - BLI_bitmap poly_tag = BLI_BITMAP_NEW(me->totpoly, __func__); + BLI_bitmap *edge_tag = BLI_BITMAP_NEW(me->totedge, __func__); + BLI_bitmap *poly_tag = BLI_BITMAP_NEW(me->totpoly, __func__); if (index != (unsigned int)-1) { /* only put face under cursor in array */ @@ -291,49 +291,37 @@ void paintface_deselect_all_visible(Object *ob, int action, bool flush_flags) me = BKE_mesh_from_object(ob); if (me == NULL) return; - if (action == SEL_INVERT) { + if (action == SEL_TOGGLE) { + action = SEL_SELECT; + mpoly = me->mpoly; a = me->totpoly; while (a--) { - if ((mpoly->flag & ME_HIDE) == 0) { - mpoly->flag ^= ME_FACE_SEL; + if ((mpoly->flag & ME_HIDE) == 0 && mpoly->flag & ME_FACE_SEL) { + action = SEL_DESELECT; + break; } mpoly++; } } - else { - if (action == SEL_TOGGLE) { - action = SEL_SELECT; - - mpoly = me->mpoly; - a = me->totpoly; - while (a--) { - if ((mpoly->flag & ME_HIDE) == 0 && mpoly->flag & ME_FACE_SEL) { - action = SEL_DESELECT; - break; - } - mpoly++; - } - } - mpoly = me->mpoly; - a = me->totpoly; - while (a--) { - if ((mpoly->flag & ME_HIDE) == 0) { - switch (action) { - case SEL_SELECT: - mpoly->flag |= ME_FACE_SEL; - break; - case SEL_DESELECT: - mpoly->flag &= ~ME_FACE_SEL; - break; - case SEL_INVERT: - mpoly->flag ^= ME_FACE_SEL; - break; - } + mpoly = me->mpoly; + a = me->totpoly; + while (a--) { + if ((mpoly->flag & ME_HIDE) == 0) { + switch (action) { + case SEL_SELECT: + mpoly->flag |= ME_FACE_SEL; + break; + case SEL_DESELECT: + mpoly->flag &= ~ME_FACE_SEL; + break; + case SEL_INVERT: + mpoly->flag ^= ME_FACE_SEL; + break; } - mpoly++; } + mpoly++; } if (flush_flags) { @@ -557,49 +545,37 @@ void paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags) me = BKE_mesh_from_object(ob); if (me == NULL) return; - if (action == SEL_INVERT) { + if (action == SEL_TOGGLE) { + action = SEL_SELECT; + mvert = me->mvert; a = me->totvert; while (a--) { - if ((mvert->flag & ME_HIDE) == 0) { - mvert->flag ^= SELECT; + if ((mvert->flag & ME_HIDE) == 0 && mvert->flag & SELECT) { + action = SEL_DESELECT; + break; } mvert++; } } - else { - if (action == SEL_TOGGLE) { - action = SEL_SELECT; - - mvert = me->mvert; - a = me->totvert; - while (a--) { - if ((mvert->flag & ME_HIDE) == 0 && mvert->flag & SELECT) { - action = SEL_DESELECT; - break; - } - mvert++; - } - } - mvert = me->mvert; - a = me->totvert; - while (a--) { - if ((mvert->flag & ME_HIDE) == 0) { - switch (action) { - case SEL_SELECT: - mvert->flag |= SELECT; - break; - case SEL_DESELECT: - mvert->flag &= ~SELECT; - break; - case SEL_INVERT: - mvert->flag ^= SELECT; - break; - } + mvert = me->mvert; + a = me->totvert; + while (a--) { + if ((mvert->flag & ME_HIDE) == 0) { + switch (action) { + case SEL_SELECT: + mvert->flag |= SELECT; + break; + case SEL_DESELECT: + mvert->flag &= ~SELECT; + break; + case SEL_INVERT: + mvert->flag ^= SELECT; + break; } - mvert++; } + mvert++; } /* handle mselect */ diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index e544592365d..f372053db55 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -118,9 +118,10 @@ static int add_primitive_plane_exec(bContext *C, wmOperator *op) obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Plane"), &dia, mat, &was_editmode, loc, rot, layer); em = BKE_editmesh_from_object(obedit); - if (!EDBM_op_call_and_selectf(em, op, "verts.out", - "create_grid x_segments=%i y_segments=%i size=%f matrix=%m4", - 1, 1, RNA_float_get(op->ptr, "radius"), mat)) + if (!EDBM_op_call_and_selectf( + em, op, "verts.out", false, + "create_grid x_segments=%i y_segments=%i size=%f matrix=%m4", + 1, 1, RNA_float_get(op->ptr, "radius"), mat)) { return OPERATOR_CANCELLED; } @@ -162,8 +163,10 @@ static int add_primitive_cube_exec(bContext *C, wmOperator *op) obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Cube"), &dia, mat, &was_editmode, loc, rot, layer); em = BKE_editmesh_from_object(obedit); - if (!EDBM_op_call_and_selectf(em, op, "verts.out", "create_cube matrix=%m4 size=%f", - mat, RNA_float_get(op->ptr, "radius") * 2.0f)) + if (!EDBM_op_call_and_selectf( + em, op, "verts.out", false, + "create_cube matrix=%m4 size=%f", + mat, RNA_float_get(op->ptr, "radius") * 2.0f)) { return OPERATOR_CANCELLED; } @@ -216,10 +219,11 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op) obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Circle"), &dia, mat, &was_editmode, loc, rot, layer); em = BKE_editmesh_from_object(obedit); - if (!EDBM_op_call_and_selectf(em, op, "verts.out", - "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"), - cap_end, cap_tri, mat)) + if (!EDBM_op_call_and_selectf( + em, op, "verts.out", false, + "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"), + cap_end, cap_tri, mat)) { return OPERATOR_CANCELLED; } @@ -269,7 +273,7 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op) em = BKE_editmesh_from_object(obedit); if (!EDBM_op_call_and_selectf( - em, op, "verts.out", + em, op, "verts.out", false, "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"), @@ -329,7 +333,7 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op) em = BKE_editmesh_from_object(obedit); if (!EDBM_op_call_and_selectf( - em, op, "verts.out", + em, op, "verts.out", false, "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"), RNA_float_get(op->ptr, "radius2"), cap_end, cap_tri, RNA_float_get(op->ptr, "depth"), mat)) @@ -385,11 +389,12 @@ static int add_primitive_grid_exec(bContext *C, wmOperator *op) obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Grid"), &dia, mat, &was_editmode, loc, rot, layer); em = BKE_editmesh_from_object(obedit); - if (!EDBM_op_call_and_selectf(em, op, "verts.out", - "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, "radius"), mat)) + if (!EDBM_op_call_and_selectf( + em, op, "verts.out", false, + "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, "radius"), mat)) { return OPERATOR_CANCELLED; } @@ -444,7 +449,10 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op) em = BKE_editmesh_from_object(obedit); - if (!EDBM_op_call_and_selectf(em, op, "verts.out", "create_monkey matrix=%m4", mat)) { + if (!EDBM_op_call_and_selectf( + em, op, "verts.out", false, + "create_monkey matrix=%m4", mat)) + { return OPERATOR_CANCELLED; } @@ -485,10 +493,11 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op) obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Sphere"), &dia, mat, &was_editmode, loc, rot, layer); em = BKE_editmesh_from_object(obedit); - if (!EDBM_op_call_and_selectf(em, op, "verts.out", - "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"), mat)) + if (!EDBM_op_call_and_selectf( + em, op, "verts.out", false, + "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"), mat)) { return OPERATOR_CANCELLED; } @@ -538,7 +547,7 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op) em = BKE_editmesh_from_object(obedit); if (!EDBM_op_call_and_selectf( - em, op, "verts.out", + em, op, "verts.out", false, "create_icosphere subdivisions=%i diameter=%f matrix=%m4", RNA_int_get(op->ptr, "subdivisions"), RNA_float_get(op->ptr, "size"), mat)) diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c index 65c528dbe03..b38f09b1dec 100644 --- a/source/blender/editors/mesh/editmesh_extrude.c +++ b/source/blender/editors/mesh/editmesh_extrude.c @@ -713,7 +713,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op) BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; BMOperator spinop; - float cent[3], axis[3], imat[3][3]; + float cent[3], axis[3]; float d[3] = {0.0f, 0.0f, 0.0f}; int steps, dupli; float angle; @@ -726,15 +726,10 @@ static int edbm_spin_exec(bContext *C, wmOperator *op) angle = -angle; dupli = RNA_boolean_get(op->ptr, "dupli"); - /* undo object transformation */ - copy_m3_m4(imat, obedit->imat); - sub_v3_v3(cent, obedit->obmat[3]); - mul_m3_v3(imat, cent); - mul_m3_v3(imat, axis); - + /* keep the values in worldspace since we're passing the obmat */ 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, angle, dupli)) + "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f space=%m4 use_duplicate=%b", + BM_ELEM_SELECT, cent, axis, d, steps, angle, obedit->obmat, dupli)) { return OPERATOR_CANCELLED; } @@ -800,8 +795,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op) BMVert *eve, *v1, *v2; BMIter iter, eiter; BMOperator spinop; - float dvec[3], nor[3], cent[3], axis[3]; - float imat[3][3]; + float dvec[3], nor[3], cent[3], axis[3], v1_co_global[3], v2_co_global[3]; int steps, turns; int valence; @@ -811,13 +805,6 @@ static int edbm_screw_exec(bContext *C, wmOperator *op) RNA_float_get_array(op->ptr, "center", cent); RNA_float_get_array(op->ptr, "axis", axis); - /* undo object transformation */ - copy_m3_m4(imat, obedit->imat); - sub_v3_v3(cent, obedit->obmat[3]); - mul_m3_v3(imat, cent); - mul_m3_v3(imat, axis); - - /* find two vertices with valence count == 1, more or less is wrong */ v1 = NULL; v2 = NULL; @@ -850,15 +837,17 @@ static int edbm_screw_exec(bContext *C, wmOperator *op) } /* calculate dvec */ - sub_v3_v3v3(dvec, v1->co, v2->co); + mul_v3_m4v3(v1_co_global, obedit->obmat, v1->co); + mul_v3_m4v3(v2_co_global, obedit->obmat, v2->co); + sub_v3_v3v3(dvec, v1_co_global, v2_co_global); mul_v3_fl(dvec, 1.0f / steps); - if (dot_v3v3(nor, dvec) > 0.000f) + if (dot_v3v3(nor, dvec) > 0.0f) negate_v3(dvec); 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, dvec, turns * steps, DEG2RADF(360.0f * turns), false)) + "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f space=%m4 use_duplicate=%b", + BM_ELEM_SELECT, cent, axis, dvec, turns * steps, DEG2RADF(360.0f * turns), obedit->obmat, false)) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 50db460e5bc..e1d0a412ce7 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -38,6 +38,7 @@ #include "BLI_listbase.h" #include "BLI_string.h" #include "BLI_array.h" +#include "BLI_alloca.h" #include "BLI_linklist.h" #include "BLI_math.h" #include "BLI_smallhash.h" @@ -2623,15 +2624,15 @@ static bool knife_edge_in_face(KnifeTool_OpData *UNUSED(kcd), KnifeEdge *kfe, BM /* Split face f with KnifeEdges on chain. f remains as one side, the face formed is put in *newface. * The new face will be on the left side of the chain as viewed from the normal-out side of f. */ -static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *chain, BMFace **newface) +static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *chain, BMFace **r_f_new) { BMesh *bm = kcd->em->bm; KnifeEdge *kfe, *kfelast; BMVert *v1, *v2; - BMFace *fnew; + BMFace *f_new; Ref *ref; KnifeVert *kfv, *kfvprev; - BMLoop *lnew, *l_iter; + BMLoop *l_new, *l_iter; int i; int nco = BLI_countlist(chain) - 1; float (*cos)[3] = BLI_array_alloca(cos, nco); @@ -2652,23 +2653,21 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha kfvprev = kfv; } BLI_assert(i == nco); - lnew = NULL; + l_new = NULL; if (nco == 0) { /* Want to prevent creating two-sided polygons */ if (BM_edge_exists(v1, v2)) { - *newface = NULL; + f_new = NULL; } else { - *newface = BM_face_split(bm, f, v1, v2, &lnew, NULL, true); + f_new = BM_face_split(bm, f, v1, v2, &l_new, NULL, true); } } else { - fnew = BM_face_split_n(bm, f, v1, v2, cos, nco, &lnew, NULL); - *newface = fnew; - - if (fnew) { + f_new = BM_face_split_n(bm, f, v1, v2, cos, nco, &l_new, NULL); + if (f_new) { /* Now go through lnew chain matching up chain kv's and assign real v's to them */ - for (l_iter = lnew->next, i = 0; i < nco; l_iter = l_iter->next, i++) { + for (l_iter = l_new->next, i = 0; i < nco; l_iter = l_iter->next, i++) { BLI_assert(equals_v3v3(cos[i], l_iter->v->co)); if (kcd->select_result) { BM_edge_select_set(bm, l_iter->e, true); @@ -2680,10 +2679,15 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha /* the select chain above doesnt account for the first loop */ if (kcd->select_result) { - if (lnew) { - BM_edge_select_set(bm, lnew->e, true); + if (l_new) { + BM_edge_select_set(bm, l_new->e, true); } } + else { + BM_elem_select_copy(bm, bm, f_new, f); + } + + *r_f_new = f_new; } static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfedges) @@ -2887,6 +2891,7 @@ static void knifetool_finish_ex(KnifeTool_OpData *kcd) knife_make_cuts(kcd); #endif + EDBM_selectmode_flush(kcd->em); EDBM_mesh_normals_update(kcd->em); EDBM_update_generic(kcd->em, true, true); } diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index 3c1b210d171..892b773b1ba 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -125,9 +125,9 @@ static void edgering_find_order(BMEdge *lasteed, BMEdge *eed, l = eed->l; /* find correct order for v[1] */ - if (!(BM_edge_in_face(l->f, eed) && BM_edge_in_face(l->f, lasteed))) { + if (!(BM_edge_in_face(eed, l->f) && BM_edge_in_face(lasteed, l->f))) { BM_ITER_ELEM (l, &liter, l, BM_LOOPS_OF_LOOP) { - if (BM_edge_in_face(l->f, eed) && BM_edge_in_face(l->f, lasteed)) + if (BM_edge_in_face(eed, l->f) && BM_edge_in_face(lasteed, l->f)) break; } } diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index c027c1bbcd1..1360a180b2d 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -510,24 +510,6 @@ static void edbm_tagged_loop_pairs_do_fill_faces(BMesh *bm, UnorderedLoopPair *u /* --- end 'face-fill' code --- */ - -static bool edbm_rip_call_edgesplit(BMEditMesh *em, wmOperator *op) -{ - BMOperator bmop; - - if (!EDBM_op_init(em, &bmop, op, "split_edges edges=%he verts=%hv use_verts=%b", - BM_ELEM_TAG, BM_ELEM_SELECT, true)) - { - return false; - } - BMO_op_exec(em->bm, &bmop); - if (!EDBM_op_finish(em, &bmop, op, true)) { - return false; - } - - return true; -} - /** * This is the main vert ripping function (rip when one vertex is selected) */ @@ -648,11 +630,9 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve BM_vert_select_set(bm, v, false); - if (bmesh_vert_separate(bm, v, &vout, &vout_len) == false) { - BKE_report(op->reports, RPT_ERROR, "Error ripping vertex from faces"); - return OPERATOR_CANCELLED; - } - else if (vout_len < 2) { + bmesh_vert_separate(bm, v, &vout, &vout_len, true); + + if (vout_len < 2) { MEM_freeN(vout); /* set selection back to avoid active-unselected vertex */ BM_vert_select_set(bm, v, true); @@ -786,10 +766,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve fill_uloop_pairs = edbm_tagged_loop_pairs_to_fill(bm); } - if (!edbm_rip_call_edgesplit(em, op)) { - if (fill_uloop_pairs) MEM_freeN(fill_uloop_pairs); - return OPERATOR_CANCELLED; - } + BM_mesh_edgesplit(em->bm, true, true, true); } dist = FLT_MAX; @@ -951,10 +928,7 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, const wmEvent *eve fill_uloop_pairs = edbm_tagged_loop_pairs_to_fill(bm); } - if (!edbm_rip_call_edgesplit(em, op)) { - if (fill_uloop_pairs) MEM_freeN(fill_uloop_pairs); - return OPERATOR_CANCELLED; - } + BM_mesh_edgesplit(em->bm, true, true, true); /* note: the output of the bmesh operator is ignored, since we built * the contiguous loop pairs to split already, its possible that some @@ -965,6 +939,9 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, const wmEvent *eve ar, projectMat, fmval); MEM_freeN(eloop_pairs); + /* deselect loose verts */ + BM_mesh_select_mode_clean_ex(bm, SCE_SELECT_EDGE); + if (do_fill && fill_uloop_pairs) { edbm_tagged_loop_pairs_do_fill_faces(bm, fill_uloop_pairs); MEM_freeN(fill_uloop_pairs); @@ -975,7 +952,7 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, const wmEvent *eve return OPERATOR_CANCELLED; } - EDBM_selectmode_flush(em); + BM_select_history_validate(bm); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index f50ff45e83b..a1f1f6bd83f 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -1590,8 +1590,7 @@ void EDBM_selectmode_set(BMEditMesh *em) } if (em->bm->totfacesel) { - efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL); - for (; efa; efa = BM_iter_step(&iter)) { + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) { BM_face_select_set(em->bm, efa, true); } @@ -2427,9 +2426,6 @@ static void walker_deselect_nth(BMEditMesh *em, int nth, int offset, BMHeader *h static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa) { - BMVert *v; - BMEdge *e; - BMFace *f; BMIter iter; BMElem *ele; @@ -2440,7 +2436,7 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed, EDBM_selectmode_flush(em); ele = BM_mesh_active_elem_get(em->bm); - if (ele) { + if (ele && BM_elem_flag_test(ele, BM_ELEM_SELECT)) { switch (ele->head.htype) { case BM_VERT: *r_eve = (BMVert *)ele; @@ -2455,6 +2451,7 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed, } if (em->selectmode & SCE_SELECT_VERTEX) { + BMVert *v; BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { *r_eve = v; @@ -2463,6 +2460,7 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed, } } else if (em->selectmode & SCE_SELECT_EDGE) { + BMEdge *e; BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { *r_eed = e; @@ -2471,8 +2469,8 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed, } } else if (em->selectmode & SCE_SELECT_FACE) { - f = BM_mesh_active_face_get(em->bm, true, false); - if (f) { + BMFace *f = BM_mesh_active_face_get(em->bm, true, false); + if (f && BM_elem_flag_test(f, BM_ELEM_SELECT)) { *r_efa = f; return; } @@ -2619,7 +2617,7 @@ static int edbm_select_linked_flat_faces_exec(bContext *C, wmOperator *op) BMLoop *l, *l2; const float angle_limit = RNA_float_get(op->ptr, "sharpness"); - BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false); + BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false); BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { @@ -3076,10 +3074,10 @@ void MESH_OT_region_to_loop(wmOperatorType *ot) static int loop_find_region(BMLoop *l, int flag, SmallHash *fhash, BMFace ***region_out) { - BLI_array_declare(region); - BLI_array_declare(stack); BMFace **region = NULL; BMFace **stack = NULL; + BLI_array_declare(region); + BLI_array_declare(stack); BMFace *f; BLI_array_append(stack, l->f); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index bf9dd03f170..4610bb89ae4 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -428,8 +428,9 @@ static int edbm_add_edge_face__smooth_get(BMesh *bm) * Function used to get a fixed number of edges linked to a vertex that passes a test function. * This is used so we can request all boundary edges connected to a vertex for eg. */ -static int edbm_add_edge_face_exec__vert_edge_lookup(BMVert *v, BMEdge *e_used, BMEdge **e_arr, const int e_arr_len, - bool (* func)(BMEdge *)) +static int edbm_add_edge_face_exec__vert_edge_lookup( + BMVert *v, BMEdge *e_used, BMEdge **e_arr, const int e_arr_len, + bool (* func)(const BMEdge *)) { BMIter iter; BMEdge *e_iter; @@ -635,7 +636,7 @@ void MESH_OT_edge_face_add(wmOperatorType *ot) /* ************************* SEAMS AND EDGES **************** */ -static int edbm_mark_seam(bContext *C, wmOperator *op) +static int edbm_mark_seam_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *obedit = CTX_data_edit_object(C); @@ -681,7 +682,7 @@ void MESH_OT_mark_seam(wmOperatorType *ot) ot->description = "(Un)mark selected edges as a seam"; /* api callbacks */ - ot->exec = edbm_mark_seam; + ot->exec = edbm_mark_seam_exec; ot->poll = ED_operator_editmesh; /* flags */ @@ -690,7 +691,7 @@ void MESH_OT_mark_seam(wmOperatorType *ot) RNA_def_boolean(ot->srna, "clear", 0, "Clear", ""); } -static int edbm_mark_sharp(bContext *C, wmOperator *op) +static int edbm_mark_sharp_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); Mesh *me = ((Mesh *)obedit->data); @@ -735,7 +736,7 @@ void MESH_OT_mark_sharp(wmOperatorType *ot) ot->description = "(Un)mark selected edges as sharp"; /* api callbacks */ - ot->exec = edbm_mark_sharp; + ot->exec = edbm_mark_sharp_exec; ot->poll = ED_operator_editmesh; /* flags */ @@ -745,7 +746,7 @@ void MESH_OT_mark_sharp(wmOperatorType *ot) } -static int edbm_vert_connect(bContext *C, wmOperator *op) +static int edbm_vert_connect_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); @@ -795,33 +796,79 @@ void MESH_OT_vert_connect(wmOperatorType *ot) ot->description = "Connect 2 vertices of a face by an edge, splitting the face in two"; /* api callbacks */ - ot->exec = edbm_vert_connect; + ot->exec = edbm_vert_connect_exec; ot->poll = ED_operator_editmesh; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -static int edbm_edge_split_exec(bContext *C, wmOperator *op) + +static int edbm_vert_connect_nonplaner_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); - BMesh *bm = em->bm; - BMOperator bmop; - int len = 0; - - if (!EDBM_op_init(em, &bmop, op, "split_edges edges=%he", BM_ELEM_SELECT)) { + + const float angle_limit = RNA_float_get(op->ptr, "angle_limit"); + + if (!EDBM_op_call_and_selectf( + em, op, + "faces.out", true, + "connect_verts_nonplanar faces=%hf angle_limit=%f", + BM_ELEM_SELECT, angle_limit)) + { return OPERATOR_CANCELLED; } - BMO_op_exec(bm, &bmop); - len = BMO_slot_get(bmop.slots_out, "edges.out")->len; - if (!EDBM_op_finish(em, &bmop, op, true)) { + + + EDBM_update_generic(em, true, true); + return OPERATOR_FINISHED; +} + +void MESH_OT_vert_connect_nonplanar(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Split Non-Planar Faces"; + ot->idname = "MESH_OT_vert_connect_nonplanar"; + ot->description = "Split non-planar faces that exceed the angle threshold"; + + /* api callbacks */ + ot->exec = edbm_vert_connect_nonplaner_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + prop = RNA_def_float_rotation(ot->srna, "angle_limit", 0, NULL, 0.0f, DEG2RADF(180.0f), + "Max Angle", "Angle limit", 0.0f, DEG2RADF(180.0f)); + RNA_def_property_float_default(prop, DEG2RADF(5.0f)); +} + + +static int edbm_edge_split_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + + if (!EDBM_op_call_and_selectf( + em, op, + "edges.out", false, + "split_edges edges=%he", + BM_ELEM_SELECT)) + { return OPERATOR_CANCELLED; } + if (em->selectmode == SCE_SELECT_FACE) { + EDBM_select_flush(em); + } + EDBM_update_generic(em, true, true); - return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED; + return OPERATOR_FINISHED; } void MESH_OT_edge_split(wmOperatorType *ot) @@ -2277,7 +2324,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) /* store percentage of edge cut for KNIFE_EXACT here.*/ 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)) { + BM_ITER_MESH (be, &iter, bm, BM_EDGES_OF_MESH) { bool is_cut = false; if (BM_elem_flag_test(be, BM_ELEM_SELECT)) { const float *sco_a = screen_vert_coords[BM_elem_index_get(be->v1)]; @@ -2752,15 +2799,56 @@ void MESH_OT_fill_grid(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static int edbm_fill_holes_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + const int sides = RNA_int_get(op->ptr, "sides"); + + if (!EDBM_op_call_and_selectf( + em, op, + "faces.out", true, + "holes_fill edges=%he sides=%i", + BM_ELEM_SELECT, sides)) + { + return OPERATOR_CANCELLED; + } + + EDBM_update_generic(em, true, true); + + return OPERATOR_FINISHED; + +} + +void MESH_OT_fill_holes(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Fill Holes"; + ot->idname = "MESH_OT_fill_holes"; + ot->description = "Fill in holes (boundary edge loops)"; + /* api callbacks */ + ot->exec = edbm_fill_holes_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_int(ot->srna, "sides", 4, 0, INT_MAX, "Sides", "Number of sides (zero disables)", 0, 100); +} static int edbm_beautify_fill_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); - if (!EDBM_op_callf(em, op, "beautify_fill faces=%hf edges=ae", BM_ELEM_SELECT)) + if (!EDBM_op_call_and_selectf( + em, op, "geom.out", true, + "beautify_fill faces=%hf edges=ae", + BM_ELEM_SELECT)) + { return OPERATOR_CANCELLED; + } EDBM_update_generic(em, true, true); @@ -2855,11 +2943,14 @@ static int edbm_quads_convert_to_tris_exec(bContext *C, wmOperator *op) EDBM_op_init(em, &bmop, op, "triangulate faces=%hf use_beauty=%b", BM_ELEM_SELECT, use_beauty); BMO_op_exec(em->bm, &bmop); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true); + /* now call beauty fill */ if (use_beauty) { - EDBM_op_callf(em, op, - "beautify_fill faces=%S edges=%S", - &bmop, "faces.out", &bmop, "edges.out"); + EDBM_op_call_and_selectf( + em, op, "geom.out", true, + "beautify_fill faces=%S edges=%S", + &bmop, "faces.out", &bmop, "edges.out"); } if (!EDBM_op_finish(em, &bmop, op, true)) { @@ -2901,9 +2992,11 @@ static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op) dovcols = RNA_boolean_get(op->ptr, "vcols"); domaterials = RNA_boolean_get(op->ptr, "materials"); - if (!EDBM_op_callf(em, op, - "join_triangles faces=%hf limit=%f cmp_sharp=%b cmp_uvs=%b cmp_vcols=%b cmp_materials=%b", - BM_ELEM_SELECT, limit, dosharp, douvs, dovcols, domaterials)) + if (!EDBM_op_call_and_selectf( + em, op, + "faces.out", true, + "join_triangles faces=%hf limit=%f cmp_sharp=%b cmp_uvs=%b cmp_vcols=%b cmp_materials=%b", + BM_ELEM_SELECT, limit, dosharp, douvs, dovcols, domaterials)) { return OPERATOR_CANCELLED; } @@ -2947,6 +3040,17 @@ void MESH_OT_tris_convert_to_quads(wmOperatorType *ot) /* -------------------------------------------------------------------- */ /* Dissolve */ +static void edbm_dissolve_prop__use_verts(wmOperatorType *ot) +{ + RNA_def_boolean(ot->srna, "use_verts", 0, "Dissolve Verts", + "Dissolve remaining vertices"); +} +static void edbm_dissolve_prop__use_face_split(wmOperatorType *ot) +{ + RNA_def_boolean(ot->srna, "use_face_split", 0, "Face Split", + "Split off face corners to maintain surrounding geometry"); +} + static int edbm_dissolve_verts_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); @@ -2976,8 +3080,7 @@ void MESH_OT_dissolve_verts(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_boolean(ot->srna, "use_face_split", 0, "Face Split", - "Split off face corners to maintain surrounding geometry"); + edbm_dissolve_prop__use_face_split(ot); } static int edbm_dissolve_edges_exec(bContext *C, wmOperator *op) @@ -3014,9 +3117,8 @@ void MESH_OT_dissolve_edges(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_boolean(ot->srna, "use_verts", 0, "Dissolve Verts", "Dissolve remaining vertices"); - RNA_def_boolean(ot->srna, "use_face_split", 0, "Face Split", - "Split off face corners to maintain surrounding geometry"); + edbm_dissolve_prop__use_verts(ot); + edbm_dissolve_prop__use_face_split(ot); } static int edbm_dissolve_faces_exec(bContext *C, wmOperator *op) @@ -3026,8 +3128,14 @@ static int edbm_dissolve_faces_exec(bContext *C, wmOperator *op) const bool use_verts = RNA_boolean_get(op->ptr, "use_verts"); - if (!EDBM_op_callf(em, op, "dissolve_faces faces=%hf use_verts=%b", BM_ELEM_SELECT, use_verts)) + if (!EDBM_op_call_and_selectf( + em, op, + "region.out", true, + "dissolve_faces faces=%hf use_verts=%b", + BM_ELEM_SELECT, use_verts)) + { return OPERATOR_CANCELLED; + } EDBM_update_generic(em, true, true); @@ -3048,10 +3156,44 @@ void MESH_OT_dissolve_faces(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_boolean(ot->srna, "use_verts", 0, "Dissolve Verts", "Dissolve remaining vertices"); + edbm_dissolve_prop__use_verts(ot); } +static int edbm_dissolve_mode_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + + if (em->selectmode & SCE_SELECT_VERTEX) { + return edbm_dissolve_verts_exec(C, op); + } + else if (em->selectmode & SCE_SELECT_EDGE) { + return edbm_dissolve_edges_exec(C, op); + } + else { + return edbm_dissolve_faces_exec(C, op); + } +} + +void MESH_OT_dissolve_mode(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Dissolve Selection"; + ot->description = "Dissolve geometry based on the selection mode"; + ot->idname = "MESH_OT_dissolve_mode"; + + /* api callbacks */ + ot->exec = edbm_dissolve_mode_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + edbm_dissolve_prop__use_verts(ot); + edbm_dissolve_prop__use_face_split(ot); +} + static int edbm_dissolve_limited_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); @@ -3094,12 +3236,10 @@ static int edbm_dissolve_limited_exec(bContext *C, wmOperator *op) dissolve_flag = BM_ELEM_SELECT; } - if (!EDBM_op_callf(em, op, - "dissolve_limit edges=%he verts=%hv angle_limit=%f use_dissolve_boundaries=%b delimit=%i", - dissolve_flag, dissolve_flag, angle_limit, use_dissolve_boundaries, delimit)) - { - return OPERATOR_CANCELLED; - } + EDBM_op_call_and_selectf( + em, op, "region.out", true, + "dissolve_limit edges=%he verts=%hv angle_limit=%f use_dissolve_boundaries=%b delimit=%i", + dissolve_flag, dissolve_flag, angle_limit, use_dissolve_boundaries, delimit); EDBM_update_generic(em, true, true); @@ -3147,7 +3287,7 @@ static int edbm_delete_edgeloop_exec(bContext *C, wmOperator *op) BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, false); BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { + if (BM_elem_flag_test(e, BM_ELEM_SELECT) && e->l) { BMLoop *l_iter = e->l; do { BM_elem_flag_enable(l_iter->f, BM_ELEM_TAG); @@ -3936,6 +4076,7 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op) const bool use_cyclic = (type == 1); const bool use_merge = RNA_boolean_get(op->ptr, "use_merge"); const float merge_factor = RNA_float_get(op->ptr, "merge_factor"); + const int twist_offset = RNA_int_get(op->ptr, "twist_offset"); const bool use_faces = (em->bm->totfacesel != 0); char edge_hflag; @@ -3963,8 +4104,8 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op) } EDBM_op_init(em, &bmop, op, - "bridge_loops edges=%he use_pairs=%b use_cyclic=%b use_merge=%b merge_factor=%f", - edge_hflag, use_pairs, use_cyclic, use_merge, merge_factor); + "bridge_loops edges=%he use_pairs=%b use_cyclic=%b use_merge=%b merge_factor=%f twist_offset=%i", + edge_hflag, use_pairs, use_cyclic, use_merge, merge_factor, twist_offset); BMO_op_exec(em->bm, &bmop); @@ -3991,14 +4132,23 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op) mesh_operator_edgering_props_get(op, &op_props); if (op_props.cuts) { + BMOperator bmop_subd; /* we only need face normals updated */ EDBM_mesh_normals_update(em); - BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS, - "subdivide_edgering edges=%S interp_mode=%i cuts=%i smooth=%f " - "profile_shape=%i profile_shape_factor=%f", - &bmop, "edges.out", op_props.interp_mode, op_props.cuts, op_props.smooth, - op_props.profile_shape, op_props.profile_shape_factor); + BMO_op_initf( + em->bm, &bmop_subd, op->flag, + "subdivide_edgering edges=%S interp_mode=%i cuts=%i smooth=%f " + "profile_shape=%i profile_shape_factor=%f", + &bmop, "edges.out", op_props.interp_mode, op_props.cuts, op_props.smooth, + op_props.profile_shape, op_props.profile_shape_factor + ); + BMO_op_exec(em->bm, &bmop_subd); + + BMO_slot_buffer_hflag_enable(em->bm, bmop_subd.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true); + + BMO_op_finish(em->bm, &bmop_subd); + } } } @@ -4044,6 +4194,7 @@ void MESH_OT_bridge_edge_loops(wmOperatorType *ot) RNA_def_boolean(ot->srna, "use_merge", false, "Merge", "Merge rather than creating faces"); RNA_def_float(ot->srna, "merge_factor", 0.5f, 0.0f, 1.0f, "Merge Factor", "", 0.0f, 1.0f); + RNA_def_int(ot->srna, "twist_offset", 0, -1000, 1000, "Twist", "Twist offset for closed loops", -1000, 1000); mesh_operator_edgering_props(ot, 0); } @@ -4382,7 +4533,7 @@ void MESH_OT_symmetry_snap(struct wmOperatorType *ot) #ifdef WITH_FREESTYLE -static int edbm_mark_freestyle_edge(bContext *C, wmOperator *op) +static int edbm_mark_freestyle_edge_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); Mesh *me = (Mesh *)obedit->data; @@ -4435,7 +4586,7 @@ void MESH_OT_mark_freestyle_edge(wmOperatorType *ot) ot->idname = "MESH_OT_mark_freestyle_edge"; /* api callbacks */ - ot->exec = edbm_mark_freestyle_edge; + ot->exec = edbm_mark_freestyle_edge_exec; ot->poll = ED_operator_editmesh; /* flags */ diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index f64ea569100..46cab3b4416 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -35,7 +35,7 @@ #include "DNA_object_types.h" #include "BLI_math.h" -#include "BLI_array.h" +#include "BLI_alloca.h" #include "BKE_DerivedMesh.h" #include "BKE_context.h" @@ -270,7 +270,9 @@ bool EDBM_op_callf(BMEditMesh *em, wmOperator *op, const char *fmt, ...) return EDBM_op_finish(em, &bmop, op, true); } -bool EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op, const char *select_slot_out, const char *fmt, ...) +bool EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op, + const char *select_slot_out, const bool select_extend, + const char *fmt, ...) { BMOpSlot *slot_select_out; BMesh *bm = em->bm; @@ -294,8 +296,11 @@ bool EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op, const char *select slot_select_out = BMO_slot_get(bmop.slots_out, select_slot_out); hflag = slot_select_out->slot_subtype.elem & BM_ALL_NOLOOP; + BLI_assert(hflag != 0); - BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false); + if (select_extend == false) { + 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, hflag, BM_ELEM_SELECT, true); @@ -1478,7 +1483,7 @@ static BMFace *edge_ray_cast(struct BMBVHTree *tree, const float co[3], const fl { BMFace *f = BKE_bmbvh_ray_cast(tree, co, dir, NULL, r_hitout, NULL); - if (f && BM_edge_in_face(f, e)) + if (f && BM_edge_in_face(e, f)) return NULL; return f; diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 52a8ccc4aab..e8cbf0926d4 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -37,8 +37,8 @@ #include "DNA_view3d_types.h" #include "BLI_utildefines.h" +#include "BLI_alloca.h" #include "BLI_path_util.h" -#include "BLI_array.h" #include "BLI_math.h" #include "BKE_context.h" diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index a4706618765..9dcb38b9f87 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -59,7 +59,8 @@ struct LinkNode; /* Calls a bmesh op, reporting errors to the user, etc */ bool EDBM_op_callf(struct BMEditMesh *em, struct wmOperator *op, const char *fmt, ...); bool EDBM_op_call_and_selectf(struct BMEditMesh *em, struct wmOperator *op, - const char *selectslot, const char *fmt, ...); + const char *select_slot, const bool select_replace, + const char *fmt, ...); /* Same as above, but doesn't report errors.*/ bool EDBM_op_call_silentf(struct BMEditMesh *em, const char *fmt, ...); @@ -168,6 +169,7 @@ void MESH_OT_normals_make_consistent(struct wmOperatorType *ot); void MESH_OT_vertices_smooth(struct wmOperatorType *ot); void MESH_OT_vertices_smooth_laplacian(struct wmOperatorType *ot); void MESH_OT_vert_connect(struct wmOperatorType *ot); +void MESH_OT_vert_connect_nonplanar(struct wmOperatorType *ot); void MESH_OT_edge_split(struct wmOperatorType *ot); void MESH_OT_bridge_edge_loops(struct wmOperatorType *ot); void MESH_OT_wireframe(struct wmOperatorType *ot); @@ -198,12 +200,14 @@ void MESH_OT_knife_cut(struct wmOperatorType *ot); void MESH_OT_separate(struct wmOperatorType *ot); void MESH_OT_fill(struct wmOperatorType *ot); void MESH_OT_fill_grid(struct wmOperatorType *ot); +void MESH_OT_fill_holes(struct wmOperatorType *ot); void MESH_OT_beautify_fill(struct wmOperatorType *ot); void MESH_OT_quads_convert_to_tris(struct wmOperatorType *ot); void MESH_OT_tris_convert_to_quads(struct wmOperatorType *ot); void MESH_OT_dissolve_verts(struct wmOperatorType *ot); void MESH_OT_dissolve_edges(struct wmOperatorType *ot); void MESH_OT_dissolve_faces(struct wmOperatorType *ot); +void MESH_OT_dissolve_mode(struct wmOperatorType *ot); void MESH_OT_dissolve_limited(struct wmOperatorType *ot); void MESH_OT_delete_edgeloop(struct wmOperatorType *ot); void MESH_OT_edge_face_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c index 3d8718ef887..66e577975b6 100644 --- a/source/blender/editors/mesh/mesh_navmesh.c +++ b/source/blender/editors/mesh/mesh_navmesh.c @@ -461,7 +461,7 @@ static int navmesh_create_exec(bContext *C, wmOperator *op) unsigned int lay = 0; int nverts = 0, ntris = 0; - int *tris = 0; + int *tris = NULL; float *verts = NULL; createVertsTrisData(C, obs, &nverts, &verts, &ntris, &tris, &lay); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index d6dff32f097..fb0ec4e5768 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -102,12 +102,14 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_fill); WM_operatortype_append(MESH_OT_fill_grid); + WM_operatortype_append(MESH_OT_fill_holes); WM_operatortype_append(MESH_OT_beautify_fill); WM_operatortype_append(MESH_OT_quads_convert_to_tris); WM_operatortype_append(MESH_OT_tris_convert_to_quads); WM_operatortype_append(MESH_OT_dissolve_verts); WM_operatortype_append(MESH_OT_dissolve_edges); WM_operatortype_append(MESH_OT_dissolve_faces); + WM_operatortype_append(MESH_OT_dissolve_mode); WM_operatortype_append(MESH_OT_dissolve_limited); WM_operatortype_append(MESH_OT_delete_edgeloop); WM_operatortype_append(MESH_OT_faces_shade_smooth); @@ -156,6 +158,7 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_solidify); WM_operatortype_append(MESH_OT_select_nth); WM_operatortype_append(MESH_OT_vert_connect); + WM_operatortype_append(MESH_OT_vert_connect_nonplanar); WM_operatortype_append(MESH_OT_knife_tool); WM_operatortype_append(MESH_OT_knife_project); @@ -383,6 +386,9 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_delete", XKEY, KM_PRESS, 0, 0); WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_delete", DELKEY, KM_PRESS, 0, 0); + + WM_keymap_add_item(keymap, "MESH_OT_dissolve_mode", XKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "MESH_OT_dissolve_mode", DELKEY, KM_PRESS, KM_CTRL, 0); kmi = WM_keymap_add_item(keymap, "MESH_OT_knife_tool", KKEY, KM_PRESS, 0, 0); RNA_boolean_set(kmi->ptr, "use_occlude_geometry", true); diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index ed05d2a01a5..d012a8ac656 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -1336,7 +1336,7 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int const float mval_f[2] = {(float)mval[0], (float)mval[1]}; - VertPickData data = {0}; + VertPickData data = {NULL}; ED_view3d_init_mats_rv3d(ob, rv3d); @@ -1351,7 +1351,7 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int data.len_best = FLT_MAX; data.v_idx_best = -1; - dm->foreachMappedVert(dm, ed_mesh_pick_vert__mapFunc, &data); + dm->foreachMappedVert(dm, ed_mesh_pick_vert__mapFunc, &data, DM_FOREACH_NOP); dm->release(dm); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 5b100d7b6c2..ce61b4fce50 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1431,7 +1431,7 @@ static int convert_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Base *basen = NULL, *basact = NULL, *basedel = NULL; + Base *basen = NULL, *basact = NULL; Object *ob, *ob1, *newob, *obact = CTX_data_active_object(C); DerivedMesh *dm; Curve *cu; @@ -1687,14 +1687,6 @@ static int convert_exec(bContext *C, wmOperator *op) DAG_id_tag_update(&ob->id, OB_RECALC_DATA); ((ID *)ob->data)->flag &= ~LIB_DOIT; /* flag not to convert this datablock again */ } - - /* delete original if needed */ - if (basedel) { - if (!keep_original) - ED_base_object_free_and_unlink(bmain, scene, basedel); - - basedel = NULL; - } } CTX_DATA_END; diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 3f1ceb7327c..8b674cf1e50 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -107,13 +107,14 @@ typedef struct { int threads; } MultiresBakeJob; -static int multiresbake_check(bContext *C, wmOperator *op) +static bool multiresbake_check(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *ob; Mesh *me; MultiresModifierData *mmd; - int ok = 1, a; + bool ok = true; + int a; CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { @@ -122,7 +123,7 @@ static int multiresbake_check(bContext *C, wmOperator *op) if (ob->type != OB_MESH) { BKE_report(op->reports, RPT_ERROR, "Baking of multires data only works with an active mesh object"); - ok = 0; + ok = false; break; } @@ -137,12 +138,12 @@ static int multiresbake_check(bContext *C, wmOperator *op) for (md = (ModifierData *)mmd->modifier.next; md && ok; md = md->next) { if (modifier_isEnabled(scene, md, eModifierMode_Realtime)) { - ok = 0; + ok = false; } } } else { - ok = 0; + ok = false; } if (!ok) { @@ -153,14 +154,14 @@ static int multiresbake_check(bContext *C, wmOperator *op) if (mmd->lvl == 0) { BKE_report(op->reports, RPT_ERROR, "Multires data baking is not supported for preview subdivision level 0"); - + ok = false; break; } if (!me->mtpoly) { BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking"); - ok = 0; + ok = false; } else { a = me->totpoly; @@ -170,7 +171,7 @@ static int multiresbake_check(bContext *C, wmOperator *op) if (!ima) { BKE_report(op->reports, RPT_ERROR, "You should have active texture to use multires baker"); - ok = 0; + ok = false; } else { ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); @@ -178,14 +179,14 @@ static int multiresbake_check(bContext *C, wmOperator *op) if (!ibuf) { BKE_report(op->reports, RPT_ERROR, "Baking should happen to image with image buffer"); - ok = 0; + ok = false; } else { if (ibuf->rect == NULL && ibuf->rect_float == NULL) - ok = 0; + ok = false; if (ibuf->rect_float && !(ibuf->channels == 0 || ibuf->channels == 4)) - ok = 0; + ok = false; if (!ok) BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type"); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 9eaaf8fe1db..7f7a0777bbf 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1347,7 +1347,7 @@ static int shade_smooth_exec(bContext *C, wmOperator *op) static int shade_poll(bContext *C) { - return (ED_operator_object_active_editable(C) && !ED_operator_editmesh(C)); + return (CTX_data_edit_object(C) == NULL); } void OBJECT_OT_shade_flat(wmOperatorType *ot) @@ -1610,7 +1610,7 @@ void ED_object_toggle_modes(bContext *C, int mode) /************************ Game Properties ***********************/ -static int game_property_new(bContext *C, wmOperator *op) +static int game_property_new_exec(bContext *C, wmOperator *op) { Object *ob = CTX_data_active_object(C); bProperty *prop; @@ -1640,7 +1640,7 @@ void OBJECT_OT_game_property_new(wmOperatorType *ot) ot->idname = "OBJECT_OT_game_property_new"; /* api callbacks */ - ot->exec = game_property_new; + ot->exec = game_property_new_exec; ot->poll = ED_operator_object_active_editable; /* flags */ @@ -1650,7 +1650,7 @@ void OBJECT_OT_game_property_new(wmOperatorType *ot) RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Name of the game property to add"); } -static int game_property_remove(bContext *C, wmOperator *op) +static int game_property_remove_exec(bContext *C, wmOperator *op) { Object *ob = CTX_data_active_object(C); bProperty *prop; @@ -1681,7 +1681,7 @@ void OBJECT_OT_game_property_remove(wmOperatorType *ot) ot->idname = "OBJECT_OT_game_property_remove"; /* api callbacks */ - ot->exec = game_property_remove; + ot->exec = game_property_remove_exec; ot->poll = ED_operator_object_active_editable; /* flags */ diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c index f48e4ff5056..1f52346222c 100644 --- a/source/blender/editors/object/object_group.c +++ b/source/blender/editors/object/object_group.c @@ -61,6 +61,49 @@ /********************* 3d view operators ***********************/ +static bool group_link_early_exit_check(Group *group, Object *object) +{ + GroupObject *group_object; + + for (group_object = group->gobject.first; group_object; group_object = group_object->next) { + if (group_object->ob == object) { + return true; + } + } + + return false; +} + +static bool check_group_contains_object_recursive(Group *group, Object *object) +{ + GroupObject *group_object; + + if ((group->id.flag & LIB_DOIT) == 0) { + /* Cycle already exists in groups, let's prevent further crappyness */ + return true; + } + + group->id.flag &= ~LIB_DOIT; + + for (group_object = group->gobject.first; group_object; group_object = group_object->next) { + Object *current_object = group_object->ob; + + if (current_object == object) { + return true; + } + + if (current_object->dup_group) { + if (check_group_contains_object_recursive(current_object->dup_group, object)) { + return true; + } + } + } + + group->id.flag |= LIB_DOIT; + + return false; +} + /* can be called with C == NULL */ static EnumPropertyItem *group_object_active_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) { @@ -123,9 +166,15 @@ static int objects_add_active_exec(bContext *C, wmOperator *op) /* now add all selected objects from the group */ if (group) { + /* for recursive check */ + tag_main_lb(&bmain->group, TRUE); + CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { - if (base->object->dup_group != group) { + if (group_link_early_exit_check(group, base->object)) + continue; + + if (base->object->dup_group != group && !check_group_contains_object_recursive(group, base->object)) { BKE_group_object_add(group, base->object, scene, base); } else { @@ -378,47 +427,6 @@ void OBJECT_OT_group_add(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -static bool group_link_early_exit_check(Group *group, Object *object) -{ - GroupObject *group_object; - - for (group_object = group->gobject.first; group_object; group_object = group_object->next) { - if (group_object->ob == object) { - return true; - } - } - - return false; -} - -static bool check_group_contains_object_recursive(Group *group, Object *object) -{ - GroupObject *group_object; - - if ((group->id.flag & LIB_DOIT) == 0) { - /* Cycle already exists in groups, let's prevent further crappyness */ - return true; - } - - group->id.flag &= ~LIB_DOIT; - - for (group_object = group->gobject.first; group_object; group_object = group_object->next) { - Object *current_object = group_object->ob; - - if (current_object == object) { - return true; - } - - if (current_object->dup_group) { - if (check_group_contains_object_recursive(current_object->dup_group, object)) { - return true; - } - } - } - - return false; -} - static int group_link_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c index c8baa0d84dc..5b20489c9cb 100644 --- a/source/blender/editors/object/object_hook.c +++ b/source/blender/editors/object/object_hook.c @@ -713,11 +713,11 @@ static int object_hook_reset_exec(bContext *C, wmOperator *op) mul_m4_m4m4(mat, hmd->object->obmat, pchan->pose_mat); invert_m4_m4(imat, mat); - mul_serie_m4(hmd->parentinv, imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL); + mul_m4_m4m4(hmd->parentinv, imat, ob->obmat); } else { invert_m4_m4(hmd->object->imat, hmd->object->obmat); - mul_serie_m4(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL); + mul_m4_m4m4(hmd->parentinv, hmd->object->imat, ob->obmat); } } diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index 54e8d8e6599..a79b0607421 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -228,7 +228,7 @@ void LATTICE_OT_select_random(wmOperatorType *ot) /************************** Select More/Less Operator *************************/ -static bool lattice_test_bitmap_uvw(Lattice *lt, BLI_bitmap selpoints, int u, int v, int w, const bool selected) +static bool lattice_test_bitmap_uvw(Lattice *lt, BLI_bitmap *selpoints, int u, int v, int w, const bool selected) { if ((u < 0 || u >= lt->pntsu) || (v < 0 || v >= lt->pntsv) || @@ -252,7 +252,7 @@ static int lattice_select_more_less(bContext *C, const bool select) BPoint *bp; const int tot = lt->pntsu * lt->pntsv * lt->pntsw; int i, w, u, v; - BLI_bitmap selpoints; + BLI_bitmap *selpoints; lt->actbp = LT_ACTBP_NONE; diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index b1f1f73f493..03d51fcbe82 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -873,9 +873,9 @@ static int modifier_remove_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *ob = ED_object_active_context(C); ModifierData *md = edit_modifier_property_get(op, ob, 0); - int mode_orig = ob ? ob->mode : 0; + int mode_orig = ob->mode; - if (!ob || !md || !ED_object_modifier_remove(op->reports, bmain, ob, md)) + if (!md || !ED_object_modifier_remove(op->reports, bmain, ob, md)) return OPERATOR_CANCELLED; WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); @@ -919,7 +919,7 @@ static int modifier_move_up_exec(bContext *C, wmOperator *op) Object *ob = ED_object_active_context(C); ModifierData *md = edit_modifier_property_get(op, ob, 0); - if (!ob || !md || !ED_object_modifier_move_up(op->reports, ob, md)) + if (!md || !ED_object_modifier_move_up(op->reports, ob, md)) return OPERATOR_CANCELLED; DAG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -958,7 +958,7 @@ static int modifier_move_down_exec(bContext *C, wmOperator *op) Object *ob = ED_object_active_context(C); ModifierData *md = edit_modifier_property_get(op, ob, 0); - if (!ob || !md || !ED_object_modifier_move_down(op->reports, ob, md)) + if (!md || !ED_object_modifier_move_down(op->reports, ob, md)) return OPERATOR_CANCELLED; DAG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -999,7 +999,7 @@ static int modifier_apply_exec(bContext *C, wmOperator *op) ModifierData *md = edit_modifier_property_get(op, ob, 0); int apply_as = RNA_enum_get(op->ptr, "apply_as"); - if (!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) { + if (!md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) { return OPERATOR_CANCELLED; } @@ -1049,7 +1049,7 @@ static int modifier_convert_exec(bContext *C, wmOperator *op) Object *ob = ED_object_active_context(C); ModifierData *md = edit_modifier_property_get(op, ob, 0); - if (!ob || !md || !ED_object_modifier_convert(op->reports, bmain, scene, ob, md)) + if (!md || !ED_object_modifier_convert(op->reports, bmain, scene, ob, md)) return OPERATOR_CANCELLED; DAG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -1088,7 +1088,7 @@ static int modifier_copy_exec(bContext *C, wmOperator *op) Object *ob = ED_object_active_context(C); ModifierData *md = edit_modifier_property_get(op, ob, 0); - if (!ob || !md || !ED_object_modifier_copy(op->reports, ob, md)) + if (!md || !ED_object_modifier_copy(op->reports, ob, md)) return OPERATOR_CANCELLED; DAG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -1671,7 +1671,7 @@ void OBJECT_OT_skin_radii_equalize(wmOperatorType *ot) static void skin_armature_bone_create(Object *skin_ob, MVert *mvert, MEdge *medge, bArmature *arm, - BLI_bitmap edges_visited, + BLI_bitmap *edges_visited, const MeshElemMap *emap, EditBone *parent_bone, int parent_v) @@ -1720,7 +1720,7 @@ static void skin_armature_bone_create(Object *skin_ob, static Object *modifier_skin_armature_create(Main *bmain, Scene *scene, Object *skin_ob) { - BLI_bitmap edges_visited; + BLI_bitmap *edges_visited; DerivedMesh *deform_dm; MVert *mvert; Mesh *me = skin_ob->data; diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 13fb46e35de..52f51cfcf48 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2049,7 +2049,7 @@ static int make_local_exec(bContext *C, wmOperator *op) if (adt) BKE_animdata_make_local(adt); /* tag indirect data direct */ - matarar = (Material ***)give_matarar(ob); + matarar = give_matarar(ob); if (matarar) { for (a = 0; a < ob->totcol; a++) { ma = (*matarar)[a]; diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 9b3f1a4f3ac..294b0632015 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -547,7 +547,6 @@ static void vgroup_normalize_active(Object *ob, eVGroupSelect subset_type) ED_mesh_defvert_mirror_update_em(ob, eve_act, -1, -1, cd_dvert_offset); } else { - int v_act = BKE_mesh_mselect_active_get(me, ME_VSEL); ED_mesh_defvert_mirror_update_ob(ob, -1, v_act); } } diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index bc4ca82392f..3a6bd05df0b 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -1120,7 +1120,7 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C) glEnable(GL_BLEND); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glaDrawPixelsTex(rres.xof, rres.yof, rres.rectx, rres.recty, GL_RGBA, GL_FLOAT, - GL_LINEAR, rres.rectf); + GL_NEAREST, rres.rectf); glDisable(GL_BLEND); IMB_colormanagement_finish_glsl_draw(); @@ -1139,7 +1139,7 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C) glEnable(GL_BLEND); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glaDrawPixelsAuto(rres.xof, rres.yof, rres.rectx, rres.recty, GL_RGBA, GL_UNSIGNED_BYTE, - GL_LINEAR, display_buffer); + GL_NEAREST, display_buffer); glDisable(GL_BLEND); MEM_freeN(display_buffer); diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 93ae913cee0..e21e889d99d 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -469,9 +469,7 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer); } - if (oglrender->win) { - WM_cursor_restore(oglrender->win); - } + WM_cursor_restore(oglrender->win); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene); @@ -560,9 +558,7 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op) } } - if (oglrender->win) { - WM_cursor_time(oglrender->win, scene->r.cfra); - } + WM_cursor_time(oglrender->win, scene->r.cfra); BKE_scene_update_for_newframe(bmain, scene, screen_opengl_layers(oglrender)); @@ -688,6 +684,7 @@ static int screen_opengl_render_modal(bContext *C, wmOperator *op, const wmEvent /* render frame? */ if (oglrender->timer == event->customdata) break; + /* fall-through */ default: /* nothing to do */ return OPERATOR_RUNNING_MODAL; @@ -728,6 +725,9 @@ static int screen_opengl_render_invoke(bContext *C, wmOperator *op, const wmEven oglrender = op->customdata; render_view_open(C, event->x, event->y); + /* view may be changed above (R_OUTPUT_WINDOW) */ + oglrender->win = CTX_wm_window(C); + WM_event_add_modal_handler(C, op); oglrender->timer = WM_event_add_timer(oglrender->wm, oglrender->win, TIMER, 0.01f); diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 8da66c114d5..4bd8a7d426a 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -964,7 +964,7 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat br->icon_imbuf = get_brush_icon(br); - memset(sp->pr_rect, 0x888888, sp->sizex * sp->sizey * sizeof(unsigned int)); + memset(sp->pr_rect, 0x88, sp->sizex * sp->sizey * sizeof(unsigned int)); if (!(br->icon_imbuf) || !(br->icon_imbuf->rect)) return; diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 49ecfe2940e..58c244228ed 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -1214,7 +1214,7 @@ void SCENE_OT_freestyle_modifier_move(wmOperatorType *ot) #endif /* WITH_FREESTYLE */ -static int texture_slot_move(bContext *C, wmOperator *op) +static int texture_slot_move_exec(bContext *C, wmOperator *op) { ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data; @@ -1292,7 +1292,7 @@ void TEXTURE_OT_slot_move(wmOperatorType *ot) ot->description = "Move texture slots up and down"; /* api callbacks */ - ot->exec = texture_slot_move; + ot->exec = texture_slot_move_exec; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 6c0d5ccd844..e805b3f30fc 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -387,7 +387,7 @@ void ED_region_set(const bContext *C, ARegion *ar) ar->drawrct = ar->winrct; /* note; this sets state, so we can use wmOrtho and friends */ - wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct); + wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct, true); UI_SetTheme(sa ? sa->spacetype : 0, ar->type ? ar->type->regionid : 0); @@ -401,26 +401,27 @@ void ED_region_do_draw(bContext *C, ARegion *ar) wmWindow *win = CTX_wm_window(C); ScrArea *sa = CTX_wm_area(C); ARegionType *at = ar->type; - + bool scissor_pad; + /* see BKE_spacedata_draw_locks() */ if (at->do_lock) return; /* if no partial draw rect set, full rect */ - if (ar->drawrct.xmin == ar->drawrct.xmax) + if (ar->drawrct.xmin == ar->drawrct.xmax) { ar->drawrct = ar->winrct; + scissor_pad = true; + } else { - /* extra clip for safety (intersect the rects, could use API func) */ - ar->drawrct.xmin = max_ii(ar->winrct.xmin, ar->drawrct.xmin); - ar->drawrct.ymin = max_ii(ar->winrct.ymin, ar->drawrct.ymin); - ar->drawrct.xmax = min_ii(ar->winrct.xmax, ar->drawrct.xmax); - ar->drawrct.ymax = min_ii(ar->winrct.ymax, ar->drawrct.ymax); + /* extra clip for safety */ + BLI_rcti_isect(&ar->winrct, &ar->drawrct, &ar->drawrct); + scissor_pad = false; } /* note; this sets state, so we can use wmOrtho and friends */ - wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct); + wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct, scissor_pad); - UI_SetTheme(sa ? sa->spacetype : 0, ar->type ? ar->type->regionid : 0); + UI_SetTheme(sa ? sa->spacetype : 0, at->regionid); /* optional header info instead? */ if (ar->headerstr) { diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index d9dc5648ae3..498762f1603 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1378,10 +1378,7 @@ void ED_screen_set(bContext *C, bScreen *sc) if (id == NULL) return; - /* check for valid winid */ - if (sc->winid != 0 && sc->winid != win->winid) - return; - + if (sc->full) { /* find associated full */ bScreen *sc1; for (sc1 = bmain->screen.first; sc1; sc1 = sc1->id.next) { @@ -1392,6 +1389,10 @@ void ED_screen_set(bContext *C, bScreen *sc) } } } + + /* check for valid winid */ + if (sc->winid != 0 && sc->winid != win->winid) + return; if (oldscreen != sc) { wmTimer *wt = oldscreen->animtimer; diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index ff2561dc66f..3066b733fc5 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -649,7 +649,8 @@ static void actionzone_apply(bContext *C, wmOperator *op, int type) sad->modifier = RNA_int_get(op->ptr, "modifier"); - event = *(win->eventstate); /* XXX huh huh? make api call */ + wm_event_init_from_window(win, &event); + if (type == AZONE_AREA) event.type = EVT_ACTIONZONE_AREA; else @@ -2564,7 +2565,7 @@ static void SCREEN_OT_area_options(wmOperatorType *ot) /* ******************************* */ -static int spacedata_cleanup(bContext *C, wmOperator *op) +static int spacedata_cleanup_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); bScreen *screen; @@ -2596,7 +2597,7 @@ static void SCREEN_OT_spacedata_cleanup(wmOperatorType *ot) ot->idname = "SCREEN_OT_spacedata_cleanup"; /* api callbacks */ - ot->exec = spacedata_cleanup; + ot->exec = spacedata_cleanup_exec; ot->poll = WM_operator_winactive; } @@ -3184,7 +3185,7 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv sound_seek_scene(bmain, scene); /* since we follow drawflags, we can't send notifier but tag regions ourselves */ - ED_update_for_newframe(CTX_data_main(C), scene, 1); + ED_update_for_newframe(bmain, scene, 1); for (window = wm->windows.first; window; window = window->next) { for (sa = window->screen->areabase.first; sa; sa = sa->next) { @@ -3369,7 +3370,7 @@ static void SCREEN_OT_animation_cancel(wmOperatorType *ot) * poll() has to be filled in by user for context */ #if 0 -static int border_select_do(bContext *C, wmOperator *op) +static int border_select_exec(bContext *C, wmOperator *op) { int event_type = RNA_int_get(op->ptr, "event_type"); @@ -3390,7 +3391,7 @@ static void SCREEN_OT_border_select(wmOperatorType *ot) ot->idname = "SCREEN_OT_border_select"; /* api callbacks */ - ot->exec = border_select_do; + ot->exec = border_select_exec; ot->invoke = WM_border_select_invoke; ot->modal = WM_border_select_modal; ot->cancel = WM_border_select_cancel; diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index 3db0bd61f03..db6380e920f 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -154,7 +154,7 @@ static void partialvis_update_grids(Object *ob, { CCGElem **grids; CCGKey key; - BLI_bitmap *grid_hidden; + BLI_bitmap **grid_hidden; int any_visible = 0; int *grid_indices, totgrid, any_changed, i; @@ -171,7 +171,7 @@ static void partialvis_update_grids(Object *ob, for (i = 0; i < totgrid; i++) { int any_hidden = 0; int g = grid_indices[i], x, y; - BLI_bitmap gh = grid_hidden[g]; + BLI_bitmap *gh = grid_hidden[g]; if (!gh) { switch (action) { diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 017232d1856..db55dc271f1 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -2816,7 +2816,11 @@ static void project_paint_begin(ProjPaintState *ps) int a, i; /* generic looping vars */ int image_index = -1, face_index; - int *mpoly_origindex; + + /* double lookup */ + const int *index_mf_to_mpoly = NULL; + const int *index_mp_to_orig = NULL; + MVert *mv; MemArena *arena; /* at the moment this is just ps->arena_mt[0], but use this to show were not multithreading */ @@ -2871,12 +2875,17 @@ static void project_paint_begin(ProjPaintState *ps) ps->dm_totface = ps->dm->getNumTessFaces(ps->dm); if (ps->do_face_sel) { - mpoly_orig = ((Mesh *)ps->ob->data)->mpoly; - mpoly_origindex = ps->dm->getPolyDataArray(ps->dm, CD_ORIGINDEX); + index_mf_to_mpoly = ps->dm->getTessFaceDataArray(ps->dm, CD_ORIGINDEX); + index_mp_to_orig = ps->dm->getPolyDataArray(ps->dm, CD_ORIGINDEX); + if (index_mf_to_mpoly == NULL) { + index_mp_to_orig = NULL; + } + else { + mpoly_orig = ((Mesh *)ps->ob->data)->mpoly; + } } else { mpoly_orig = NULL; - mpoly_origindex = NULL; } /* use clone mtface? */ @@ -3166,8 +3175,10 @@ static void project_paint_begin(ProjPaintState *ps) if (ps->do_face_sel) { int orig_index; - if (mpoly_origindex && ((orig_index = mpoly_origindex[face_index])) != ORIGINDEX_NONE) { - MPoly *mp = mpoly_orig + orig_index; + if (index_mp_to_orig && ((orig_index = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, + face_index))) != ORIGINDEX_NONE) + { + MPoly *mp = &mpoly_orig[orig_index]; is_face_sel = ((mp->flag & ME_FACE_SEL) != 0); } else { diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index cef624463c2..bdf542526ee 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -847,7 +847,7 @@ static void BRUSH_OT_stencil_fit_image_aspect(wmOperatorType *ot) } -static int stencil_reset_transform(bContext *C, wmOperator *op) +static int stencil_reset_transform_exec(bContext *C, wmOperator *op) { Paint *paint = BKE_paint_get_active_from_context(C); Brush *br = BKE_paint_brush(paint); @@ -889,7 +889,7 @@ static void BRUSH_OT_stencil_reset_transform(wmOperatorType *ot) ot->idname = "BRUSH_OT_stencil_reset_transform"; /* api callbacks */ - ot->exec = stencil_reset_transform; + ot->exec = stencil_reset_transform_exec; ot->poll = stencil_control_poll; /* flags */ diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 576bbecb561..36e1b1feb38 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -375,13 +375,13 @@ static float paint_space_stroke_spacing(const Scene *scene, PaintStroke *stroke, /* apply spacing pressure */ if (stroke->brush->flag & BRUSH_SPACING_PRESSURE) - spacing = max_ff(1.0f, spacing * (1.5f - spacing_pressure)); + spacing = spacing * (1.5f - spacing_pressure); /* stroke system is used for 2d paint too, so we need to account for * the fact that brush can be scaled there. */ spacing *= stroke->zoom_2d; - return (size_clamp * spacing / 50.0f); + return max_ff(1.0, size_clamp * spacing / 50.0f); } static float paint_space_stroke_spacing_variable(const Scene *scene, PaintStroke *stroke, float pressure, float dpressure, float length) diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 3ecde56b5d0..d376bd3180f 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -412,7 +412,7 @@ void BRUSH_OT_curve_preset(wmOperatorType *ot) /* face-select ops */ static int paint_select_linked_exec(bContext *C, wmOperator *UNUSED(op)) { - paintface_select_linked(C, CTX_data_active_object(C), NULL, 2); + paintface_select_linked(C, CTX_data_active_object(C), NULL, true); ED_region_tag_redraw(CTX_wm_region(C)); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index b7bd061d14a..2c654507015 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -2025,7 +2025,7 @@ static void do_weight_paint_vertex( /* *************** set wpaint operator ****************** */ -static int set_wpaint(bContext *C, wmOperator *UNUSED(op)) /* toggle */ +static int wpaint_mode_toggle_exec(bContext *C, wmOperator *UNUSED(op)) /* toggle */ { Object *ob = CTX_data_active_object(C); Scene *scene = CTX_data_scene(C); @@ -2096,7 +2096,7 @@ void PAINT_OT_weight_paint_toggle(wmOperatorType *ot) ot->description = "Toggle weight paint mode in 3D view"; /* api callbacks */ - ot->exec = set_wpaint; + ot->exec = wpaint_mode_toggle_exec; ot->poll = paint_poll_test; /* flags */ @@ -2642,7 +2642,7 @@ void PAINT_OT_weight_set(wmOperatorType *ot) /* ************ set / clear vertex paint mode ********** */ -static int set_vpaint(bContext *C, wmOperator *op) /* toggle */ +static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op) /* toggle */ { Object *ob = CTX_data_active_object(C); Scene *scene = CTX_data_scene(C); @@ -2673,7 +2673,7 @@ static int set_vpaint(bContext *C, wmOperator *op) /* toggle */ ob->mode |= OB_MODE_VERTEX_PAINT; /* Turn off weight painting */ if (ob->mode & OB_MODE_WEIGHT_PAINT) - set_wpaint(C, op); + wpaint_mode_toggle_exec(C, op); if (vp == NULL) vp = scene->toolsettings->vpaint = new_vpaint(0); @@ -2700,7 +2700,7 @@ void PAINT_OT_vertex_paint_toggle(wmOperatorType *ot) ot->description = "Toggle the vertex paint mode in 3D view"; /* api callbacks */ - ot->exec = set_vpaint; + ot->exec = vpaint_mode_toggle_exec; ot->poll = paint_poll_test; /* flags */ @@ -3364,7 +3364,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) const bool is_interactive = (gesture != NULL); DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask); - DMGradient_userData data = {0}; + DMGradient_userData data = {NULL}; if (is_interactive) { if (gesture->userdata == NULL) { @@ -3413,7 +3413,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) ED_view3d_init_mats_rv3d(ob, ar->regiondata); - dm->foreachMappedVert(dm, gradientVert__mapFunc, &data); + dm->foreachMappedVert(dm, gradientVert__mapFunc, &data, DM_FOREACH_NOP); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); diff --git a/source/blender/editors/sculpt_paint/paint_vertex_proj.c b/source/blender/editors/sculpt_paint/paint_vertex_proj.c index 2d5de80efeb..4c06cb8ea0d 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_proj.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_proj.c @@ -107,7 +107,7 @@ static void vpaint_proj_dm_map_cosnos_init(Scene *scene, Object *ob, if (dm->foreachMappedVert) { memset(vp_handle->vcosnos, 0, sizeof(DMCoNo) * me->totvert); - dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_init__map_cb, vp_handle); + dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_init__map_cb, vp_handle, DM_FOREACH_USE_NORMAL); } else { DMCoNo *v_co_no = vp_handle->vcosnos; @@ -183,7 +183,7 @@ static void vpaint_proj_dm_map_cosnos_update(struct VertProjHandle *vp_handle, if (LIKELY(dm->foreachMappedVert)) { fill_vn_fl(vp_handle->dists, me->totvert, FLT_MAX); - dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_update__map_cb, &vp_update); + dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_update__map_cb, &vp_update, DM_FOREACH_USE_NORMAL); } dm->release(dm); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 3aeb2f1597b..2edd00c015d 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -306,6 +306,7 @@ typedef struct StrokeCache { char saved_active_brush_name[MAX_ID_NAME]; char saved_mask_brush_tool; + int saved_smooth_size; /* smooth tool copies the size of the current tool */ int alt_smooth; float plane_trim_squared; @@ -1529,7 +1530,7 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no float *tmpgrid_mask, *tmprow_mask; int v1, v2, v3, v4; int thread_num; - BLI_bitmap *grid_hidden; + BLI_bitmap **grid_hidden; int *grid_indices, totgrid, gridsize, i, x, y; sculpt_brush_test_init(ss, &test); @@ -1554,7 +1555,7 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no for (i = 0; i < totgrid; ++i) { int gi = grid_indices[i]; - BLI_bitmap gh = grid_hidden[gi]; + BLI_bitmap *gh = grid_hidden[gi]; data = griddata[gi]; adj = &gridadj[gi]; @@ -3710,6 +3711,7 @@ static void sculpt_omp_done(SculptSession *ss) static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSession *ss, wmOperator *op, const float mouse[2]) { StrokeCache *cache = MEM_callocN(sizeof(StrokeCache), "stroke cache"); + Scene *scene = CTX_data_scene(C); UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings; Brush *brush = BKE_paint_brush(&sd->paint); ViewContext *vc = paint_stroke_view_context(op->customdata); @@ -3755,6 +3757,7 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio else { Paint *p = &sd->paint; Brush *br; + int size = BKE_brush_size_get(scene, brush); BLI_strncpy(cache->saved_active_brush_name, brush->id.name + 2, sizeof(cache->saved_active_brush_name)); @@ -3763,6 +3766,8 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio if (br) { BKE_paint_brush_set(p, br); brush = br; + cache->saved_smooth_size = BKE_brush_size_get(scene, brush); + BKE_brush_size_set(scene, brush, size); } } } @@ -4352,6 +4357,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str { UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings; Object *ob = CTX_data_active_object(C); + Scene *scene = CTX_data_scene(C); SculptSession *ss = ob->sculpt; Sculpt *sd = CTX_data_tool_settings(C)->sculpt; @@ -4375,6 +4381,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str } else { Paint *p = &sd->paint; + BKE_brush_size_set(scene, ss->cache->brush, ss->cache->saved_smooth_size); brush = (Brush *)BKE_libblock_find_name(ID_BR, ss->cache->saved_active_brush_name); if (brush) { BKE_paint_brush_set(p, brush); @@ -4523,7 +4530,7 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot) /**** Reset the copy of the mesh that is being sculpted on (currently just for the layer brush) ****/ -static int sculpt_set_persistent_base(bContext *C, wmOperator *UNUSED(op)) +static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op)) { SculptSession *ss = CTX_data_active_object(C)->sculpt; @@ -4544,7 +4551,7 @@ static void SCULPT_OT_set_persistent_base(wmOperatorType *ot) ot->description = "Reset the copy of the mesh that is being sculpted on"; /* api callbacks */ - ot->exec = sculpt_set_persistent_base; + ot->exec = sculpt_set_persistent_base_exec; ot->poll = sculpt_mode_poll; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -4588,14 +4595,21 @@ void sculpt_dynamic_topology_enable(bContext *C) Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; Mesh *me = ob->data; + const BMAllocTemplate allocsize = {me->totvert, + me->totedge, + me->totloop, + me->totpoly}; sculpt_pbvh_clear(ob); ss->bm_smooth_shading = (scene->toolsettings->sculpt->flags & SCULPT_DYNTOPO_SMOOTH_SHADING); + /* Dynamic topology doesn't ensure selection state is valid, so remove [#36280] */ + BKE_mesh_mselect_clear(me); + /* Create triangles-only BMesh */ - ss->bm = BM_mesh_create(&bm_mesh_allocsize_default); + ss->bm = BM_mesh_create(&allocsize); BM_mesh_bm_from_me(ss->bm, me, true, true, ob->shapenr); sculpt_dynamic_topology_triangulate(ss->bm); @@ -4893,7 +4907,7 @@ int ED_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd) return ret; } -static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op)) +static int sculpt_mode_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); ToolSettings *ts = CTX_data_tool_settings(C); @@ -4981,7 +4995,7 @@ static void SCULPT_OT_sculptmode_toggle(wmOperatorType *ot) ot->description = "Toggle sculpt mode in 3D view"; /* api callbacks */ - ot->exec = sculpt_toggle_mode; + ot->exec = sculpt_mode_toggle_exec; ot->poll = ED_operator_object_active_editable_mesh; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 13f97c50dc7..d904ec3bc96 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -100,14 +100,14 @@ typedef struct SculptUndoNode { /* non-multires */ int maxvert; /* to verify if totvert it still the same */ int *index; /* to restore into right location */ - BLI_bitmap vert_hidden; + BLI_bitmap *vert_hidden; /* multires */ int maxgrid; /* same for grid */ int gridsize; /* same for grid */ int totgrid; /* to restore into right location */ int *grids; /* to restore into right location */ - BLI_bitmap *grid_hidden; + BLI_bitmap **grid_hidden; /* bmesh */ struct BMLogEntry *bm_entry; diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index 2cc09ea2aa9..8861777f326 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -210,10 +210,10 @@ static int sculpt_undo_restore_hidden(bContext *C, DerivedMesh *dm, } } else if (unode->maxgrid && dm->getGridData) { - BLI_bitmap *grid_hidden = dm->getGridHidden(dm); + BLI_bitmap **grid_hidden = dm->getGridHidden(dm); for (i = 0; i < unode->totgrid; i++) { - SWAP(BLI_bitmap, + SWAP(BLI_bitmap *, unode->grid_hidden[i], grid_hidden[unode->grids[i]]); @@ -531,7 +531,7 @@ static void sculpt_undo_alloc_and_store_hidden(PBVH *pbvh, SculptUndoNode *unode) { PBVHNode *node = unode->node; - BLI_bitmap *grid_hidden; + BLI_bitmap **grid_hidden; int i, *grid_indices, totgrid; grid_hidden = BKE_pbvh_grid_hidden(pbvh); @@ -539,7 +539,7 @@ static void sculpt_undo_alloc_and_store_hidden(PBVH *pbvh, BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, NULL, NULL, NULL, NULL); - unode->grid_hidden = MEM_mapallocN(sizeof(BLI_bitmap) * totgrid, + unode->grid_hidden = MEM_mapallocN(sizeof(*unode->grid_hidden) * totgrid, "unode->grid_hidden"); for (i = 0; i < totgrid; i++) { diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 72d7bcd43ce..d32be692558 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -266,6 +266,7 @@ static void buttons_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier * break; case ND_POSE: buttons_area_redraw(sa, BCONTEXT_DATA); + break; case ND_BONE_ACTIVE: case ND_BONE_SELECT: buttons_area_redraw(sa, BCONTEXT_BONE); diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 9afca413836..f3d070452a5 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -1226,9 +1226,9 @@ static void track_markers_freejob(void *tmv) BKE_tracking_context_sync(tmj->context); BKE_tracking_context_free(tmj->context); - MEM_freeN(tmj); - WM_main_add_notifier(NC_SCENE | ND_FRAME, tmj->scene); + + MEM_freeN(tmj); } static int track_markers_exec(bContext *C, wmOperator *op) @@ -1711,7 +1711,9 @@ static int clear_track_path_exec(bContext *C, wmOperator *op) if (clear_active) { track = BKE_tracking_track_get_active(tracking); - BKE_tracking_track_path_clear(track, framenr, action); + if (track) { + BKE_tracking_track_path_clear(track, framenr, action); + } } else { track = tracksbase->first; @@ -3476,6 +3478,8 @@ static int clean_tracks_exec(bContext *C, wmOperator *op) track = next; } + BKE_tracking_dopesheet_tag_update(tracking); + WM_event_add_notifier(C, NC_MOVIECLIP | ND_SELECT, clip); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 8b1df0f0d8f..6f3d0367574 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -500,12 +500,14 @@ static void file_channel_area_draw(const bContext *C, ARegion *ar) ED_region_panels(C, ar, 1, NULL, -1); } -static void file_channel_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), wmNotifier *wmn) +static void file_channel_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn)) { +#if 0 /* context changes */ switch (wmn->category) { } +#endif } /* add handlers, stuff you only do once or on area/region changes */ diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index a81c0d6dfd6..295f8bd9ff2 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -50,6 +50,7 @@ #include "BKE_depsgraph.h" #include "BKE_fcurve.h" #include "BKE_main.h" +#include "BKE_global.h" #include "BKE_screen.h" #include "BKE_unit.h" @@ -74,20 +75,6 @@ /* -------------- */ -static void do_graph_region_buttons(bContext *UNUSED(C), void *UNUSED(arg), int event) -{ - //Scene *scene = CTX_data_scene(C); - - switch (event) { - - } - - /* default for now */ - //WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob); -} - -/* -------------- */ - static int graph_panel_context(const bContext *C, bAnimListElem **ale, FCurve **fcu) { bAnimContext ac; @@ -162,15 +149,16 @@ static void graph_panel_properties(const bContext *C, Panel *pa) PointerRNA fcu_ptr; uiLayout *layout = pa->layout; uiLayout *col, *row, *sub; - uiBlock *block; + // uiBlock *block; // UNUSED char name[256]; int icon = 0; if (!graph_panel_context(C, &ale, &fcu)) return; - block = uiLayoutGetBlock(layout); - uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL); + // UNUSED + // block = uiLayoutGetBlock(layout); + // uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL); /* F-Curve pointer */ RNA_pointer_create(ale->id, &RNA_FCurve, fcu, &fcu_ptr); @@ -281,7 +269,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa) return; block = uiLayoutGetBlock(layout); - uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL); + /* uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL); */ /* only show this info if there are keyframes to edit */ if (get_active_fcurve_keyframe_edit(fcu, &bezt, &prevbezt)) { @@ -633,8 +621,12 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) uiItemR(col, &driver_ptr, "expression", 0, IFACE_("Expr"), ICON_NONE); /* errors? */ - if (driver->flag & DRIVER_FLAG_INVALID) + if ((G.f & G_SCRIPT_AUTOEXEC) == 0) { + uiItemL(col, IFACE_("ERROR: Python auto-execution disabled"), ICON_ERROR); + } + else if (driver->flag & DRIVER_FLAG_INVALID) { uiItemL(col, IFACE_("ERROR: Invalid Python expression"), ICON_ERROR); + } } else { /* errors? */ @@ -841,7 +833,7 @@ void graph_buttons_register(ARegionType *art) BLI_addtail(&art->paneltypes, pt); } -static int graph_properties(bContext *C, wmOperator *UNUSED(op)) +static int graph_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = graph_has_buttons_region(sa); @@ -858,7 +850,7 @@ void GRAPH_OT_properties(wmOperatorType *ot) ot->idname = "GRAPH_OT_properties"; ot->description = "Toggle display properties panel"; - ot->exec = graph_properties; + ot->exec = graph_properties_toggle_exec; ot->poll = ED_operator_graphedit_active; /* flags */ diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 4b1975bc058..144d2c14e9f 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -886,7 +886,7 @@ void image_buttons_register(ARegionType *art) BLI_addtail(&art->paneltypes, pt); } -static int image_properties(bContext *C, wmOperator *UNUSED(op)) +static int image_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = image_has_buttons_region(sa); @@ -903,14 +903,14 @@ void IMAGE_OT_properties(wmOperatorType *ot) ot->idname = "IMAGE_OT_properties"; ot->description = "Toggle display properties panel"; - ot->exec = image_properties; + ot->exec = image_properties_toggle_exec; ot->poll = ED_operator_image_active; /* flags */ ot->flag = 0; } -static int image_scopes(bContext *C, wmOperator *UNUSED(op)) +static int image_scopes_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = image_has_scope_region(sa); @@ -927,7 +927,7 @@ void IMAGE_OT_scopes(wmOperatorType *ot) ot->idname = "IMAGE_OT_scopes"; ot->description = "Toggle display scopes panel"; - ot->exec = image_scopes; + ot->exec = image_scopes_toggle_exec; ot->poll = ED_operator_image_active; /* flags */ diff --git a/source/blender/editors/space_logic/logic_buttons.c b/source/blender/editors/space_logic/logic_buttons.c index a55da0e3b2c..2c521532484 100644 --- a/source/blender/editors/space_logic/logic_buttons.c +++ b/source/blender/editors/space_logic/logic_buttons.c @@ -50,7 +50,7 @@ #include "interface_intern.h" #include "logic_intern.h" -static int logic_properties(bContext *C, wmOperator *UNUSED(op)) +static int logic_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = logic_has_buttons_region(sa); @@ -67,7 +67,7 @@ void LOGIC_OT_properties(wmOperatorType *ot) ot->description = "Toggle display properties panel"; ot->idname = "LOGIC_OT_properties"; - ot->exec = logic_properties; + ot->exec = logic_properties_toggle_exec; ot->poll = ED_operator_logic_active; /* flags */ diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index ce8ee25eef0..2957edd941b 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -1009,8 +1009,6 @@ static void draw_sensor_armature(uiLayout *layout, PointerRNA *ptr) bSensor *sens = (bSensor *)ptr->data; bArmatureSensor *as = (bArmatureSensor *) sens->data; Object *ob = (Object *)ptr->id.data; - PointerRNA pose_ptr, pchan_ptr; - PropertyRNA *bones_prop= NULL; uiLayout *row; if (ob->type != OB_ARMATURE) { @@ -1019,11 +1017,12 @@ static void draw_sensor_armature(uiLayout *layout, PointerRNA *ptr) } if (ob->pose) { + PointerRNA pose_ptr, pchan_ptr; + PropertyRNA *bones_prop; + RNA_pointer_create((ID *)ob, &RNA_Pose, ob->pose, &pose_ptr); bones_prop = RNA_struct_find_property(&pose_ptr, "bones"); - } - if (&pose_ptr.data) { uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA); if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, as->posechannel, &pchan_ptr)) diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index 4cda92fbe07..ce7d537a518 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -68,14 +68,14 @@ /* -------------- */ -static void do_nla_region_buttons(bContext *C, void *UNUSED(arg), int event) +static void do_nla_region_buttons(bContext *C, void *UNUSED(arg), int UNUSED(event)) { //Scene *scene = CTX_data_scene(C); - +#if 0 switch (event) { } - +#endif /* default for now */ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); WM_event_add_notifier(C, NC_SCENE | ND_TRANSFORM, NULL); @@ -552,7 +552,7 @@ void nla_buttons_register(ARegionType *art) BLI_addtail(&art->paneltypes, pt); } -static int nla_properties(bContext *C, wmOperator *UNUSED(op)) +static int nla_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = nla_has_buttons_region(sa); @@ -569,7 +569,7 @@ void NLA_OT_properties(wmOperatorType *ot) ot->idname = "NLA_OT_properties"; ot->description = "Toggle display properties panel"; - ot->exec = nla_properties; + ot->exec = nla_properties_toggle_exec; ot->poll = ED_operator_nla_active; /* flags */ diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 0dcae29bf7f..cf3c0454e6b 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -735,6 +735,13 @@ static void node_shader_buts_vect_math(uiLayout *layout, bContext *UNUSED(C), Po uiItemR(layout, ptr, "operation", 0, "", ICON_NONE); } +static void node_shader_buts_vect_transform(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + uiItemR(layout, ptr, "convert_from", 0, "", ICON_NONE); + uiItemR(layout, ptr, "convert_to", 0, "", ICON_NONE); +} + static void node_shader_buts_geometry(uiLayout *layout, bContext *C, PointerRNA *ptr) { PointerRNA obptr = CTX_data_pointer_get(C, "active_object"); @@ -975,6 +982,9 @@ static void node_shader_set_butfunc(bNodeType *ntype) case SH_NODE_VECT_MATH: ntype->uifunc = node_shader_buts_vect_math; break; + case SH_NODE_VECT_TRANSFORM: + ntype->uifunc = node_shader_buts_vect_transform; + break; case SH_NODE_GEOMETRY: ntype->uifunc = node_shader_buts_geometry; break; diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c index d5224a37358..c9618daa7c5 100644 --- a/source/blender/editors/space_node/node_add.c +++ b/source/blender/editors/space_node/node_add.c @@ -339,8 +339,6 @@ static int node_add_file_exec(bContext *C, wmOperator *op) } } - node_deselect_all(snode); - switch (snode->nodetree->type) { case NTREE_SHADER: type = SH_NODE_TEX_IMAGE; @@ -410,6 +408,69 @@ void NODE_OT_add_file(wmOperatorType *ot) RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Datablock name to assign"); } +/* ****************** Add Mask Node Operator ******************* */ + +static int node_add_mask_poll(bContext *C) +{ + SpaceNode *snode = CTX_wm_space_node(C); + + return ED_operator_node_editable(C) && snode->nodetree->type == NTREE_COMPOSIT; +} + +static int node_add_mask_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + ARegion *ar = CTX_wm_region(C); + SpaceNode *snode = CTX_wm_space_node(C); + bNode *node; + ID *mask = NULL; + + /* check input variables */ + char name[MAX_ID_NAME - 2]; + RNA_string_get(op->ptr, "name", name); + mask = BKE_libblock_find_name(ID_MSK, name); + if (!mask) { + BKE_reportf(op->reports, RPT_ERROR, "Mask '%s' not found", name); + return OPERATOR_CANCELLED; + } + + ED_preview_kill_jobs(C); + + /* convert mouse coordinates to v2d space */ + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], + &snode->cursor[0], &snode->cursor[1]); + node = node_add_node(C, NULL, CMP_NODE_MASK, snode->cursor[0], snode->cursor[1]); + + if (!node) { + BKE_report(op->reports, RPT_WARNING, "Could not add a mask node"); + return OPERATOR_CANCELLED; + } + + node->id = mask; + id_us_plus(mask); + + snode_notify(C, snode); + snode_dag_update(C, snode); + + return OPERATOR_FINISHED; +} + +void NODE_OT_add_mask(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Mask Node"; + ot->description = "Add a mask node to the current node editor"; + ot->idname = "NODE_OT_add_mask"; + + /* callbacks */ + ot->invoke = node_add_mask_invoke; + ot->poll = node_add_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_string(ot->srna, "name", "Mask", MAX_ID_NAME - 2, "Name", "Datablock name to assign"); +} + /********************** New node tree operator *********************/ static int new_node_tree_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c index 7068973b2bf..f95e895bef2 100644 --- a/source/blender/editors/space_node/node_buttons.c +++ b/source/blender/editors/space_node/node_buttons.c @@ -206,7 +206,7 @@ void node_buttons_register(ARegionType *art) BLI_addtail(&art->paneltypes, pt); } -static int node_properties(bContext *C, wmOperator *UNUSED(op)) +static int node_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = node_has_buttons_region(sa); @@ -230,7 +230,7 @@ void NODE_OT_properties(wmOperatorType *ot) ot->description = "Toggles the properties panel display"; ot->idname = "NODE_OT_properties"; - ot->exec = node_properties; + ot->exec = node_properties_toggle_exec; ot->poll = node_properties_poll; /* flags */ diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 9b48774588d..b7e9cb0268f 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -510,13 +510,9 @@ void ED_node_composit_default(const bContext *C, struct Scene *sce) out = nodeAddStaticNode(C, sce->nodetree, CMP_NODE_COMPOSITE); out->locx = 300.0f; out->locy = 400.0f; - out->id = &sce->id; - id_us_plus(out->id); in = nodeAddStaticNode(C, sce->nodetree, CMP_NODE_R_LAYERS); in->locx = 10.0f; in->locy = 400.0f; - in->id = &sce->id; - id_us_plus(in->id); nodeSetActive(sce->nodetree, in); /* links from color to color */ diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index a9a17b182a4..1a2e90e5522 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -143,6 +143,7 @@ void draw_nodespace_back_pix(const struct bContext *C, struct ARegion *ar, struc bNode *node_add_node(const struct bContext *C, const char *idname, int type, float locx, float locy); void NODE_OT_add_reroute(struct wmOperatorType *ot); void NODE_OT_add_file(struct wmOperatorType *ot); +void NODE_OT_add_mask(struct wmOperatorType *ot); void NODE_OT_new_node_tree(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index 2476a9b8b99..566bb1600cc 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -101,6 +101,7 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_backimage_sample); WM_operatortype_append(NODE_OT_add_file); + WM_operatortype_append(NODE_OT_add_mask); WM_operatortype_append(NODE_OT_new_node_tree); diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c index beea4dc3183..244b222811e 100644 --- a/source/blender/editors/space_node/node_relationships.c +++ b/source/blender/editors/space_node/node_relationships.c @@ -356,7 +356,7 @@ static int node_link_viewer(const bContext *C, bNode *tonode) } -static int node_active_link_viewer(bContext *C, wmOperator *UNUSED(op)) +static int node_active_link_viewer_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceNode *snode = CTX_wm_space_node(C); bNode *node; @@ -385,7 +385,7 @@ void NODE_OT_link_viewer(wmOperatorType *ot) ot->idname = "NODE_OT_link_viewer"; /* api callbacks */ - ot->exec = node_active_link_viewer; + ot->exec = node_active_link_viewer_exec; ot->poll = composite_node_editable; /* flags */ diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index bd0c9848b23..e17699309ef 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -926,7 +926,7 @@ static uiBlock *node_find_menu(bContext *C, ARegion *ar, void *arg_op) uiEndBlock(C, block); // uiButActiveOnly(C, ar, block, but); XXX using this here makes Blender hang - investigate - event = *(win->eventstate); /* XXX huh huh? make api call */ + wm_event_init_from_window(win, &event); event.type = EVT_BUT_OPEN; event.val = KM_PRESS; event.customdata = but; diff --git a/source/blender/editors/space_node/node_toolbar.c b/source/blender/editors/space_node/node_toolbar.c index 86da4009b17..dd5bad3f8ad 100644 --- a/source/blender/editors/space_node/node_toolbar.c +++ b/source/blender/editors/space_node/node_toolbar.c @@ -60,7 +60,7 @@ void node_toolbar_register(ARegionType *UNUSED(art)) /* ********** operator to open/close toolshelf region */ -static int node_toolbar(bContext *C, wmOperator *UNUSED(op)) +static int node_toolbar_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = node_has_tools_region(sa); @@ -84,7 +84,7 @@ void NODE_OT_toolbar(wmOperatorType *ot) ot->description = "Toggles tool shelf display"; ot->idname = "NODE_OT_toolbar"; - ot->exec = node_toolbar; + ot->exec = node_toolbar_toggle_exec; ot->poll = node_toolbar_poll; /* flags */ diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c index eed8a10a1db..9e6e1e628f6 100644 --- a/source/blender/editors/space_node/node_view.c +++ b/source/blender/editors/space_node/node_view.c @@ -295,7 +295,7 @@ void NODE_OT_backimage_move(wmOperatorType *ot) ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER; } -static int backimage_zoom(bContext *C, wmOperator *op) +static int backimage_zoom_exec(bContext *C, wmOperator *op) { SpaceNode *snode = CTX_wm_space_node(C); ARegion *ar = CTX_wm_region(C); @@ -317,7 +317,7 @@ void NODE_OT_backimage_zoom(wmOperatorType *ot) ot->description = "Zoom in/out the background image"; /* api callbacks */ - ot->exec = backimage_zoom; + ot->exec = backimage_zoom_exec; ot->poll = composite_node_active; /* flags */ diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index f12f7743429..922912fa540 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -635,7 +635,7 @@ static void node_main_area_draw(const bContext *C, ARegion *ar) /* ************* dropboxes ************* */ -static int node_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +static int node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { if (drag->type == WM_DRAG_ID) { ID *id = (ID *)drag->poin; @@ -649,6 +649,23 @@ static int node_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUS return 0; } +static int node_mask_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +{ + if (drag->type == WM_DRAG_ID) { + ID *id = (ID *)drag->poin; + if (GS(id->name) == ID_MSK) + return 1; + } + return 0; +} + +static void node_id_drop_copy(wmDrag *drag, wmDropBox *drop) +{ + ID *id = (ID *)drag->poin; + + RNA_string_set(drop->ptr, "name", id->name + 2); +} + static void node_id_path_drop_copy(wmDrag *drag, wmDropBox *drop) { ID *id = (ID *)drag->poin; @@ -666,7 +683,8 @@ static void node_dropboxes(void) { ListBase *lb = WM_dropboxmap_find("Node Editor", SPACE_NODE, RGN_TYPE_WINDOW); - WM_dropbox_add(lb, "NODE_OT_add_file", node_drop_poll, node_id_path_drop_copy); + WM_dropbox_add(lb, "NODE_OT_add_file", node_ima_drop_poll, node_id_path_drop_copy); + WM_dropbox_add(lb, "NODE_OT_add_mask", node_mask_drop_poll, node_id_drop_copy); } diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 81207deea01..44d5672e7da 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -40,6 +40,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLI_ghash.h" +#include "BLI_mempool.h" #include "BLF_translation.h" @@ -263,7 +264,7 @@ static void restrictbutton_bone_visibility_cb(bContext *C, void *poin, void *poi { bArmature *arm = (bArmature *)poin; Bone *bone = (Bone *)poin2; - if (bone && (bone->flag & BONE_HIDDEN_P)) + if (bone->flag & BONE_HIDDEN_P) bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); if (CTX_wm_window(C)->eventstate->ctrl) { @@ -277,7 +278,7 @@ static void restrictbutton_bone_select_cb(bContext *C, void *poin, void *poin2) { bArmature *arm = (bArmature *)poin; Bone *bone = (Bone *)poin2; - if (bone && (bone->flag & BONE_UNSELECTABLE)) + if (bone->flag & BONE_UNSELECTABLE) bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); if (CTX_wm_window(C)->eventstate->ctrl) { @@ -407,7 +408,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname) SpaceOops *soops = CTX_wm_space_outliner(C); Scene *scene = CTX_data_scene(C); Object *obedit = CTX_data_edit_object(C); - TreeStore *ts = soops->treestore; + BLI_mempool *ts = soops->treestore; TreeStoreElem *tselem = tsep; if (ts && tselem) { @@ -539,21 +540,21 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar uiBlockSetEmboss(block, UI_EMBOSSN); bt = uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_VIEW_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, &ptr, "hide", -1, 0, 0, -1, -1, TIP_("Restrict viewport visibility (Ctrl - Recursive)")); uiButSetFunc(bt, restrictbutton_view_cb, scene, ob); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); bt = uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_SELECT_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y, &ptr, "hide_select", -1, 0, 0, -1, -1, TIP_("Restrict viewport selection (Ctrl - Recursive)")); uiButSetFunc(bt, restrictbutton_sel_cb, scene, ob); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); bt = uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_RENDER_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y, &ptr, "hide_render", -1, 0, 0, -1, -1, TIP_("Restrict rendering (Ctrl - Recursive)")); uiButSetFunc(bt, restrictbutton_rend_cb, scene, ob); @@ -570,21 +571,21 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar restrict_bool = group_restrict_flag(gr, OB_RESTRICT_VIEW); bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Restrict/Allow visibility in the 3D View")); uiButSetFunc(bt, restrictbutton_gr_restrict_view, scene, gr); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); restrict_bool = group_restrict_flag(gr, OB_RESTRICT_SELECT); bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Restrict/Allow selection in the 3D View")); uiButSetFunc(bt, restrictbutton_gr_restrict_select, scene, gr); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); restrict_bool = group_restrict_flag(gr, OB_RESTRICT_RENDER); bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Restrict/Allow renderability")); uiButSetFunc(bt, restrictbutton_gr_restrict_render, scene, gr); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); @@ -596,7 +597,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar uiBlockSetEmboss(block, UI_EMBOSSN); bt = uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, 0, ICON_CHECKBOX_HLT - 1, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, te->directdata, 0, 0, 0, 0, TIP_("Render this RenderLayer")); uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); @@ -611,7 +612,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar bt = uiDefIconButBitI(block, ICONTOG, passflag, 0, ICON_CHECKBOX_HLT - 1, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, layflag, 0, 0, 0, 0, TIP_("Render this Pass")); uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); @@ -621,7 +622,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar SCE_PASS_INDIRECT, SCE_PASS_EMIT, SCE_PASS_ENVIRONMENT)) { bt = uiDefIconButBitI(block, TOG, passflag, 0, (*layflag & passflag) ? ICON_DOT : ICON_BLANK1, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y, layflag, 0, 0, 0, 0, TIP_("Exclude this Pass from Combined")); uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); @@ -635,14 +636,14 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar uiBlockSetEmboss(block, UI_EMBOSSN); bt = uiDefIconButBitI(block, ICONTOGN, eModifierMode_Realtime, 0, ICON_RESTRICT_VIEW_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, &(md->mode), 0, 0, 0, 0, TIP_("Restrict/Allow visibility in the 3D View")); uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); bt = uiDefIconButBitI(block, ICONTOGN, eModifierMode_Render, 0, ICON_RESTRICT_RENDER_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y, &(md->mode), 0, 0, 0, 0, TIP_("Restrict/Allow renderability")); uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); @@ -656,14 +657,14 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar uiBlockSetEmboss(block, UI_EMBOSSN); bt = uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_P, 0, ICON_RESTRICT_VIEW_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, &(bone->flag), 0, 0, 0, 0, TIP_("Restrict/Allow visibility in the 3D View")); uiButSetFunc(bt, restrictbutton_bone_visibility_cb, ob->data, bone); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); bt = uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y, &(bone->flag), 0, 0, 0, 0, TIP_("Restrict/Allow selection in the 3D View")); uiButSetFunc(bt, restrictbutton_bone_select_cb, ob->data, bone); @@ -676,14 +677,14 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar uiBlockSetEmboss(block, UI_EMBOSSN); bt = uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, &(ebone->flag), 0, 0, 0, 0, TIP_("Restrict/Allow visibility in the 3D View")); uiButSetFunc(bt, restrictbutton_ebone_visibility_cb, NULL, ebone); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); bt = uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y, &(ebone->flag), 0, 0, 0, 0, TIP_("Restrict/Allow selection in the 3D View")); uiButSetFunc(bt, restrictbutton_ebone_select_cb, NULL, ebone); @@ -735,7 +736,7 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa prop = te->directdata; if (!(RNA_property_type(prop) == PROP_POINTER && (TSELEM_OPEN(tselem, soops)))) { - uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, + uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y - 1); } } @@ -743,7 +744,7 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa ptr = &te->rnaptr; prop = te->directdata; - uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, + uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y - 1); } } @@ -811,7 +812,7 @@ static uiBlock *operator_search_menu(bContext *C, ARegion *ar, void *arg_kmi) uiBlockSetDirection(block, UI_DOWN); uiEndBlock(C, block); - event = *(win->eventstate); /* XXX huh huh? make api call */ + wm_event_init_from_window(win, &event); event.type = EVT_BUT_OPEN; event.val = KM_PRESS; event.customdata = but; @@ -960,7 +961,7 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo /* pass */ } else { - uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys + 1, butw1, UI_UNIT_Y - 1, + uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, te->ys + 1, butw1, UI_UNIT_Y - 1, TIP_("Assign new Operator")); } xstart += butw1 + 10; @@ -969,7 +970,7 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo kmi->maptype = keymap_menu_type(kmi->type); str = keymap_type_menu(); - but = uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->maptype, + but = uiDefButS(block, MENU, 0, str, xstart, te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->maptype, 0, 0, 0, 0, TIP_("Event type")); uiButSetFunc(but, keymap_type_cb, kmi, NULL); xstart += butw2 + 5; @@ -977,48 +978,48 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo /* edit actual event */ switch (kmi->maptype) { case OL_KM_KEYBOARD: - uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, + uiDefKeyevtButS(block, 0, "", xstart, te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, TIP_("Key code")); xstart += butw2 + 5; break; case OL_KM_MOUSE: str = keymap_mouse_menu(); - uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, + uiDefButS(block, MENU, 0, str, xstart, te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, 0, 0, 0, 0, TIP_("Mouse button")); xstart += butw2 + 5; break; case OL_KM_TWEAK: str = keymap_tweak_menu(); - uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, + uiDefButS(block, MENU, 0, str, xstart, te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, 0, 0, 0, 0, TIP_("Tweak gesture")); xstart += butw2 + 5; str = keymap_tweak_dir_menu(); - uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->val, + uiDefButS(block, MENU, 0, str, xstart, te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->val, 0, 0, 0, 0, TIP_("Tweak gesture direction")); xstart += butw2 + 5; break; } /* modifiers */ - uiDefButS(block, OPTION, 0, IFACE_("Shift"), xstart, (int)te->ys + 1, butw3 + 5, UI_UNIT_Y - 1, + uiDefButS(block, OPTION, 0, IFACE_("Shift"), xstart, te->ys + 1, butw3 + 5, UI_UNIT_Y - 1, &kmi->shift, 0, 0, 0, 0, TIP_("Modifier")); xstart += butw3 + 5; - uiDefButS(block, OPTION, 0, IFACE_("Ctrl"), xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->ctrl, + uiDefButS(block, OPTION, 0, IFACE_("Ctrl"), xstart, te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->ctrl, 0, 0, 0, 0, TIP_("Modifier")); xstart += butw3; - uiDefButS(block, OPTION, 0, IFACE_("Alt"), xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->alt, + uiDefButS(block, OPTION, 0, IFACE_("Alt"), xstart, te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->alt, 0, 0, 0, 0, TIP_("Modifier")); xstart += butw3; - uiDefButS(block, OPTION, 0, IFACE_("OS"), xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->oskey, + uiDefButS(block, OPTION, 0, IFACE_("OS"), xstart, te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->oskey, 0, 0, 0, 0, TIP_("Modifier")); xstart += butw3 + 5; - uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->keymodifier, + uiDefKeyevtButS(block, 0, "", xstart, te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->keymodifier, TIP_("Key Modifier code")); xstart += butw3 + 5; /* rna property */ if (kmi->ptr && kmi->ptr->data) { - uiDefBut(block, LABEL, 0, IFACE_("(RNA property)"), xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, + uiDefBut(block, LABEL, 0, IFACE_("(RNA property)"), xstart, te->ys + 1, butw2, UI_UNIT_Y - 1, NULL, 0, 0, 0, 0, ""); xstart += butw2; } @@ -1064,7 +1065,7 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa spx = te->xs + 1.8f * UI_UNIT_X; if (spx + dx + 0.5f * UI_UNIT_X > ar->v2d.cur.xmax) dx = ar->v2d.cur.xmax - spx - 0.5f * UI_UNIT_X; - bt = uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, (int)te->ys, dx + UI_UNIT_X, UI_UNIT_Y - 1, (void *)te->name, + bt = uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, te->ys, dx + UI_UNIT_X, UI_UNIT_Y - 1, (void *)te->name, 1.0, (float)len, 0, 0, ""); uiButSetRenameFunc(bt, namebutton_cb, tselem); @@ -1440,8 +1441,8 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa } tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.5f); - te->xs = (float)*offsx; - te->ys = (float)ys; + te->xs = *offsx; + te->ys = ys; te->xend = (short)*offsx + UI_UNIT_X; te->flag |= TE_ICONROW; // for click @@ -1456,13 +1457,13 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa } /* closed tree element */ -static void outliner_set_coord_tree_element(SpaceOops *soops, TreeElement *te, int startx, int *starty) +static void outliner_set_coord_tree_element(SpaceOops *soops, TreeElement *te, int startx, int starty) { TreeElement *ten; /* store coord and continue, we need coordinates for elements outside view too */ - te->xs = (float)startx; - te->ys = (float)(*starty); + te->xs = startx; + te->ys = starty; for (ten = te->subtree.first; ten; ten = ten->next) { outliner_set_coord_tree_element(soops, ten, startx + UI_UNIT_X, starty); @@ -1656,8 +1657,8 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene } } /* store coord and continue, we need coordinates for elements outside view too */ - te->xs = (float)startx; - te->ys = (float)*starty; + te->xs = startx; + te->ys = *starty; te->xend = startx + offsx; if (TSELEM_OPEN(tselem, soops)) { @@ -1668,7 +1669,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene } else { for (ten = te->subtree.first; ten; ten = ten->next) - outliner_set_coord_tree_element(soops, te, startx, starty); + outliner_set_coord_tree_element(soops, ten, startx, *starty); *starty -= UI_UNIT_Y; } diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 0161f53e690..1e9b681197c 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -618,7 +618,7 @@ static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op)) te = outliner_find_id(so, &so->tree, (ID *)OBACT); if (te) { /* make te->ys center of view */ - ytop = (int)(te->ys + BLI_rcti_size_y(&v2d->mask) / 2); + ytop = te->ys + BLI_rcti_size_y(&v2d->mask) / 2; if (ytop > 0) ytop = 0; v2d->cur.ymax = (float)ytop; @@ -984,7 +984,7 @@ static int ed_operator_outliner_datablocks_active(bContext *C) * NOTE: the caller must zero-out all values of the pointers that it passes here first, as * this function does not do that yet */ -static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, +static void tree_element_to_path(TreeElement *te, TreeStoreElem *tselem, ID **id, char **path, int *array_index, short *flag, short *UNUSED(groupmode)) { ListBase hierarchy = {NULL, NULL}; @@ -1152,7 +1152,7 @@ static void do_outliner_drivers_editop(SpaceOops *soops, ListBase *tree, ReportL RNA_property_animateable(&te->rnaptr, te->directdata)) { /* get id + path + index info from the selected element */ - tree_element_to_path(soops, te, tselem, + tree_element_to_path(te, tselem, &id, &path, &array_index, &flag, &groupmode); } @@ -1333,7 +1333,7 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa RNA_property_animateable(&te->rnaptr, te->directdata)) { /* get id + path + index info from the selected element */ - tree_element_to_path(soops, te, tselem, + tree_element_to_path(te, tselem, &id, &path, &array_index, &flag, &groupmode); } @@ -1648,26 +1648,29 @@ void OUTLINER_OT_parent_drop(wmOperatorType *ot) RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", ""); } +static int outliner_parenting_poll(bContext *C) +{ + SpaceOops *soops = CTX_wm_space_outliner(C); + + if (soops) { + return ELEM4(soops->outlinevis, SO_ALL_SCENES, SO_CUR_SCENE, SO_VISIBLE, SO_GROUPS); + } + + return FALSE; +} + static int parent_clear_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { Main *bmain = CTX_data_main(C); - Scene *scene = NULL; Object *ob = NULL; SpaceOops *soops = CTX_wm_space_outliner(C); - TreeElement *te; char obname[MAX_ID_NAME]; RNA_string_get(op->ptr, "dragged_obj", obname); ob = (Object *)BKE_libblock_find_name(ID_OB, obname); /* search forwards to find the object */ - te = outliner_find_id(soops, &soops->tree, (ID *)ob); - /* then search backwards to get the scene */ - scene = (Scene *)outliner_search_back(soops, te, ID_SCE); - - if (scene == NULL) { - return OPERATOR_CANCELLED; - } + outliner_find_id(soops, &soops->tree, (ID *)ob); ED_object_parent_clear(ob, RNA_enum_get(op->ptr, "type")); @@ -1687,7 +1690,7 @@ void OUTLINER_OT_parent_clear(wmOperatorType *ot) /* api callbacks */ ot->invoke = parent_clear_invoke; - ot->poll = ED_operator_outliner_active; + ot->poll = outliner_parenting_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index fe07a7dae9f..5aaf8b5430b 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -48,15 +48,15 @@ struct Object; typedef struct TreeElement { struct TreeElement *next, *prev, *parent; ListBase subtree; - float xs, ys; // do selection - int store_index; // offset in tree store - short flag; // flag for non-saved stuff - short index; // index for data arrays - short idcode; // from TreeStore id - short xend; // width of item display, for select + int xs, ys; // do selection + TreeStoreElem *store_elem; // element in tree store + short flag; // flag for non-saved stuff + short index; // index for data arrays + short idcode; // from TreeStore id + short xend; // width of item display, for select const char *name; - void *directdata; // Armature Bones, Base, Sequence, Strip... - PointerRNA rnaptr; // RNA Pointer + void *directdata; // Armature Bones, Base, Sequence, Strip... + PointerRNA rnaptr; // RNA Pointer } TreeElement; /* TreeElement->flag */ @@ -111,7 +111,7 @@ typedef struct TreeElement { /* get TreeStoreElem associated with a TreeElement * < a: (TreeElement) tree element to find stored element for */ -#define TREESTORE(a) (soops->treestore->data + (a)->store_index) +#define TREESTORE(a) ((a)->store_elem) /* size constants */ #define OL_Y_OFFSET 2 @@ -150,6 +150,7 @@ typedef struct TreeElement { /* outliner_tree.c ----------------------------------------------- */ +void outliner_rebuild_treehash(struct SpaceOops *soops); void outliner_free_tree(ListBase *lb); void outliner_cleanup_tree(struct SpaceOops *soops); diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 9720d981e85..41ad75bb14f 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -282,7 +282,7 @@ static int tree_element_active_material(bContext *C, Scene *scene, SpaceOops *so return 0; } -static int tree_element_active_texture(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set) +static int tree_element_active_texture(bContext *C, Scene *scene, SpaceOops *UNUSED(soops), TreeElement *te, int set) { TreeElement *tep; TreeStoreElem /* *tselem,*/ *tselemp; @@ -384,7 +384,7 @@ static int tree_element_active_camera(bContext *UNUSED(C), Scene *scene, SpaceOo return scene->camera == ob; } -static int tree_element_active_world(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set) +static int tree_element_active_world(bContext *C, Scene *scene, SpaceOops *UNUSED(soops), TreeElement *te, int set) { TreeElement *tep; TreeStoreElem *tselem = NULL; diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index fb56c5c6dfe..c1950e62817 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -45,6 +45,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BLI_ghash.h" #include "BKE_animsys.h" #include "BKE_context.h" @@ -298,13 +299,17 @@ static void object_delete_cb(bContext *C, Scene *scene, TreeElement *te, if (base == NULL) base = BKE_scene_base_find(scene, (Object *)tselem->id); if (base) { + SpaceOops *soops = CTX_wm_space_outliner(C); + // check also library later if (scene->obedit == base->object) ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); ED_base_object_free_and_unlink(CTX_data_main(C), scene, base); te->directdata = NULL; + BLI_ghash_remove(soops->treehash, tselem, NULL, NULL); tselem->id = NULL; + BLI_ghash_insert(soops->treehash, tselem, tselem); } } @@ -683,6 +688,10 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op) outliner_do_object_operation(C, scene, soops, &soops->tree, item_rename_cb); str = "Rename Object"; } + else { + BLI_assert(0); + return OPERATOR_CANCELLED; + } ED_undo_push(C, str); diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 7d3ec148662..514bfc43ac7 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -63,6 +63,8 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLI_math.h" +#include "BLI_ghash.h" +#include "BLI_mempool.h" #include "BLF_translation.h" @@ -84,114 +86,131 @@ #include "outliner_intern.h" /* ********************************************************* */ -/* Defines */ - -#define TS_CHUNK 128 - -/* ********************************************************* */ /* Persistent Data */ static void outliner_storage_cleanup(SpaceOops *soops) { - TreeStore *ts = soops->treestore; + BLI_mempool *ts = soops->treestore; if (ts) { TreeStoreElem *tselem; - int a, unused = 0; + int unused = 0; /* each element used once, for ID blocks with more users to have each a treestore */ - for (a = 0, tselem = ts->data; a < ts->usedelem; a++, tselem++) tselem->used = 0; + BLI_mempool_iter iter; + + BLI_mempool_iternew(ts, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { + tselem->used = 0; + } /* cleanup only after reading file or undo step, and always for * RNA datablocks view in order to save memory */ if (soops->storeflag & SO_TREESTORE_CLEANUP) { - - for (a = 0, tselem = ts->data; a < ts->usedelem; a++, tselem++) { + BLI_mempool_iternew(ts, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { if (tselem->id == NULL) unused++; } if (unused) { - if (ts->usedelem == unused) { - MEM_freeN(ts->data); - ts->data = NULL; - ts->usedelem = ts->totelem = 0; + if (BLI_mempool_count(ts) == unused) { + BLI_mempool_destroy(ts); + soops->treestore = NULL; + + if (soops->treehash) { + BLI_ghash_free(soops->treehash, NULL, NULL); + soops->treehash = NULL; + } } else { - TreeStoreElem *tsnewar, *tsnew; - - tsnew = tsnewar = MEM_mallocN((ts->usedelem - unused) * sizeof(TreeStoreElem), "new tselem"); - for (a = 0, tselem = ts->data; a < ts->usedelem; a++, tselem++) { + TreeStoreElem *tsenew; + BLI_mempool *new_ts = BLI_mempool_create(sizeof(TreeStoreElem), BLI_mempool_count(ts) - unused, + 512, BLI_MEMPOOL_ALLOW_ITER); + BLI_mempool_iternew(ts, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { if (tselem->id) { - *tsnew = *tselem; - tsnew++; + tsenew = BLI_mempool_alloc(new_ts); + *tsenew = *tselem; + } + } + BLI_mempool_destroy(ts); + soops->treestore = new_ts; + + if (soops->treehash) { + /* update hash table to fix broken pointers */ + BLI_ghash_clear(soops->treehash, NULL, NULL); + BLI_mempool_iternew(soops->treestore, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { + BLI_ghash_insert(soops->treehash, tselem, tselem); } } - MEM_freeN(ts->data); - ts->data = tsnewar; - ts->usedelem -= unused; - ts->totelem = ts->usedelem; } } } } } -/* XXX - THIS FUNCTION IS INCREDIBLY SLOW - * ... 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) - * - use a hash for duplicate (could even store a hash per type) - * - use mempool for TreeElements - * */ +static unsigned int tse_hash(const void *ptr) +{ + const TreeStoreElem *tse = (const TreeStoreElem *)ptr; + unsigned int hash; + BLI_assert(tse->type || !tse->nr); + hash = BLI_ghashutil_inthash(SET_INT_IN_POINTER((tse->nr << 16) + tse->type)); + hash ^= BLI_ghashutil_inthash(tse->id); + return hash; +} + +static int tse_cmp(const void *a, const void *b) +{ + const TreeStoreElem *tse_a = (const TreeStoreElem *)a; + const TreeStoreElem *tse_b = (const TreeStoreElem *)b; + return tse_a->type != tse_b->type || tse_a->nr != tse_b->nr || tse_a->id != tse_b->id; +} + static void check_persistent(SpaceOops *soops, TreeElement *te, ID *id, short type, short nr) { - TreeStore *ts; - TreeStoreElem *tselem; - int a; + /* When treestore comes directly from readfile.c, treehash is empty; + * In this case we don't want to get TSE_CLOSED while adding elements one by one, + * that is why this function restores treehash */ + bool restore_treehash = (soops->treestore && !soops->treehash); + TreeStoreElem *tselem, elem_template; - /* case 1; no TreeStore */ if (soops->treestore == NULL) { - soops->treestore = MEM_callocN(sizeof(TreeStore), "treestore"); + /* if treestore was not created in readfile.c, create it here */ + soops->treestore = BLI_mempool_create(sizeof(TreeStoreElem), 1, 512, BLI_MEMPOOL_ALLOW_ITER); } - ts = soops->treestore; - - /* check if 'te' is in treestore */ - tselem = ts->data; - for (a = 0; a < ts->usedelem; a++, tselem++) { - if ((tselem->used == 0) && (tselem->type == type) && (tselem->id == id)) { - if ((type == 0) || (tselem->nr == nr)) { - te->store_index = a; - tselem->used = 1; - return; - } - } + if (soops->treehash == NULL) { + soops->treehash = BLI_ghash_new(tse_hash, tse_cmp, "treehash"); } - /* add 1 element to treestore */ - if (ts->usedelem == ts->totelem) { - TreeStoreElem *tsnew; - - tsnew = MEM_mallocN((ts->totelem + TS_CHUNK) * sizeof(TreeStoreElem), "treestore data"); - if (ts->data) { - memcpy(tsnew, ts->data, ts->totelem * sizeof(TreeStoreElem)); - MEM_freeN(ts->data); + if (restore_treehash) { + BLI_mempool_iter iter; + BLI_mempool_iternew(soops->treestore, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { + BLI_ghash_insert(soops->treehash, tselem, tselem); } - ts->data = tsnew; - ts->totelem += TS_CHUNK; } - - tselem = ts->data + ts->usedelem; - + + /* check if 'te' is in treestore */ + elem_template.type = type; + elem_template.nr = type ? nr : 0; // we're picky! :) + elem_template.id = id; + tselem = BLI_ghash_lookup(soops->treehash, &elem_template); + if (tselem && !tselem->used) { + te->store_elem = tselem; + tselem->used = 1; + return; + } + + /* add 1 element to treestore */ + tselem = BLI_mempool_alloc(soops->treestore); tselem->type = type; - if (type) tselem->nr = nr; // we're picky! :) - else tselem->nr = 0; + tselem->nr = type ? nr : 0; tselem->id = id; tselem->used = 0; tselem->flag = TSE_CLOSED; - te->store_index = ts->usedelem; - - ts->usedelem++; + te->store_elem = tselem; + BLI_ghash_insert(soops->treehash, tselem, tselem); } /* ********************************************************* */ @@ -216,15 +235,14 @@ void outliner_cleanup_tree(SpaceOops *soops) outliner_storage_cleanup(soops); } -/* Find ith item from the treestore */ -static TreeElement *outliner_find_tree_element(ListBase *lb, int store_index) +/* Find specific item from the treestore */ +static TreeElement *outliner_find_tree_element(ListBase *lb, TreeStoreElem *store_elem) { - TreeElement *te = lb->first, *tes; - while (te) { - if (te->store_index == store_index) return te; - tes = outliner_find_tree_element(&te->subtree, store_index); + TreeElement *te, *tes; + for (te = lb->first; te; te = te->next) { + if (te->store_elem == store_elem) return te; + tes = outliner_find_tree_element(&te->subtree, store_elem); if (tes) return tes; - te = te->next; } return NULL; } @@ -232,23 +250,18 @@ static TreeElement *outliner_find_tree_element(ListBase *lb, int store_index) /* tse is not in the treestore, we use its contents to find a match */ TreeElement *outliner_find_tse(SpaceOops *soops, TreeStoreElem *tse) { - TreeStore *ts = soops->treestore; - TreeStoreElem *tselem; - int a; - + GHash *th = soops->treehash; + TreeStoreElem *tselem, tselem_template; + if (tse->id == NULL) return NULL; /* check if 'tse' is in treestore */ - tselem = ts->data; - for (a = 0; a < ts->usedelem; a++, tselem++) { - if ((tse->type == 0 && tselem->type == 0) || (tselem->type == tse->type && tselem->nr == tse->nr)) { - if (tselem->id == tse->id) { - break; - } - } - } + tselem_template.id = tse->id; + tselem_template.type = tse->type; + tselem_template.nr = tse->type ? tse->nr : 0; + tselem = BLI_ghash_lookup(th, &tselem_template); if (tselem) - return outliner_find_tree_element(&soops->tree, a); + return outliner_find_tree_element(&soops->tree, tselem); return NULL; } @@ -274,7 +287,7 @@ TreeElement *outliner_find_id(SpaceOops *soops, ListBase *lb, ID *id) } -ID *outliner_search_back(SpaceOops *soops, TreeElement *te, short idcode) +ID *outliner_search_back(SpaceOops *UNUSED(soops), TreeElement *te, short idcode) { TreeStoreElem *tselem; te = te->parent; @@ -420,7 +433,7 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s for (a = 0, srl = sce->r.layers.first; srl; srl = srl->next, a++) { TreeElement *tenlay = outliner_add_element(soops, &tenla->subtree, sce, te, TSE_R_LAYER, a); tenlay->name = srl->name; - tenlay->directdata = &srl->passflag; + tenlay->directdata = &srl->layflag; if (srl->light_override) outliner_add_element(soops, &tenlay->subtree, srl->light_override, tenlay, TSE_LINKED_LAMP, 0); @@ -804,7 +817,6 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i TreeElement *te; TreeStoreElem *tselem; ID *id = idv; - int a = 0; if (ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) { id = ((PointerRNA *)idv)->id.data; @@ -1084,7 +1096,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i te->name = km->idname; if (TSELEM_OPEN(tselem, soops)) { - a = 0; + int a = 0; for (kmi = km->items.first; kmi; kmi = kmi->next, a++) { const char *key = WM_key_event_string(kmi->type); @@ -1131,7 +1143,7 @@ static int need_add_seq_dup(Sequence *seq) { Sequence *p; - if ((!seq->strip) || (!seq->strip->stripdata) || (!seq->strip->stripdata->name)) + if ((!seq->strip) || (!seq->strip->stripdata)) return(1); /* @@ -1140,7 +1152,7 @@ static int need_add_seq_dup(Sequence *seq) */ p = seq->prev; while (p) { - if ((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) { + if ((!p->strip) || (!p->strip->stripdata)) { p = p->prev; continue; } @@ -1152,7 +1164,7 @@ static int need_add_seq_dup(Sequence *seq) p = seq->next; while (p) { - if ((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) { + if ((!p->strip) || (!p->strip->stripdata)) { p = p->next; continue; } @@ -1188,7 +1200,7 @@ static void outliner_add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *t /* Hierarchy --------------------------------------------- */ /* make sure elements are correctly nested */ -static void outliner_make_hierarchy(SpaceOops *soops, ListBase *lb) +static void outliner_make_hierarchy(ListBase *lb) { TreeElement *te, *ten, *tep; TreeStoreElem *tselem; @@ -1490,7 +1502,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) Object *ob; TreeElement *te = NULL, *ten; TreeStoreElem *tselem; - int show_opened = (soops->treestore == NULL); /* on first view, we open scenes */ + int show_opened = !soops->treestore || !BLI_mempool_count(soops->treestore); /* on first view, we open scenes */ /* Are we looking for something - we want to tag parents to filter child matches * - NOT in datablocks view - searching all datablocks takes way too long to be useful @@ -1562,7 +1574,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) ten = outliner_add_element(soops, &te->subtree, base->object, te, 0, 0); ten->directdata = base; } - outliner_make_hierarchy(soops, &te->subtree); + outliner_make_hierarchy(&te->subtree); /* clear id.newid, to prevent objects be inserted in wrong scenes (parent in other scene) */ for (base = sce->base.first; base; base = base->next) base->object->id.newid = NULL; } @@ -1575,14 +1587,14 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) ten = outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); ten->directdata = base; } - outliner_make_hierarchy(soops, &soops->tree); + outliner_make_hierarchy(&soops->tree); } else if (soops->outlinevis == SO_VISIBLE) { for (base = scene->base.first; base; base = base->next) { if (base->lay & scene->lay) outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); } - outliner_make_hierarchy(soops, &soops->tree); + outliner_make_hierarchy(&soops->tree); } else if (soops->outlinevis == SO_GROUPS) { Group *group; @@ -1596,7 +1608,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) ten = outliner_add_element(soops, &te->subtree, go->ob, te, 0, 0); ten->directdata = NULL; /* eh, why? */ } - outliner_make_hierarchy(soops, &te->subtree); + outliner_make_hierarchy(&te->subtree); /* clear id.newid, to prevent objects be inserted in wrong scenes (parent in other scene) */ for (go = group->gobject.first; go; go = go->next) go->ob->id.newid = NULL; } @@ -1611,7 +1623,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) ten->directdata = base; } } - outliner_make_hierarchy(soops, &soops->tree); + outliner_make_hierarchy(&soops->tree); } } else if (soops->outlinevis == SO_SELECTED) { @@ -1623,7 +1635,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) } } } - outliner_make_hierarchy(soops, &soops->tree); + outliner_make_hierarchy(&soops->tree); } else if (soops->outlinevis == SO_SEQUENCE) { Sequence *seq; diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index 8da244b1db1..874852ee320 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -37,6 +37,8 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_mempool.h" +#include "BLI_ghash.h" #include "BKE_context.h" #include "BKE_screen.h" @@ -142,6 +144,10 @@ static int outliner_parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent * UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + if (!ELEM4(soops->outlinevis, SO_ALL_SCENES, SO_CUR_SCENE, SO_VISIBLE, SO_GROUPS)) { + return FALSE; + } + if (drag->type == WM_DRAG_ID) { ID *id = (ID *)drag->poin; if (GS(id->name) == ID_OB) { @@ -426,10 +432,11 @@ static void outliner_free(SpaceLink *sl) outliner_free_tree(&soutliner->tree); if (soutliner->treestore) { - if (soutliner->treestore->data) MEM_freeN(soutliner->treestore->data); - MEM_freeN(soutliner->treestore); + BLI_mempool_destroy(soutliner->treestore); + } + if (soutliner->treehash) { + BLI_ghash_free(soutliner->treehash, NULL, NULL); } - } /* spacetype; init callback */ @@ -445,6 +452,7 @@ static SpaceLink *outliner_duplicate(SpaceLink *sl) soutlinern->tree.first = soutlinern->tree.last = NULL; soutlinern->treestore = NULL; + soutlinern->treehash = NULL; return (SpaceLink *)soutlinern; } diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c index 197cc64dea4..36589984c78 100644 --- a/source/blender/editors/space_sequencer/sequencer_buttons.c +++ b/source/blender/editors/space_sequencer/sequencer_buttons.c @@ -76,7 +76,7 @@ void sequencer_buttons_register(ARegionType *art) /* **************** operator to open/close properties view ************* */ -static int sequencer_properties(bContext *C, wmOperator *UNUSED(op)) +static int sequencer_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = sequencer_has_buttons_region(sa); @@ -93,7 +93,7 @@ void SEQUENCER_OT_properties(wmOperatorType *ot) ot->idname = "SEQUENCER_OT_properties"; ot->description = "Open sequencer properties panel"; - ot->exec = sequencer_properties; + ot->exec = sequencer_properties_toggle_exec; ot->poll = ED_operator_sequencer_active; /* flags */ diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index c13dc118de5..955a9c78c56 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2721,7 +2721,6 @@ static void seq_copy_del_sound(Scene *scene, Sequence *seq) } } -/* TODO, validate scenes */ static int sequencer_copy_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); @@ -2766,6 +2765,11 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) for (seq = seqbase_clipboard.first; seq; seq = seq->next) { seq_copy_del_sound(scene, seq); } + + /* duplicate pointers */ + for (seq = seqbase_clipboard.first; seq; seq = seq->next) { + BKE_sequence_clipboard_pointers_store(seq); + } } return OPERATOR_FINISHED; @@ -2790,11 +2794,12 @@ void SEQUENCER_OT_copy(wmOperatorType *ot) static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op)) { + Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Editing *ed = BKE_sequencer_editing_get(scene, TRUE); /* create if needed */ ListBase nseqbase = {NULL, NULL}; int ofs; - Sequence *iseq; + Sequence *iseq, *iseq_first; ED_sequencer_deselect_all(scene); ofs = scene->r.cfra - seqbase_clipboard_frame; @@ -2805,19 +2810,33 @@ static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op)) if (ofs) { for (iseq = nseqbase.first; iseq; iseq = iseq->next) { BKE_sequence_translate(scene, iseq, ofs); - BKE_sequence_sound_init(scene, iseq); } } - iseq = nseqbase.first; + for (iseq = nseqbase.first; iseq; iseq = iseq->next) { + BKE_sequence_clipboard_pointers_restore(iseq, bmain); + } + + for (iseq = nseqbase.first; iseq; iseq = iseq->next) { + BKE_sequence_sound_init(scene, iseq); + } + + iseq_first = nseqbase.first; BLI_movelisttolist(ed->seqbasep, &nseqbase); /* make sure the pasted strips have unique names between them */ - for (; iseq; iseq = iseq->next) { + for (iseq = iseq_first; iseq; iseq = iseq->next) { BKE_sequencer_recursive_apply(iseq, apply_unique_name_cb, scene); } + /* ensure pasted strips don't overlap */ + for (iseq = iseq_first; iseq; iseq = iseq->next) { + if (BKE_sequence_test_overlap(ed->seqbasep, iseq)) { + BKE_sequence_base_shuffle(ed->seqbasep, iseq, scene); + } + } + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c index f7116c01a72..ad761971200 100644 --- a/source/blender/editors/space_time/space_time.c +++ b/source/blender/editors/space_time/space_time.c @@ -420,6 +420,9 @@ static void time_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn) case NC_SCENE: { switch (wmn->data) { + case ND_RENDER_RESULT: + ED_area_tag_redraw(sa); + break; case ND_OB_ACTIVE: case ND_FRAME: ED_area_tag_refresh(sa); @@ -559,6 +562,7 @@ static void time_main_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), AR ED_region_tag_redraw(ar); break; } + break; } } @@ -588,6 +592,7 @@ static void time_header_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), case NC_SCENE: { switch (wmn->data) { + case ND_RENDER_RESULT: case ND_OB_SELECT: case ND_FRAME: case ND_FRAME_RANGE: diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index fb20f082085..d3d8868520d 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -1485,7 +1485,7 @@ static void draw_dof_ellipse(float ax, float az) z = staticSine[i]; px = 0.0f; - for (j = 1; j < n - i + 1; j++) { + for (j = 1; j <= (n - i); j++) { x = staticSine[j]; if (j == n - i) { @@ -2060,20 +2060,10 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, } /* in editmode, we don't store the bone matrix... */ -static void get_matrix_editbone(EditBone *eBone, float bmat[4][4]) +static void get_matrix_editbone(EditBone *ebone, float bmat[4][4]) { - float delta[3]; - float mat[3][3]; - - /* Compose the parent transforms (i.e. their translations) */ - sub_v3_v3v3(delta, eBone->tail, eBone->head); - - eBone->length = (float)sqrt(delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2]); - - vec_roll_to_mat3(delta, eBone->roll, mat); - copy_m4_m3(bmat, mat); - - add_v3_v3(bmat[3], eBone->head); + ebone->length = len_v3v3(ebone->tail, ebone->head); + ED_armature_ebone_to_mat4(ebone, bmat); } static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt) diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 767d4aca3a8..16423c60cac 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -77,7 +77,7 @@ /* user data structures for derived mesh callbacks */ typedef struct drawMeshFaceSelect_userData { Mesh *me; - BLI_bitmap edge_flags; /* pairs of edge options (visible, select) */ + BLI_bitmap *edge_flags; /* pairs of edge options (visible, select) */ } drawMeshFaceSelect_userData; typedef struct drawEMTFMapped_userData { @@ -100,9 +100,9 @@ typedef struct drawTFace_userData { BLI_INLINE int edge_vis_index(const int index) { return index * 2; } BLI_INLINE int edge_sel_index(const int index) { return index * 2 + 1; } -static BLI_bitmap get_tface_mesh_marked_edge_info(Mesh *me) +static BLI_bitmap *get_tface_mesh_marked_edge_info(Mesh *me) { - BLI_bitmap bitmap_edge_flags = BLI_BITMAP_NEW(me->totedge * 2, __func__); + BLI_bitmap *bitmap_edge_flags = BLI_BITMAP_NEW(me->totedge * 2, __func__); MPoly *mp; MLoop *ml; int i, j; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index dca1160b194..62e3f8471a3 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2002,7 +2002,7 @@ static void drawSelectedVertices(DerivedMesh *dm, Mesh *me) data.col[2] = act_col; glBegin(GL_POINTS); - dm->foreachMappedVert(dm, drawSelectedVertices__mapFunc, &data); + dm->foreachMappedVert(dm, drawSelectedVertices__mapFunc, &data, DM_FOREACH_NOP); glEnd(); } @@ -2068,7 +2068,7 @@ static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, Deriv calcDrawDMNormalScale(ob, &data); glBegin(GL_LINES); - dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, &data); + dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL); glEnd(); } @@ -2088,7 +2088,7 @@ static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, char sel) void *ptrs[2] = {em, &sel}; bglBegin(GL_POINTS); - dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, ptrs); + dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, ptrs, DM_FOREACH_NOP); bglEnd(); } @@ -2133,7 +2133,7 @@ static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, Object *ob, Deriv calcDrawDMNormalScale(ob, &data); glBegin(GL_LINES); - dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, &data); + dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL); glEnd(); } @@ -2204,7 +2204,7 @@ static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, const char sel, BMVer invert_m4(data.imat); bglBegin(GL_POINTS); - dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data); + dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data, DM_FOREACH_NOP); bglEnd(); } @@ -2534,7 +2534,7 @@ static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm) if (data.cd_layer_offset != -1) { glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2); bglBegin(GL_POINTS); - dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, &data); + dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, &data, DM_FOREACH_NOP); bglEnd(); } } @@ -3094,8 +3094,8 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d, BMVert *eve_act = NULL; bool use_occlude_wire = (v3d->flag2 & V3D_OCCLUDE_WIRE) && (dt > OB_WIRE); - // if (cageDM) BLI_assert(!(cageDM->dirty & DM_DIRTY_NORMALS)); - if (finalDM) BLI_assert(!(finalDM->dirty & DM_DIRTY_NORMALS)); + // BLI_assert(!cageDM || !(cageDM->dirty & DM_DIRTY_NORMALS)); + BLI_assert(!finalDM || !(finalDM->dirty & DM_DIRTY_NORMALS)); if (em->bm->selected.last) { BMEditSelection *ese = em->bm->selected.last; @@ -3132,9 +3132,10 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d, } else if (dt > OB_WIRE) { if (use_occlude_wire) { + /* use the cageDM since it always overlaps the editmesh faces */ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, - GPU_enable_material, NULL, me->edit_btmesh, 0); + cageDM->drawMappedFaces(cageDM, draw_em_fancy__setFaceOpts, + GPU_enable_material, NULL, me->edit_btmesh, 0); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } else if (check_object_draw_texture(scene, v3d, dt)) { @@ -3851,8 +3852,8 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag, glEnd(); glEnable(GL_LIGHTING); - break; } + break; case DL_SURF: if (dl->index) { @@ -6779,7 +6780,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short cpack(0xffffff); set_inverted_drawing(1); - for (i = 0; i < (selend - selstart + 1); i++) { + for (i = 0; i <= (selend - selstart); i++) { SelBox *sb = &(cu->selboxes[i]); if (i < (selend - selstart)) { @@ -7052,18 +7053,15 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short mul_mat3_m4_v3(ob->imat, viewnormal); normalize_v3(viewnormal); - /* set dynamic boundaries to draw the volume */ - p0[0] = sds->p0[0] + sds->cell_size[0] * sds->res_min[0] + sds->obj_shift_f[0]; - p0[1] = sds->p0[1] + sds->cell_size[1] * sds->res_min[1] + sds->obj_shift_f[1]; - p0[2] = sds->p0[2] + sds->cell_size[2] * sds->res_min[2] + sds->obj_shift_f[2]; - p1[0] = sds->p0[0] + sds->cell_size[0] * sds->res_max[0] + sds->obj_shift_f[0]; - p1[1] = sds->p0[1] + sds->cell_size[1] * sds->res_max[1] + sds->obj_shift_f[1]; - p1[2] = sds->p0[2] + sds->cell_size[2] * sds->res_max[2] + sds->obj_shift_f[2]; - - /* scale cube to global space to equalize volume slicing on all axises + /* set dynamic boundaries to draw the volume + * also scale cube to global space to equalize volume slicing on all axises * (its scaled back before drawing) */ - mul_v3_v3(p0, ob->size); - mul_v3_v3(p1, ob->size); + p0[0] = (sds->p0[0] + sds->cell_size[0] * sds->res_min[0] + sds->obj_shift_f[0]) * fabsf(ob->size[0]); + p0[1] = (sds->p0[1] + sds->cell_size[1] * sds->res_min[1] + sds->obj_shift_f[1]) * fabsf(ob->size[1]); + p0[2] = (sds->p0[2] + sds->cell_size[2] * sds->res_min[2] + sds->obj_shift_f[2]) * fabsf(ob->size[2]); + p1[0] = (sds->p0[0] + sds->cell_size[0] * sds->res_max[0] + sds->obj_shift_f[0]) * fabsf(ob->size[0]); + p1[1] = (sds->p0[1] + sds->cell_size[1] * sds->res_max[1] + sds->obj_shift_f[1]) * fabsf(ob->size[1]); + p1[2] = (sds->p0[2] + sds->cell_size[2] * sds->res_max[2] + sds->obj_shift_f[2]) * fabsf(ob->size[2]); if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { smd->domain->tex = NULL; @@ -7255,23 +7253,19 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT); for (curcon = list->first; curcon; curcon = curcon->next) { - bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon); - ListBase targets = {NULL, NULL}; - bConstraintTarget *ct; - - if (ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_OBJECTSOLVER)) { + if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_OBJECTSOLVER)) { /* special case for object solver and follow track constraints because they don't fill * constraint targets properly (design limitation -- scene is needed for their target * but it can't be accessed from get_targets callvack) */ Object *camob = NULL; - if (cti->type == CONSTRAINT_TYPE_FOLLOWTRACK) { + if (curcon->type == CONSTRAINT_TYPE_FOLLOWTRACK) { bFollowTrackConstraint *data = (bFollowTrackConstraint *)curcon->data; camob = data->camera ? data->camera : scene->camera; } - else if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) { + else if (curcon->type == CONSTRAINT_TYPE_OBJECTSOLVER) { bObjectSolverConstraint *data = (bObjectSolverConstraint *)curcon->data; camob = data->camera ? data->camera : scene->camera; @@ -7286,26 +7280,33 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short setlinestyle(0); } } - else if ((curcon->flag & CONSTRAINT_EXPAND) && (cti->get_constraint_targets)) { - cti->get_constraint_targets(curcon, &targets); - - for (ct = targets.first; ct; ct = ct->next) { - /* calculate target's matrix */ - if (cti->get_target_matrix) - cti->get_target_matrix(curcon, cob, ct, BKE_scene_frame_get(scene)); - else - unit_m4(ct->matrix); - - setlinestyle(3); - glBegin(GL_LINES); - glVertex3fv(ct->matrix[3]); - glVertex3fv(ob->obmat[3]); - glEnd(); - setlinestyle(0); + else { + bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon); + + if ((cti && cti->get_constraint_targets) && (curcon->flag & CONSTRAINT_EXPAND)) { + ListBase targets = {NULL, NULL}; + bConstraintTarget *ct; + + cti->get_constraint_targets(curcon, &targets); + + for (ct = targets.first; ct; ct = ct->next) { + /* calculate target's matrix */ + if (cti->get_target_matrix) + cti->get_target_matrix(curcon, cob, ct, BKE_scene_frame_get(scene)); + else + unit_m4(ct->matrix); + + setlinestyle(3); + glBegin(GL_LINES); + glVertex3fv(ct->matrix[3]); + glVertex3fv(ob->obmat[3]); + glEnd(); + setlinestyle(0); + } + + if (cti->flush_constraint_targets) + cti->flush_constraint_targets(curcon, &targets, 1); } - - if (cti->flush_constraint_targets) - cti->flush_constraint_targets(curcon, &targets, 1); } } @@ -7358,7 +7359,7 @@ static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset) data.offset = (void *)(intptr_t) offset; glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); bglBegin(GL_POINTS); - dm->foreachMappedVert(dm, bbs_obmode_mesh_verts__mapFunc, &data); + dm->foreachMappedVert(dm, bbs_obmode_mesh_verts__mapFunc, &data, DM_FOREACH_NOP); bglEnd(); glPointSize(1.0); } @@ -7381,7 +7382,7 @@ static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *dm, int offset) glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); bglBegin(GL_POINTS); - dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, ptrs); + dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, ptrs, DM_FOREACH_NOP); bglEnd(); glPointSize(1.0); } @@ -7447,7 +7448,7 @@ static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d, glPointSize(UI_GetThemeValuef(TH_FACEDOT_SIZE)); bglBegin(GL_POINTS); - dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, ptrs); + dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, ptrs, DM_FOREACH_NOP); bglEnd(); } diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index 8323e7de9a4..542ed7af0e6 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -461,7 +461,9 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0], (points[i * 3 + 1] - min[1]) * cor[1] / size[1], (points[i * 3 + 2] - min[2]) * cor[2] / size[2]); - glVertex3f(points[i * 3 + 0] / ob->size[0], points[i * 3 + 1] / ob->size[1], points[i * 3 + 2] / ob->size[2]); + glVertex3f(points[i * 3 + 0] / fabsf(ob->size[0]), + points[i * 3 + 1] / fabsf(ob->size[1]), + points[i * 3 + 2] / fabsf(ob->size[2])); } glEnd(); @@ -474,7 +476,9 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0], (points[i * 3 + 1] - min[1]) * cor[1] / size[1], (points[i * 3 + 2] - min[2]) * cor[2] / size[2]); - glVertex3f(points[i * 3 + 0] / ob->size[0], points[i * 3 + 1] / ob->size[1], points[i * 3 + 2] / ob->size[2]); + glVertex3f(points[i * 3 + 0] / fabsf(ob->size[0]), + points[i * 3 + 1] / fabsf(ob->size[1]), + points[i * 3 + 2] / fabsf(ob->size[2])); } glEnd(); } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 92bf8214336..6c61c2af816 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -826,6 +826,7 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN if (rv3d->persp == RV3D_CAMOB) { ED_region_tag_redraw(ar); } + break; } } break; @@ -881,8 +882,8 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN /* screen was changed, need to update used layers due to NC_SCENE|ND_LAYER_CONTENT */ /* updates used layers only for View3D in active screen */ if (wmn->reference) { - bScreen *sc = wmn->reference; - view3d_recalc_used_layers(ar, wmn, sc->scene); + bScreen *sc_ref = wmn->reference; + view3d_recalc_used_layers(ar, wmn, sc_ref->scene); } ED_region_tag_redraw(ar); break; @@ -1141,17 +1142,17 @@ const char *view3d_context_dir[] = { static int view3d_context(const bContext *C, const char *member, bContextDataResult *result) { - View3D *v3d = CTX_wm_view3d(C); - Scene *scene = CTX_data_scene(C); - Base *base; /* fallback to the scene layer, allows duplicate and other object operators to run outside the 3d view */ - unsigned int lay = v3d ? v3d->lay : scene->lay; if (CTX_data_dir(member)) { CTX_data_dir_set(result, view3d_context_dir); } else if (CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) { - int selected_objects = CTX_data_equals(member, "selected_objects"); + View3D *v3d = CTX_wm_view3d(C); + Scene *scene = CTX_data_scene(C); + const unsigned int lay = v3d ? v3d->lay : scene->lay; + Base *base; + const bool selected_objects = CTX_data_equals(member, "selected_objects"); for (base = scene->base.first; base; base = base->next) { if ((base->flag & SELECT) && (base->lay & lay)) { @@ -1167,7 +1168,11 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes return 1; } else if (CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) { - int selected_editable_objects = CTX_data_equals(member, "selected_editable_objects"); + View3D *v3d = CTX_wm_view3d(C); + Scene *scene = CTX_data_scene(C); + const unsigned int lay = v3d ? v3d->lay : scene->lay; + Base *base; + const bool selected_editable_objects = CTX_data_equals(member, "selected_editable_objects"); for (base = scene->base.first; base; base = base->next) { if ((base->flag & SELECT) && (base->lay & lay)) { @@ -1185,7 +1190,11 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes return 1; } else if (CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) { - int visible_objects = CTX_data_equals(member, "visible_objects"); + View3D *v3d = CTX_wm_view3d(C); + Scene *scene = CTX_data_scene(C); + const unsigned int lay = v3d ? v3d->lay : scene->lay; + Base *base; + const bool visible_objects = CTX_data_equals(member, "visible_objects"); for (base = scene->base.first; base; base = base->next) { if (base->lay & lay) { @@ -1201,7 +1210,11 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes return 1; } else if (CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) { - int selectable_objects = CTX_data_equals(member, "selectable_objects"); + View3D *v3d = CTX_wm_view3d(C); + Scene *scene = CTX_data_scene(C); + const unsigned int lay = v3d ? v3d->lay : scene->lay; + Base *base; + const bool selectable_objects = CTX_data_equals(member, "selectable_objects"); for (base = scene->base.first; base; base = base->next) { if (base->lay & lay) { @@ -1217,6 +1230,9 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes return 1; } else if (CTX_data_equals(member, "active_base")) { + View3D *v3d = CTX_wm_view3d(C); + Scene *scene = CTX_data_scene(C); + const unsigned int lay = v3d ? v3d->lay : scene->lay; if (scene->basact && (scene->basact->lay & lay)) { Object *ob = scene->basact->object; /* if hidden but in edit mode, we still display, can happen with animation */ @@ -1227,6 +1243,9 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes return 1; } else if (CTX_data_equals(member, "active_object")) { + View3D *v3d = CTX_wm_view3d(C); + Scene *scene = CTX_data_scene(C); + const unsigned int lay = v3d ? v3d->lay : scene->lay; if (scene->basact && (scene->basact->lay & lay)) { Object *ob = scene->basact->object; if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0 || (ob->mode & OB_MODE_EDIT)) diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 536bccfbe7a..75e7605df6b 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -95,8 +95,6 @@ typedef struct { float ob_dims[3]; short link_scale; float ve_median[NBR_TRANSFORM_PROPERTIES]; - int curdef; - float *defweightp; } TransformProperties; /* Helper function to compute a median changed value, @@ -154,17 +152,14 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float #define L_WEIGHT 4 uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : NULL; - MDeformVert *dvert = NULL; TransformProperties *tfp; float median[NBR_TRANSFORM_PROPERTIES], ve_median[NBR_TRANSFORM_PROPERTIES]; int tot, totedgedata, totcurvedata, totlattdata, totskinradius, totcurvebweight; bool has_meshdata = false; - char defstr[320]; PointerRNA data_ptr; fill_vn_fl(median, NBR_TRANSFORM_PROPERTIES, 0.0f); tot = totedgedata = totcurvedata = totlattdata = totskinradius = totcurvebweight = 0; - defstr[0] = '\0'; /* make sure we got storage */ if (v3d->properties_storage == NULL) @@ -175,7 +170,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float Mesh *me = ob->data; BMEditMesh *em = me->edit_btmesh; BMesh *bm = em->bm; - BMVert *eve, *evedef = NULL; + BMVert *eve; BMEdge *eed; BMIter iter; @@ -187,7 +182,6 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if (bm->totvertsel) { BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - evedef = eve; tot++; add_v3_v3(&median[LOC_X], eve->co); @@ -226,33 +220,6 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float totedgedata = bm->totedgesel; } - /* check for defgroups */ - if (evedef) - dvert = CustomData_bmesh_get(&bm->vdata, evedef->head.data, CD_MDEFORMVERT); - if (tot == 1 && dvert && dvert->totweight) { - bDeformGroup *dg; - int i, max = 1, init = 1; - char str[320]; - - for (i = 0; i < dvert->totweight; i++) { - dg = BLI_findlink(&ob->defbase, dvert->dw[i].def_nr); - if (dg) { - max += BLI_snprintf(str, sizeof(str), "%s %%x%d|", dg->name, dvert->dw[i].def_nr); - if (max < sizeof(str)) strcat(defstr, str); - } - - if (tfp->curdef == dvert->dw[i].def_nr) { - init = 0; - tfp->defweightp = &dvert->dw[i].weight; - } - } - - if (init) { /* needs new initialized */ - tfp->curdef = dvert->dw[0].def_nr; - tfp->defweightp = &dvert->dw[0].weight; - } - } - has_meshdata = (totedgedata || totskinradius); } else if (ob->type == OB_CURVE || ob->type == OB_SURF) { @@ -1204,7 +1171,7 @@ void view3d_buttons_register(ARegionType *art) BLI_addtail(&art->paneltypes, pt); } -static int view3d_properties(bContext *C, wmOperator *UNUSED(op)) +static int view3d_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = view3d_has_buttons_region(sa); @@ -1221,7 +1188,7 @@ void VIEW3D_OT_properties(wmOperatorType *ot) ot->description = "Toggles the properties panel display"; ot->idname = "VIEW3D_OT_properties"; - ot->exec = view3d_properties; + ot->exec = view3d_properties_toggle_exec; ot->poll = ED_operator_view3d_active; /* flags */ diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 61532e75ee9..fa8d43b1756 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -350,18 +350,19 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char ** } } else { - short sublines = v3d->gridsubdiv; + const double sublines = v3d->gridsubdiv; + const float sublines_fl = v3d->gridsubdiv; if (dx < GRID_MIN_PX_D) { - rv3d->gridview *= sublines; + rv3d->gridview *= sublines_fl; dx *= sublines; if (dx < GRID_MIN_PX_D) { - rv3d->gridview *= sublines; + rv3d->gridview *= sublines_fl; dx *= sublines; if (dx < GRID_MIN_PX_D) { - rv3d->gridview *= sublines; + rv3d->gridview *= sublines_fl; dx *= sublines; if (dx < GRID_MIN_PX_D) { /* pass */ @@ -389,10 +390,10 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char ** } else { if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */ - rv3d->gridview /= sublines; + rv3d->gridview /= sublines_fl; dx /= sublines; if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */ - rv3d->gridview /= sublines; + rv3d->gridview /= sublines_fl; dx /= sublines; if (dx > (GRID_MIN_PX_D * 10.0)) { UI_ThemeColor(TH_GRID); @@ -494,6 +495,7 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit) /* draw the Y axis and/or grid lines */ if (v3d->gridflag & V3D_SHOW_FLOOR) { + const int sublines = v3d->gridsubdiv; float vert[4][3] = {{0.0f}}; unsigned char col_bg[3]; unsigned char col_grid_emphasise[3], col_grid_light[3]; @@ -517,7 +519,7 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit) for (a = -gridlines; a <= gridlines; a++) { const float line = a * grid_scale; - const int is_emphasise = (a % 10) == 0; + const int is_emphasise = (a % sublines) == 0; if (is_emphasise != prev_emphasise) { glColor3ubv(is_emphasise ? col_grid_emphasise : col_grid_light); @@ -531,8 +533,6 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit) } glDisableClientState(GL_VERTEX_ARRAY); - - GPU_print_error("sdsd"); } /* draw the Z axis line */ @@ -1189,7 +1189,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) y4 = y1 + scene->r.border.ymax * (y2 - y1); cpack(0x4040FF); - glRectf(x3, y3, x4, y4); + glRecti(x3, y3, x4, y4); } /* safety border */ @@ -2953,10 +2953,8 @@ bool ED_view3d_calc_render_border(Scene *scene, View3D *v3d, ARegion *ar, rcti * rect->ymax = v3d->render_border.ymax * ar->winy; } - rect->xmin = CLAMPIS(ar->winrct.xmin + rect->xmin, ar->winrct.xmin, ar->winrct.xmax); - rect->ymin = CLAMPIS(ar->winrct.ymin + rect->ymin, ar->winrct.ymin, ar->winrct.ymax); - rect->xmax = CLAMPIS(ar->winrct.xmin + rect->xmax, ar->winrct.xmin, ar->winrct.xmax); - rect->ymax = CLAMPIS(ar->winrct.ymin + rect->ymax, ar->winrct.ymin, ar->winrct.ymax); + BLI_rcti_translate(rect, ar->winrct.xmin, ar->winrct.ymin); + BLI_rcti_isect(&ar->winrct, rect, rect); return true; } @@ -3422,7 +3420,7 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha setlinestyle(3); cpack(0x4040FF); - glRectf(v3d->render_border.xmin * ar->winx, v3d->render_border.ymin * ar->winy, + glRecti(v3d->render_border.xmin * ar->winx, v3d->render_border.ymin * ar->winy, v3d->render_border.xmax * ar->winx, v3d->render_border.ymax * ar->winy); setlinestyle(0); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index bfc64d1d37a..7b8c197f3e6 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -3241,16 +3241,11 @@ static void axis_set_view(bContext *C, View3D *v3d, ARegion *ar, align_active = false; } else { - const float z_flip_quat[4] = {0.0f, 0.0f, 0.0f, 1.0f}; float obact_quat[4]; float twmat[3][3]; - /* flip the input, the end result being that an object - * with no rotation behaves as if 'align_active' is off */ - mul_qt_qtqt(new_quat, new_quat, z_flip_quat); - /* same as transform manipulator when normal is set */ - ED_getTransformOrientationMatrix(C, twmat, false); + ED_getTransformOrientationMatrix(C, twmat, true); mat3_to_quat(obact_quat, twmat); invert_qt(obact_quat); @@ -4205,28 +4200,27 @@ float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float */ void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist) { + float nmat[3][3]; + + /* dist depends on offset */ + BLI_assert(dist == NULL || ofs != NULL); + + copy_m3_m4(nmat, mat); + normalize_m3(nmat); + /* Offset */ if (ofs) negate_v3_v3(ofs, mat[3]); /* Quat */ if (quat) { - float imat[4][4]; - normalize_m4_m4(imat, mat); - invert_m4(imat); - mat4_to_quat(quat, imat); + float imat[3][3]; + invert_m3_m3(imat, nmat); + mat3_to_quat(quat, imat); } - if (dist) { - float nmat[3][3]; - float vec[3]; - - vec[0] = 0.0f; - vec[1] = 0.0f; - vec[2] = -(*dist); - - copy_m3_m4(nmat, mat); - normalize_m3(nmat); + if (ofs && dist) { + float vec[3] = {0.0f, 0.0f, -(*dist)}; mul_m3_v3(nmat, vec); sub_v3_v3(ofs, vec); diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c index 0490d8763d8..d13ab15d837 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.c +++ b/source/blender/editors/space_view3d/view3d_iterators.c @@ -124,7 +124,7 @@ void meshobject_foreachScreenVert( ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ } - dm->foreachMappedVert(dm, meshobject_foreachScreenVert__mapFunc, &data); + dm->foreachMappedVert(dm, meshobject_foreachScreenVert__mapFunc, &data, DM_FOREACH_NOP); dm->release(dm); } @@ -166,7 +166,7 @@ void mesh_foreachScreenVert( } EDBM_index_arrays_ensure(vc->em, BM_VERT); - dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data); + dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data, DM_FOREACH_NOP); dm->release(dm); } @@ -262,7 +262,7 @@ void mesh_foreachScreenFace( data.clip_flag = clip_flag; EDBM_index_arrays_ensure(vc->em, BM_FACE); - dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data); + dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data, DM_FOREACH_NOP); dm->release(dm); } diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 16282b0d49c..19426ab2dfa 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -146,12 +146,13 @@ static void edbm_backbuf_check_and_select_verts(BMEditMesh *em, const bool selec BMIter iter; unsigned int index = bm_wireoffs; - for (eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL); eve; eve = BM_iter_step(&iter), index++) { + BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { if (EDBM_backbuf_check(index)) { BM_vert_select_set(em->bm, eve, select); } } + index++; } } @@ -161,13 +162,13 @@ static void edbm_backbuf_check_and_select_edges(BMEditMesh *em, const bool selec BMIter iter; int index = bm_solidoffs; - eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL); - for (; eed; eed = BM_iter_step(&iter), index++) { + BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { if (EDBM_backbuf_check(index)) { BM_edge_select_set(em->bm, eed, select); } } + index++; } } @@ -177,13 +178,13 @@ static void edbm_backbuf_check_and_select_faces(BMEditMesh *em, const bool selec BMIter iter; unsigned int index = 1; - efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL); - for (; efa; efa = BM_iter_step(&iter), index++) { + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { if (EDBM_backbuf_check(index)) { BM_face_select_set(em->bm, efa, select); } } + index++; } } @@ -2553,7 +2554,7 @@ static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChan /* project tail location to screenspace */ if (screen_co_b[0] != IS_CLIPPED) { points_proj_tot++; - if (pchan_circle_doSelectJoint(data, pchan, screen_co_a)) { + if (pchan_circle_doSelectJoint(data, pchan, screen_co_b)) { is_point_done = true; } } diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index fb7bbdaa178..0f2f07a1053 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -343,7 +343,7 @@ static void make_trans_verts(Object *obedit, float min[3], float max[3], int mod if (transvmain && em->derivedCage) { EDBM_index_arrays_ensure(em, BM_VERT); - em->derivedCage->foreachMappedVert(em->derivedCage, set_mapped_co, userdata); + em->derivedCage->foreachMappedVert(em->derivedCage, set_mapped_co, userdata, DM_FOREACH_NOP); } } else if (obedit->type == OB_ARMATURE) { @@ -532,7 +532,7 @@ static void make_trans_verts(Object *obedit, float min[3], float max[3], int mod /* *********************** operators ******************** */ -static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op)) +static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) { Object *obedit = CTX_data_edit_object(C); Scene *scene = CTX_data_scene(C); @@ -660,11 +660,11 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot) { /* identifiers */ ot->name = "Snap Selection to Grid"; - ot->description = "Snap selected item(s) to nearest grid node"; + ot->description = "Snap selected item(s) to nearest grid division"; ot->idname = "VIEW3D_OT_snap_selected_to_grid"; /* api callbacks */ - ot->exec = snap_sel_to_grid; + ot->exec = snap_sel_to_grid_exec; ot->poll = ED_operator_region_view3d_active; /* flags */ @@ -673,7 +673,7 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot) /* *************************************************** */ -static int snap_sel_to_curs(bContext *C, wmOperator *op) +static int snap_sel_to_curs_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); Scene *scene = CTX_data_scene(C); @@ -832,7 +832,7 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot) ot->idname = "VIEW3D_OT_snap_selected_to_cursor"; /* api callbacks */ - ot->exec = snap_sel_to_curs; + ot->exec = snap_sel_to_curs_exec; ot->poll = ED_operator_view3d_active; /* flags */ @@ -844,7 +844,7 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot) /* *************************************************** */ -static int snap_curs_to_grid(bContext *C, wmOperator *UNUSED(op)) +static int snap_curs_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); RegionView3D *rv3d = CTX_wm_region_data(C); @@ -867,11 +867,11 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot) { /* identifiers */ ot->name = "Snap Cursor to Grid"; - ot->description = "Snap cursor to nearest grid node"; + ot->description = "Snap cursor to nearest grid division"; ot->idname = "VIEW3D_OT_snap_cursor_to_grid"; /* api callbacks */ - ot->exec = snap_curs_to_grid; + ot->exec = snap_curs_to_grid_exec; ot->poll = ED_operator_region_view3d_active; /* flags */ @@ -1029,7 +1029,7 @@ static bool snap_curs_to_sel_ex(bContext *C, float cursor[3]) return true; } -static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op)) +static int snap_curs_to_sel_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); @@ -1055,7 +1055,7 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot) ot->idname = "VIEW3D_OT_snap_cursor_to_selected"; /* api callbacks */ - ot->exec = snap_curs_to_sel; + ot->exec = snap_curs_to_sel_exec; ot->poll = ED_operator_view3d_active; /* flags */ @@ -1064,7 +1064,7 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot) /* ********************************************** */ -static int snap_curs_to_active(bContext *C, wmOperator *UNUSED(op)) +static int snap_curs_to_active_exec(bContext *C, wmOperator *UNUSED(op)) { Object *obedit = CTX_data_edit_object(C); Object *obact = CTX_data_active_object(C); @@ -1113,7 +1113,7 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot) ot->idname = "VIEW3D_OT_snap_cursor_to_active"; /* api callbacks */ - ot->exec = snap_curs_to_active; + ot->exec = snap_curs_to_active_exec; ot->poll = ED_operator_view3d_active; /* flags */ @@ -1122,7 +1122,7 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot) /* **************************************************** */ /*New Code - Snap Cursor to Center -*/ -static int snap_curs_to_center(bContext *C, wmOperator *UNUSED(op)) +static int snap_curs_to_center_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); @@ -1144,7 +1144,7 @@ void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot) ot->idname = "VIEW3D_OT_snap_cursor_to_center"; /* api callbacks */ - ot->exec = snap_curs_to_center; + ot->exec = snap_curs_to_center_exec; ot->poll = ED_operator_view3d_active; /* flags */ diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c index ebb9a7b8c81..bdb203ab003 100644 --- a/source/blender/editors/space_view3d/view3d_toolbar.c +++ b/source/blender/editors/space_view3d/view3d_toolbar.c @@ -195,7 +195,7 @@ static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase) uiBlockSetDirection(block, UI_DOWN); uiEndBlock(C, block); - event = *(win->eventstate); /* XXX huh huh? make api call */ + wm_event_init_from_window(win, &event); event.type = EVT_BUT_OPEN; event.val = KM_PRESS; event.customdata = but; @@ -258,7 +258,7 @@ void view3d_tool_props_register(ARegionType *art) /* ********** operator to open/close toolshelf region */ -static int view3d_toolshelf(bContext *C, wmOperator *UNUSED(op)) +static int view3d_toolshelf_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = view3d_has_tools_region(sa); @@ -275,7 +275,7 @@ void VIEW3D_OT_toolshelf(wmOperatorType *ot) ot->description = "Toggles tool shelf display"; ot->idname = "VIEW3D_OT_toolshelf"; - ot->exec = view3d_toolshelf; + ot->exec = view3d_toolshelf_toggle_exec; ot->poll = ED_operator_view3d_active; /* flags */ diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 3638690a0a5..44c338d22b9 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -202,7 +202,7 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera } /* skip smooth viewing for render engine draw */ - if (C && U.smooth_viewtx && v3d->drawtype != OB_RENDER) { + if (U.smooth_viewtx && v3d->drawtype != OB_RENDER) { bool changed = false; /* zero means no difference */ if (oldcamera != camera) @@ -444,14 +444,27 @@ void VIEW3D_OT_camera_to_view(wmOperatorType *ot) /* unlike VIEW3D_OT_view_selected this is for framing a render and not * meant to take into account vertex/bone selection for eg. */ -static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *UNUSED(op)) +static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - View3D *v3d = CTX_wm_view3d(C); - Object *camera_ob = v3d->camera; + View3D *v3d = CTX_wm_view3d(C); /* can be NULL */ + Object *camera_ob = v3d ? v3d->camera : scene->camera; float r_co[3]; /* the new location to apply */ + if (camera_ob == NULL) { + BKE_report(op->reports, RPT_ERROR, "No active camera"); + return OPERATOR_CANCELLED; + } + else if (camera_ob->type != OB_CAMERA) { + BKE_report(op->reports, RPT_ERROR, "Object not a camera"); + return OPERATOR_CANCELLED; + } + else if (((Camera *)camera_ob->data)->type == R_ORTHO) { + BKE_report(op->reports, RPT_ERROR, "Orthographic cameras not supported"); + return OPERATOR_CANCELLED; + } + /* this function does all the important stuff */ if (BKE_camera_view_frame_fit_to_scene(scene, v3d, camera_ob, r_co)) { @@ -476,24 +489,6 @@ static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *UNUSED(o } } -static int view3d_camera_to_view_selected_poll(bContext *C) -{ - View3D *v3d = CTX_wm_view3d(C); - if (v3d && v3d->camera && v3d->camera->id.lib == NULL) { - RegionView3D *rv3d = CTX_wm_region_view3d(C); - if (rv3d) { - if (rv3d->is_persp == false) { - CTX_wm_operator_poll_msg_set(C, "Only valid for a perspective camera view"); - } - else if (!rv3d->viewlock) { - return 1; - } - } - } - - return 0; -} - void VIEW3D_OT_camera_to_view_selected(wmOperatorType *ot) { /* identifiers */ @@ -503,7 +498,7 @@ void VIEW3D_OT_camera_to_view_selected(wmOperatorType *ot) /* api callbacks */ ot->exec = view3d_camera_to_view_selected_exec; - ot->poll = view3d_camera_to_view_selected_poll; + ot->poll = ED_operator_scene_editable; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -753,7 +748,7 @@ void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect) glGetFloatv(GL_PROJECTION_MATRIX, (float *)rv3d->winmat); } -static void obmat_to_viewmat(View3D *v3d, RegionView3D *rv3d, Object *ob, short smooth) +static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob) { float bmat[4][4]; float tmat[3][3]; @@ -766,36 +761,7 @@ static void obmat_to_viewmat(View3D *v3d, RegionView3D *rv3d, Object *ob, short /* view quat calculation, needed for add object */ copy_m3_m4(tmat, rv3d->viewmat); - if (smooth) { - float new_quat[4]; - if (rv3d->persp == RV3D_CAMOB && v3d->camera) { - /* were from a camera view */ - - float orig_ofs[3]; - float orig_dist = rv3d->dist; - float orig_lens = v3d->lens; - copy_v3_v3(orig_ofs, rv3d->ofs); - - /* Switch from camera view */ - mat3_to_quat(new_quat, tmat); - - rv3d->persp = RV3D_PERSP; - rv3d->dist = 0.0; - - ED_view3d_from_object(v3d->camera, rv3d->ofs, NULL, NULL, &v3d->lens); - view3d_smooth_view(NULL, NULL, NULL, NULL, NULL, orig_ofs, new_quat, &orig_dist, &orig_lens); /* XXX */ - - rv3d->persp = RV3D_CAMOB; /* just to be polite, not needed */ - - } - else { - mat3_to_quat(new_quat, tmat); - view3d_smooth_view(NULL, NULL, NULL, NULL, NULL, NULL, new_quat, NULL, NULL); /* XXX */ - } - } - else { - mat3_to_quat(rv3d->viewquat, tmat); - } + mat3_to_quat(rv3d->viewquat, tmat); } #define QUATSET(a, b, c, d, e) { a[0] = b; a[1] = c; a[2] = d; a[3] = e; } (void)0 @@ -839,7 +805,7 @@ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d) if (rv3d->persp == RV3D_CAMOB) { /* obs/camera */ if (v3d->camera) { BKE_object_where_is_calc(scene, v3d->camera); - obmat_to_viewmat(v3d, rv3d, v3d->camera, 0); + obmat_to_viewmat(rv3d, v3d->camera); } else { quat_to_mat4(rv3d->viewmat, rv3d->viewquat); @@ -1562,40 +1528,6 @@ void VIEW3D_OT_game_start(wmOperatorType *ot) /* ************************************** */ -static void UNUSED_FUNCTION(view3d_align_axis_to_vector)(View3D *v3d, RegionView3D *rv3d, int axisidx, float vec[3]) -{ - float alignaxis[3] = {0.0, 0.0, 0.0}; - float norm[3], axis[3], angle, new_quat[4]; - - if (axisidx > 0) alignaxis[axisidx - 1] = 1.0; - else alignaxis[-axisidx - 1] = -1.0; - - normalize_v3_v3(norm, vec); - - angle = (float)acos(dot_v3v3(alignaxis, norm)); - cross_v3_v3v3(axis, alignaxis, norm); - axis_angle_to_quat(new_quat, axis, -angle); - - rv3d->view = RV3D_VIEW_USER; - - if (rv3d->persp == RV3D_CAMOB && v3d->camera) { - /* switch out of camera view */ - float orig_ofs[3]; - float orig_dist = rv3d->dist; - float orig_lens = v3d->lens; - - copy_v3_v3(orig_ofs, rv3d->ofs); - rv3d->persp = RV3D_PERSP; - rv3d->dist = 0.0; - ED_view3d_from_object(v3d->camera, rv3d->ofs, NULL, NULL, &v3d->lens); - view3d_smooth_view(NULL, NULL, NULL, NULL, NULL, orig_ofs, new_quat, &orig_dist, &orig_lens); /* XXX */ - } - else { - if (rv3d->persp == RV3D_CAMOB) rv3d->persp = RV3D_PERSP; /* switch out of camera mode */ - view3d_smooth_view(NULL, NULL, NULL, NULL, NULL, NULL, new_quat, NULL, NULL); /* XXX */ - } -} - float ED_view3d_pixel_size(RegionView3D *rv3d, const float co[3]) { return mul_project_m4_v3_zfac(rv3d->persmat, co) * rv3d->pixsize * U.pixelsize; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index a565213f031..d5a9d0f9f93 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -61,7 +61,6 @@ #include "BLI_linklist.h" #include "BKE_nla.h" -#include "BKE_bmesh.h" #include "BKE_editmesh_bvh.h" #include "BKE_context.h" #include "BKE_constraint.h" @@ -111,9 +110,7 @@ static bool transdata_check_local_center(TransInfo *t) { return ((t->around == V3D_LOCAL) && ( (t->flag & (T_OBJECT | T_POSE)) || - (t->obedit && t->obedit->type == OB_MESH && (t->settings->selectmode & (SCE_SELECT_EDGE | SCE_SELECT_FACE))) || - (t->obedit && t->obedit->type == OB_MBALL) || - (t->obedit && t->obedit->type == OB_ARMATURE) || + (t->obedit && ELEM4(t->obedit->type, OB_MESH, OB_CURVE, OB_MBALL, OB_ARMATURE)) || (t->spacetype == SPACE_IPO)) ); } @@ -1327,12 +1324,6 @@ int transformEvent(TransInfo *t, const wmEvent *event) t->redraw |= TREDRAW_HARD; } break; -// case LEFTMOUSE: -// case RIGHTMOUSE: -// if (WM_modal_tweak_exit(event, t->event_type)) -//// if (t->options & CTX_TWEAK) -// t->state = TRANS_CONFIRM; -// break; case LEFTALTKEY: case RIGHTALTKEY: if (ELEM(t->spacetype, SPACE_SEQ, SPACE_VIEW3D)) { @@ -1377,7 +1368,7 @@ int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], int c t->state = TRANS_RUNNING; /* avoid calculating PET */ - t->options = CTX_NONE | CTX_NO_PET; + t->options = CTX_NO_PET; t->mode = TFM_DUMMY; @@ -5709,7 +5700,7 @@ int handleEventEdgeSlide(struct TransInfo *t, const struct wmEvent *event) return 0; } -void drawEdgeSlide(const struct bContext *C, TransInfo *t) +static void drawEdgeSlide(const struct bContext *C, TransInfo *t) { if (t->mode == TFM_EDGE_SLIDE) { EdgeSlideData *sld = (EdgeSlideData *)t->customData; @@ -5883,14 +5874,8 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2])) t->values[0] = final; - /*do stuff here*/ - if (t->customData) { - doEdgeSlide(t, final); - } - else { - BLI_strncpy(str, IFACE_("Invalid Edge Selection"), MAX_INFO_LEN); - t->state = TRANS_CANCEL; - } + /* do stuff here */ + doEdgeSlide(t, final); recalcData(t); @@ -6397,14 +6382,8 @@ int VertSlide(TransInfo *t, const int UNUSED(mval[2])) ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Alt or (C)lamp: %s"), is_clamp ? on_str : off_str); /* done with header string */ - /*do stuff here*/ - if (t->customData) { - doVertSlide(t, final); - } - else { - BLI_strncpy(str, IFACE_("Invalid Vert Selection"), MAX_INFO_LEN); - t->state = TRANS_CANCEL; - } + /* do stuff here */ + doVertSlide(t, final); recalcData(t); @@ -7358,7 +7337,7 @@ bool checkUseAxisMatrix(TransInfo *t) { /* currenly only checks for editmode */ if (t->flag & T_EDIT) { - if ((t->around == V3D_LOCAL) && (ELEM3(t->obedit->type, OB_MESH, OB_MBALL, OB_ARMATURE))) { + if ((t->around == V3D_LOCAL) && (ELEM4(t->obedit->type, OB_MESH, OB_CURVE, OB_MBALL, OB_ARMATURE))) { /* not all editmode supports axis-matrix */ return true; } diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 911d4b0a623..4a1c4203a43 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -725,7 +725,7 @@ void initTransformOrientation(struct bContext *C, TransInfo *t); /* Those two fill in mat and return non-zero on success */ bool createSpaceNormal(float mat[3][3], const float normal[3]); -bool createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]); +bool createSpaceNormalTangent(float mat[3][3], const float normal[3], const float tangent[3]); struct TransformOrientation *addMatrixSpace(struct bContext *C, float mat[3][3], char name[], int overwrite); void applyTransformOrientation(const struct bContext *C, float mat[3][3], char *name); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 93e01d84eaf..95ec20a0c2b 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -59,14 +59,12 @@ #include "BLI_math.h" #include "BLI_blenlib.h" -#include "BLI_array.h" #include "BLI_utildefines.h" #include "BLI_smallhash.h" #include "BKE_DerivedMesh.h" #include "BKE_action.h" #include "BKE_armature.h" -#include "BKE_bmesh.h" #include "BKE_constraint.h" #include "BKE_context.h" #include "BKE_curve.h" @@ -124,6 +122,11 @@ #include "BLI_sys_types.h" // for intptr_t support +/* when transforming islands */ +struct TransIslandData { + float co[3]; + float axismtx[3][3]; +}; /* local function prototype - for Object/Bone Constraints */ static bool constraints_list_needinv(TransInfo *t, ListBase *list); @@ -1043,7 +1046,7 @@ static void createTransArmatureVerts(TransInfo *t) bArmature *arm = t->obedit->data; ListBase *edbo = arm->edbo; TransData *td; - float mtx[3][3], smtx[3][3], delta[3], bonemat[3][3]; + float mtx[3][3], smtx[3][3], bonemat[3][3]; /* special hack for envelope drawmode and scaling: * to allow scaling the size of the envelope around single points, @@ -1135,8 +1138,7 @@ static void createTransArmatureVerts(TransInfo *t) td->flag = TD_SELECTED; /* use local bone matrix */ - sub_v3_v3v3(delta, ebo->tail, ebo->head); - vec_roll_to_mat3(delta, ebo->roll, bonemat); + ED_armature_ebone_to_mat3(ebo, bonemat); mul_m3_m3m3(td->mtx, mtx, bonemat); invert_m3_m3(td->smtx, td->mtx); @@ -1176,8 +1178,7 @@ static void createTransArmatureVerts(TransInfo *t) copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); - sub_v3_v3v3(delta, ebo->tail, ebo->head); - vec_roll_to_mat3(delta, ebo->roll, td->axismtx); + ED_armature_ebone_to_mat3(ebo, td->axismtx); if ((ebo->flag & BONE_ROOTSEL) == 0) { td->extra = ebo; @@ -1200,8 +1201,7 @@ static void createTransArmatureVerts(TransInfo *t) copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); - sub_v3_v3v3(delta, ebo->tail, ebo->head); - vec_roll_to_mat3(delta, ebo->roll, td->axismtx); + ED_armature_ebone_to_mat3(ebo, td->axismtx); td->extra = ebo; /* to fix roll */ @@ -1413,6 +1413,23 @@ static void createTransCurveVerts(TransInfo *t) for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) { if (bezt->hide == 0) { TransDataCurveHandleFlags *hdata = NULL; + float axismtx[3][3]; + + if (t->around == V3D_LOCAL) { + float normal[3], plane[3]; + + BKE_nurb_bezt_calc_normal(nu, bezt, normal); + BKE_nurb_bezt_calc_plane(nu, bezt, plane); + + if (createSpaceNormalTangent(axismtx, normal, plane)) { + /* pass */ + } + else { + normalize_v3(normal); + axis_dominant_v3_to_m3(axismtx, normal); + invert_m3(axismtx); + } + } if (propmode || ((bezt->f2 & SELECT) && hide_handles) || @@ -1436,6 +1453,9 @@ static void createTransCurveVerts(TransInfo *t) copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); + if (t->around == V3D_LOCAL) { + copy_m3_m3(td->axismtx, axismtx); + } td++; count++; @@ -1465,6 +1485,9 @@ static void createTransCurveVerts(TransInfo *t) copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); + if (t->around == V3D_LOCAL) { + copy_m3_m3(td->axismtx, axismtx); + } if ((bezt->f1 & SELECT) == 0 && (bezt->f3 & SELECT) == 0) /* If the middle is selected but the sides arnt, this is needed */ @@ -1500,6 +1523,9 @@ static void createTransCurveVerts(TransInfo *t) copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); + if (t->around == V3D_LOCAL) { + copy_m3_m3(td->axismtx, axismtx); + } td++; count++; @@ -1914,34 +1940,124 @@ static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float MEM_freeN(dists_prev); } -static BMElem *bm_vert_single_select_face(BMVert *eve) +static struct TransIslandData *editmesh_islands_info_calc(BMEditMesh *em, int *r_island_tot, int **r_island_vert_map) { - BMElem *ele; - BMIter iter; + BMesh *bm = em->bm; + struct TransIslandData *trans_islands; + char htype; + char itype; + int i; + + /* group vars */ + int *groups_array; + int (*group_index)[2]; + int group_tot; + void **ele_array; + + int *vert_map; + + if (em->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) { + groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totedgesel, __func__); + group_tot = BM_mesh_calc_edge_groups(bm, groups_array, &group_index, + NULL, NULL, + BM_ELEM_SELECT); + + htype = BM_EDGE; + itype = BM_VERTS_OF_EDGE; - BM_ITER_ELEM (ele, &iter, eve, BM_FACES_OF_VERT) { - if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) { - return ele; - } } - return NULL; -} -static BMElem *bm_vert_single_select_edge(BMVert *eve) -{ - BMElem *ele; - BMIter iter; + else { /* (bm->selectmode & SCE_SELECT_FACE) */ + groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totfacesel, __func__); + group_tot = BM_mesh_calc_face_groups(bm, groups_array, &group_index, + NULL, NULL, + BM_ELEM_SELECT, BM_VERT); + + htype = BM_FACE; + itype = BM_VERTS_OF_FACE; + } + + + trans_islands = MEM_mallocN(sizeof(*trans_islands) * group_tot, __func__); + + vert_map = MEM_mallocN(sizeof(*vert_map) * bm->totvert, __func__); + /* we shouldn't need this, but with incorrect selection flushing + * its possible we have a selected vertex thats not in a face, for now best not crash in that case. */ + fill_vn_i(vert_map, bm->totvert, -1); + + EDBM_index_arrays_ensure(em, htype); + ele_array = (htype == BM_FACE) ? (void **)em->face_index : (void **)em->edge_index; + + BM_mesh_elem_index_ensure(bm, BM_VERT); + + /* may be an edge OR a face array */ + for (i = 0; i < group_tot; i++) { + BMEditSelection ese = {NULL}; + + const int fg_sta = group_index[i][0]; + const int fg_len = group_index[i][1]; + float co[3], no[3], tangent[3]; + int j; + + zero_v3(co); + zero_v3(no); + zero_v3(tangent); - BM_ITER_ELEM (ele, &iter, eve, BM_EDGES_OF_VERT) { - if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) { - return ele; + ese.htype = htype; + + /* loop on each face in this group: + * - assign r_vert_map + * - calculate (co, no) + */ + for (j = 0; j < fg_len; j++) { + float tmp_co[3], tmp_no[3], tmp_tangent[3]; + + ese.ele = ele_array[groups_array[fg_sta + j]]; + + BM_editselection_center(&ese, tmp_co); + BM_editselection_normal(&ese, tmp_no); + BM_editselection_plane(&ese, tmp_tangent); + + add_v3_v3(co, tmp_co); + add_v3_v3(no, tmp_no); + add_v3_v3(tangent, tmp_tangent); + + { + /* setup vertex map */ + BMIter iter; + BMVert *v; + + /* connected edge-verts */ + BM_ITER_ELEM (v, &iter, ese.ele, itype) { + vert_map[BM_elem_index_get(v)] = i; + } + } + } + + mul_v3_v3fl(trans_islands[i].co, co, 1.0f / (float)fg_len); + + if (createSpaceNormalTangent(trans_islands[i].axismtx, no, tangent)) { + /* pass */ + } + else { + normalize_v3(no); + axis_dominant_v3_to_m3(trans_islands[i].axismtx, no); + invert_m3(trans_islands[i].axismtx); } } - return NULL; + + MEM_freeN(groups_array); + MEM_freeN(group_index); + + *r_island_tot = group_tot; + *r_island_vert_map = vert_map; + + return trans_islands; } /* way to overwrite what data is edited with transform */ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx, - BMEditMesh *em, BMVert *eve, float *bweight) + BMEditMesh *em, BMVert *eve, float *bweight, + struct TransIslandData *v_island) { BLI_assert(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) == 0); @@ -1951,40 +2067,20 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx //else td->loc = eve->co; copy_v3_v3(td->iloc, td->loc); - copy_v3_v3(td->center, td->loc); - - if (t->around == V3D_LOCAL) { - BMElem *ele; - bool is_axismat_set = false; - if (em->selectmode & (SCE_SELECT_FACE | SCE_SELECT_EDGE) && - (ele = ((em->selectmode & SCE_SELECT_FACE) ? - bm_vert_single_select_face(eve) : - bm_vert_single_select_edge(eve)))) - { - float normal[3], tangent[3]; - - BMEditSelection ese; - ese.next = ese.prev = NULL; - ese.ele = ele; - ese.htype = ele->head.htype; - - BM_editselection_center(&ese, td->center); - BM_editselection_normal(&ese, normal); - BM_editselection_plane(&ese, tangent); - - if (createSpaceNormalTangent(td->axismtx, normal, tangent)) { - is_axismat_set = true; - } - } + if (v_island) { + copy_v3_v3(td->center, v_island->co); + copy_m3_m3(td->axismtx, v_island->axismtx); + } + else if (t->around == V3D_LOCAL) { + copy_v3_v3(td->center, td->loc); - /* for verts or fallback when createSpaceNormalTangent fails */ - if (is_axismat_set == false) { - axis_dominant_v3_to_m3(td->axismtx, eve->no); - invert_m3(td->axismtx); - } + axis_dominant_v3_to_m3(td->axismtx, eve->no); + invert_m3(td->axismtx); } else { + copy_v3_v3(td->center, td->loc); + /* Setting normals */ copy_v3_v3(td->axismtx[2], eve->no); td->axismtx[0][0] = @@ -2021,7 +2117,6 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx static void createTransEditVerts(TransInfo *t) { - ToolSettings *ts = t->scene->toolsettings; TransData *tob = NULL; TransDataExtension *tx = NULL; BMEditMesh *em = BKE_editmesh_from_object(t->obedit); @@ -2033,15 +2128,15 @@ static void createTransEditVerts(TransInfo *t) float *mappedcos = NULL, *quats = NULL; float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL; float *dists = NULL; - int count = 0, countsel = 0, a, totleft; + int a; int propmode = (t->flag & T_PROP_EDIT) ? (t->flag & T_PROP_EDIT_ALL) : 0; int mirror = 0; - short selectmode = ts->selectmode; int cd_vert_bweight_offset = -1; bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0; - /* BMESH_TODO, writing into the index values is BAD!, means we cant - * use the values for vertex mirror - campbell */ + struct TransIslandData *island_info = NULL; + int island_info_tot; + int *island_vert_map = NULL; if (t->flag & T_MIRROR) { EDBM_verts_mirror_cache_begin(em, 0, false, (t->flag & T_PROP_EDIT) == 0, use_topology); @@ -2050,17 +2145,17 @@ static void createTransEditVerts(TransInfo *t) /* quick check if we can transform */ /* note: in prop mode we need at least 1 selected */ - if (selectmode & SCE_SELECT_VERTEX) { + if (em->selectmode & SCE_SELECT_VERTEX) { if (bm->totvertsel == 0) { goto cleanup; } } - else if (selectmode & SCE_SELECT_EDGE) { + else if (em->selectmode & SCE_SELECT_EDGE) { if (bm->totvertsel == 0 || bm->totedgesel == 0) { goto cleanup; } } - else if (selectmode & SCE_SELECT_FACE) { + else if (em->selectmode & SCE_SELECT_FACE) { if (bm->totvertsel == 0 || bm->totfacesel == 0) { goto cleanup; } @@ -2069,10 +2164,6 @@ static void createTransEditVerts(TransInfo *t) BLI_assert(0); } - countsel = bm->totvertsel; - if (propmode) { - count = bm->totvert; - } /* check active */ eve_act = BM_mesh_active_vert_get(bm); @@ -2083,6 +2174,13 @@ static void createTransEditVerts(TransInfo *t) } if (propmode) { + unsigned int count = 0; + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { + count++; + } + } + t->total = count; /* allocating scratch arrays */ @@ -2090,7 +2188,7 @@ static void createTransEditVerts(TransInfo *t) dists = MEM_mallocN(em->bm->totvert * sizeof(float), "scratch nears"); } else { - t->total = countsel; + t->total = bm->totvertsel; } tob = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Mesh EditMode)"); @@ -2112,9 +2210,17 @@ static void createTransEditVerts(TransInfo *t) editmesh_set_connectivity_distance(em->bm, mtx, dists); } + if (t->around == V3D_LOCAL) { + island_info = editmesh_islands_info_calc(em, &island_info_tot, &island_vert_map); + } + + /* BMESH_TODO, crazy-space writing into the index values is BAD!, means we cant + * use the values for vertex mirror - campbell */ + /* detect CrazySpace [tm] */ if (modifiers_getCageIndex(t->scene, t->obedit, NULL, 1) >= 0) { if (modifiers_isCorrectableDeformed(t->obedit)) { + int totleft; /* check if we can use deform matrices for modifier from the * start up to stack, they are more accurate than quats */ totleft = editbmesh_get_first_deform_matrices(t->scene, t->obedit, em, &defmats, &defcos); @@ -2151,9 +2257,11 @@ static void createTransEditVerts(TransInfo *t) BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) { if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { if (propmode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + struct TransIslandData *v_island = (island_info && island_vert_map[a] != -1) ? + &island_info[island_vert_map[a]] : NULL; float *bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset) : NULL; - - VertsToTransData(t, tob, tx, em, eve, bweight); + + VertsToTransData(t, tob, tx, em, eve, bweight, v_island); if (tx) tx++; @@ -2213,6 +2321,11 @@ static void createTransEditVerts(TransInfo *t) } } + if (island_info) { + MEM_freeN(island_info); + MEM_freeN(island_vert_map); + } + if (mirror != 0) { tob = t->data; for (a = 0; a < t->total; a++, tob++) { @@ -2233,7 +2346,6 @@ cleanup: if (t->flag & T_MIRROR) { EDBM_verts_mirror_cache_end(em); - mirror = 1; } } @@ -6309,7 +6421,7 @@ void flushTransTracking(TransInfo *t) } } - if (tdt->area != TRACK_AREA_POINT || tdt->relative == 0) { + if (tdt->area != TRACK_AREA_POINT || tdt->relative == NULL) { td2d->loc2d[0] = loc2d[0]; td2d->loc2d[1] = loc2d[1]; @@ -6556,10 +6668,6 @@ void createTransData(bContext *C, TransInfo *t) sort_trans_data_dist(t); } } - else if (t->options == CTX_BMESH) { - // TRANSFORM_FIX_ME - //createTransBMeshVerts(t, G.editBMesh->bm, G.editBMesh->td); - } else if (t->spacetype == SPACE_IMAGE) { t->flag |= T_POINTS | T_2D_EDIT; if (t->options & CTX_MASK) { diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 2be4a072d49..55d80d63234 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -166,6 +166,26 @@ static TransformOrientation *createBoneSpace(bContext *C, ReportList *reports, c return addMatrixSpace(C, mat, name, overwrite); } +static TransformOrientation *createCurveSpace(bContext *C, ReportList *reports, char *name, int overwrite) +{ + float mat[3][3]; + float normal[3], plane[3]; + + getTransformOrientation(C, normal, plane, 0); + + if (createSpaceNormalTangent(mat, normal, plane) == 0) { + BKE_reports_prepend(reports, "Cannot use zero-length curve"); + return NULL; + } + + if (name[0] == 0) { + strcpy(name, "Curve"); + } + + return addMatrixSpace(C, mat, name, overwrite); +} + + static TransformOrientation *createMeshSpace(bContext *C, ReportList *reports, char *name, int overwrite) { float mat[3][3]; @@ -236,26 +256,34 @@ bool createSpaceNormal(float mat[3][3], const float normal[3]) return true; } -bool createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]) +/** + * \note To recreate an orientation from the matrix: + * - (plane == mat[1]) + * - (normal == mat[2]) + */ +bool createSpaceNormalTangent(float mat[3][3], const float normal[3], const float tangent[3]) { - copy_v3_v3(mat[2], normal); - if (normalize_v3(mat[2]) == 0.0f) { + if (normalize_v3_v3(mat[2], normal) == 0.0f) { return false; /* error return */ } - + + /* negate so we can use values from the matrix as input */ + negate_v3_v3(mat[1], tangent); /* preempt zero length tangent from causing trouble */ - if (tangent[0] == 0 && tangent[1] == 0 && tangent[2] == 0) { - tangent[2] = 1; + if (is_zero_v3(mat[1])) { + mat[1][2] = 1.0f; } - cross_v3_v3v3(mat[0], mat[2], tangent); + cross_v3_v3v3(mat[0], mat[2], mat[1]); if (normalize_v3(mat[0]) == 0.0f) { return false; /* error return */ } cross_v3_v3v3(mat[1], mat[2], mat[0]); + normalize_v3(mat[1]); - normalize_m3(mat); + /* final matrix must be normalized, do inline */ + // normalize_m3(mat); return true; } @@ -276,6 +304,8 @@ void BIF_createTransformOrientation(bContext *C, ReportList *reports, char *name ts = createMeshSpace(C, reports, name, overwrite); else if (obedit->type == OB_ARMATURE) ts = createBoneSpace(C, reports, name, overwrite); + else if (obedit->type == OB_CURVE) + ts = createCurveSpace(C, reports, name, overwrite); } else if (ob && (ob->mode & OB_MODE_POSE)) { ts = createBoneSpace(C, reports, name, overwrite); @@ -667,6 +697,10 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], result = ORIENTATION_VERT; } } + + /* not needed but this matches 2.68 and older behavior */ + negate_v3(plane); + } /* end editmesh */ else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { Curve *cu = obedit->data; @@ -675,34 +709,67 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], int a; ListBase *nurbs = BKE_curve_editNurbs_get(cu); - for (nu = nurbs->first; nu; nu = nu->next) { - /* only bezier has a normal */ - if (nu->type == CU_BEZIER) { - bezt = nu->bezt; - a = nu->pntsu; - while (a--) { - /* exception */ - if ((bezt->f1 & SELECT) + (bezt->f2 & SELECT) + (bezt->f3 & SELECT) > SELECT) { - sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[2]); + if (activeOnly && cu->lastsel) { + for (nu = nurbs->first; nu; nu = nu->next) { + if (nu->type == CU_BEZIER) { + if (ARRAY_HAS_ITEM((BezTriple *)cu->lastsel, nu->bezt, nu->pntsu)) { + bezt = cu->lastsel; + BKE_nurb_bezt_calc_normal(nu, bezt, normal); + BKE_nurb_bezt_calc_plane(nu, bezt, plane); + break; } - else { - if (bezt->f1) { - sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[1]); - } - if (bezt->f2) { - sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[2]); - } - if (bezt->f3) { - sub_v3_v3v3(normal, bezt->vec[1], bezt->vec[2]); + } + else { + if (ARRAY_HAS_ITEM((BPoint *)cu->lastsel, nu->bp, nu->pntsu)) { + /* do nothing */ + break; + } + } + } + } + else { + for (nu = nurbs->first; nu; nu = nu->next) { + /* only bezier has a normal */ + if (nu->type == CU_BEZIER) { + bezt = nu->bezt; + a = nu->pntsu; + while (a--) { + /* exception */ + if ((bezt->f1 | bezt->f2 | bezt->f3) & SELECT) { + float tvec[3]; + if ((bezt->f1 & SELECT) + (bezt->f2 & SELECT) + (bezt->f3 & SELECT) > SELECT) { + BKE_nurb_bezt_calc_normal(nu, bezt, tvec); + add_v3_v3(normal, tvec); + } + else { + if (bezt->f1 & SELECT) { + sub_v3_v3v3(tvec, bezt->vec[0], bezt->vec[1]); + normalize_v3(tvec); + add_v3_v3(normal, tvec); + } + if (bezt->f2 & SELECT) { + sub_v3_v3v3(tvec, bezt->vec[0], bezt->vec[2]); + normalize_v3(tvec); + add_v3_v3(normal, tvec); + } + if (bezt->f3 & SELECT) { + sub_v3_v3v3(tvec, bezt->vec[1], bezt->vec[2]); + normalize_v3(tvec); + add_v3_v3(normal, tvec); + } + } + + BKE_nurb_bezt_calc_plane(nu, bezt, tvec); + add_v3_v3(plane, tvec); } + bezt++; } - bezt++; } } } if (!is_zero_v3(normal)) { - result = ORIENTATION_NORMAL; + result = ORIENTATION_FACE; } } else if (obedit->type == OB_MBALL) { @@ -716,7 +783,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], copy_v3_v3(normal, qmat[2]); - negate_v3_v3(plane, qmat[1]); + copy_v3_v3(plane, qmat[1]); result = ORIENTATION_FACE; } @@ -724,45 +791,33 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], else if (obedit->type == OB_ARMATURE) { bArmature *arm = obedit->data; EditBone *ebone; - int ok = FALSE; - - /* grr. but better then duplicate code */ -#define EBONE_CALC_NORMAL_PLANE { \ - float tmat[3][3]; \ - float vec[3]; \ - sub_v3_v3v3(vec, ebone->tail, ebone->head); \ - normalize_v3(vec); \ - add_v3_v3(normal, vec); \ - \ - vec_roll_to_mat3(vec, ebone->roll, tmat); \ - add_v3_v3(plane, tmat[2]); \ - } (void)0 - + bool ok = false; + float tmat[3][3]; if (activeOnly && (ebone = arm->act_edbone)) { - EBONE_CALC_NORMAL_PLANE; - ok = TRUE; + ED_armature_ebone_to_mat3(ebone, tmat); + add_v3_v3(normal, tmat[2]); + add_v3_v3(plane, tmat[1]); + ok = true; } else { for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { if (arm->layer & ebone->layer) { if (ebone->flag & BONE_SELECTED) { - EBONE_CALC_NORMAL_PLANE; - ok = TRUE; + ED_armature_ebone_to_mat3(ebone, tmat); + add_v3_v3(normal, tmat[2]); + add_v3_v3(plane, tmat[1]); + ok = true; } } } } if (ok) { - normalize_v3(normal); - normalize_v3(plane); - if (!is_zero_v3(plane)) { result = ORIENTATION_EDGE; } } -#undef EBONE_CALC_NORMAL_PLANE } /* Vectors from edges don't need the special transpose inverse multiplication */ @@ -804,8 +859,6 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], /* use for both active & all */ if (ok) { - negate_v3(plane); - /* we need the transpose of the inverse for a normal... */ copy_m3_m4(imat, ob->obmat); @@ -823,11 +876,14 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], else { /* we need the one selected object, if its not active */ ob = OBACT; - if (ob && !(ob->flag & SELECT)) ob = NULL; - - for (base = scene->base.first; base; base = base->next) { - if (TESTBASELIB(v3d, base)) { - if (ob == NULL) { + if (ob && (ob->flag & SELECT)) { + /* pass */ + } + else { + /* first selected */ + ob = NULL; + for (base = scene->base.first; base; base = base->next) { + if (TESTBASELIB(v3d, base)) { ob = base->object; break; } diff --git a/source/blender/editors/util/crazyspace.c b/source/blender/editors/util/crazyspace.c index ea3687ad715..bed8aaaddf2 100644 --- a/source/blender/editors/util/crazyspace.c +++ b/source/blender/editors/util/crazyspace.c @@ -40,6 +40,7 @@ #include "BLI_utildefines.h" #include "BLI_math.h" +#include "BLI_bitmap.h" #include "BKE_DerivedMesh.h" #include "BKE_modifier.h" @@ -51,7 +52,7 @@ typedef struct { float *vertexcos; - short *flags; + BLI_bitmap *vertex_visit; } MappedUserData; #define TAN_MAKE_VEC(a, b, c) a[0] = b[0] + 0.2f * (b[0] - c[0]); a[1] = b[1] + 0.2f * (b[1] - c[1]); a[2] = b[2] + 0.2f * (b[2] - c[2]) @@ -79,11 +80,11 @@ static void make_vertexcos__mapFunc(void *userData, int index, const float co[3] float *vec = mappedData->vertexcos; vec += 3 * index; - if (!mappedData->flags[index]) { + if (BLI_BITMAP_GET(mappedData->vertex_visit, index) == 0) { /* we need coord from prototype vertex, not it clones or images, * suppose they stored in the beginning of vertex array stored in DM */ copy_v3_v3(vec, co); - mappedData->flags[index] = 1; + BLI_BITMAP_SET(mappedData->vertex_visit, index); } } @@ -109,7 +110,7 @@ float *crazyspace_get_mapped_editverts(Scene *scene, Object *obedit) DerivedMesh *dm; float *vertexcos; int nverts = me->edit_btmesh->bm->totvert; - short *flags; + BLI_bitmap *vertex_visit; MappedUserData userData; /* disable subsurf temporal, get mapped cos, and enable it */ @@ -122,18 +123,18 @@ float *crazyspace_get_mapped_editverts(Scene *scene, Object *obedit) dm = editbmesh_get_derived_cage(scene, obedit, me->edit_btmesh, CD_MASK_BAREMESH); vertexcos = MEM_callocN(3 * sizeof(float) * nverts, "vertexcos map"); - flags = MEM_callocN(sizeof(short) * nverts, "vertexcos flags"); + vertex_visit = BLI_BITMAP_NEW(nverts, "vertexcos flags"); userData.vertexcos = vertexcos; - userData.flags = flags; - dm->foreachMappedVert(dm, make_vertexcos__mapFunc, &userData); + userData.vertex_visit = vertex_visit; + dm->foreachMappedVert(dm, make_vertexcos__mapFunc, &userData, DM_FOREACH_NOP); dm->release(dm); /* set back the flag, no new cage needs to be built, transform does it */ modifiers_disable_subsurf_temporary(obedit); - MEM_freeN(flags); + MEM_freeN(vertex_visit); return vertexcos; } @@ -278,7 +279,7 @@ int editbmesh_get_first_deform_matrices(Scene *scene, Object *ob, BMEditMesh *em if (!defmats) { dm = getEditDerivedBMesh(em, ob, NULL); deformedVerts = editbmesh_get_vertex_cos(em, &numVerts); - defmats = MEM_callocN(sizeof(*defmats) * numVerts, "defmats"); + defmats = MEM_mallocN(sizeof(*defmats) * numVerts, "defmats"); for (a = 0; a < numVerts; a++) unit_m3(defmats[a]); diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 438f6bbdb9c..a873702b5b8 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -49,7 +49,6 @@ #include "BKE_mesh.h" #include "BKE_editmesh.h" -#include "BLI_array.h" #include "BLI_buffer.h" #include "BIF_gl.h" @@ -66,6 +65,10 @@ #include "uvedit_intern.h" +/* use editmesh tessface */ +#define USE_EDBM_LOOPTRIS + + void draw_image_cursor(SpaceImage *sima, ARegion *ar) { float zoom[2], x_fac, y_fac; @@ -257,6 +260,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe weight_to_rgb(col, areadiff); glColor3fv(col); + /* TODO: USE_EDBM_LOOPTRIS */ glBegin(GL_POLYGON); BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); @@ -321,6 +325,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe ang[i] = angle_normalized_v3v3(av[i], av[(i + 1) % efa_len]); } + /* TODO: USE_EDBM_LOOPTRIS */ glBegin(GL_POLYGON); BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); @@ -421,6 +426,23 @@ static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, Object *ob) } } +#ifdef USE_EDBM_LOOPTRIS +static void draw_uvs_looptri(BMEditMesh *em, unsigned int *r_loop_index, const int cd_loop_uv_offset) +{ + unsigned int i = *r_loop_index; + BMFace *f = em->looptris[i][0]->f; + do { + unsigned int j; + for (j = 0; j < 3; j++) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(em->looptris[i][j], cd_loop_uv_offset); + glVertex2fv(luv->uv); + } + i++; + } while (i != em->tottri && (f == em->looptris[i][0]->f)); + *r_loop_index = i - 1; +} +#endif + /* draws uv's in the image space */ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) { @@ -428,7 +450,10 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) Mesh *me = obedit->data; BMEditMesh *em = me->edit_btmesh; BMesh *bm = em->bm; - BMFace *efa, *efa_act, *activef; + BMFace *efa, *efa_act; +#ifndef USE_EDBM_LOOPTRIS + BMFace *activef; +#endif BMLoop *l; BMIter iter, liter; MTexPoly *tf, *activetf = NULL; @@ -443,7 +468,9 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY); activetf = EDBM_mtexpoly_active_get(em, &efa_act, FALSE, FALSE); /* will be set to NULL if hidden */ +#ifndef USE_EDBM_LOOPTRIS activef = BM_mesh_active_face_get(bm, FALSE, FALSE); +#endif ts = scene->toolsettings; drawfaces = draw_uvs_face_check(scene); @@ -490,9 +517,42 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); +#ifdef USE_EDBM_LOOPTRIS + { + unsigned int i; + for (i = 0; i < em->tottri; i++) { + efa = em->looptris[i][0]->f; + tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); + if (uvedit_face_visible_test(scene, ima, efa, tf)) { + const bool is_select = uvedit_face_select_test(scene, efa, cd_loop_uv_offset); + BM_elem_flag_enable(efa, BM_ELEM_TAG); + + if (tf == activetf) { + /* only once */ + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); + UI_ThemeColor4(TH_EDITMESH_ACTIVE); + } + else { + glColor4ubv((GLubyte *)(is_select ? col2 : col1)); + } + + glBegin(GL_TRIANGLES); + draw_uvs_looptri(em, &i, cd_loop_uv_offset); + glEnd(); + + if (tf == activetf) { + glDisable(GL_POLYGON_STIPPLE); + } + } + else { + BM_elem_flag_disable(efa, BM_ELEM_TAG); + } + } + } +#else BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); - if (uvedit_face_visible_test(scene, ima, efa, tf)) { BM_elem_flag_enable(efa, BM_ELEM_TAG); if (tf == activetf) continue; /* important the temp boolean is set above */ @@ -515,6 +575,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) BM_elem_flag_disable(efa, BM_ELEM_TAG); } } +#endif glDisable(GL_BLEND); } else { @@ -536,7 +597,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) } /* 3. draw active face stippled */ - +#ifndef USE_EDBM_LOOPTRIS if (activef) { tf = BM_ELEM_CD_GET_VOID_P(activef, cd_poly_tex_offset); if (uvedit_face_visible_test(scene, ima, activef, tf)) { @@ -558,6 +619,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) glDisable(GL_BLEND); } } +#endif /* 4. draw edges */ diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 0f7caf126d3..0b514e3f6fd 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -46,11 +46,12 @@ #include "DNA_space_types.h" #include "DNA_scene_types.h" +#include "BLI_utildefines.h" +#include "BLI_alloca.h" #include "BLI_math.h" #include "BLI_lasso.h" #include "BLI_blenlib.h" #include "BLI_array.h" -#include "BLI_utildefines.h" #include "BKE_context.h" #include "BKE_customdata.h" diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index 18f4e8cafaf..7851eebe269 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -26,15 +26,13 @@ #include "MEM_guardedalloc.h" -#include "BLI_array.h" +#include "BLI_utildefines.h" +#include "BLI_alloca.h" #include "BLI_memarena.h" #include "BLI_math.h" #include "BLI_rand.h" #include "BLI_heap.h" #include "BLI_boxpack2d.h" -#include "BLI_utildefines.h" - - #include "ONL_opennl.h" diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index a100757980c..49505b03a19 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -44,6 +44,7 @@ #include "DNA_modifier_types.h" #include "BLI_utildefines.h" +#include "BLI_alloca.h" #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_uvproject.h" @@ -65,7 +66,6 @@ #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_scanfill.h" -#include "BLI_array.h" #include "BLI_uvproject.h" #include "PIL_time.h" @@ -362,7 +362,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B ModifierData *md; SubsurfModifierData *smd_real; /* modifier initialization data, will control what type of subdivision will happen*/ - SubsurfModifierData smd = {{0}}; + SubsurfModifierData smd = {{NULL}}; /* Used to hold subsurfed Mesh */ DerivedMesh *derivedMesh, *initialDerived; /* holds original indices for subsurfed mesh */ diff --git a/source/blender/freestyle/intern/application/AppView.h b/source/blender/freestyle/intern/application/AppView.h index ca250f89850..3f6d0b8e93e 100644 --- a/source/blender/freestyle/intern/application/AppView.h +++ b/source/blender/freestyle/intern/application/AppView.h @@ -234,7 +234,6 @@ protected: NodeDrawingStyle *_p2DSelectionNode; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:AppView") #endif }; diff --git a/source/blender/freestyle/intern/application/Controller.h b/source/blender/freestyle/intern/application/Controller.h index c8eaaf5486b..d4537f5f987 100644 --- a/source/blender/freestyle/intern/application/Controller.h +++ b/source/blender/freestyle/intern/application/Controller.h @@ -244,7 +244,6 @@ private: FEdgeXDetector edgeDetector; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Controller") #endif }; diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h index c505eab40f1..17c0dd0c6db 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h @@ -127,7 +127,6 @@ protected: RenderMonitor *_pRenderMonitor; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BlenderFileLoader") #endif }; diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h index ae0e6bed3b2..96ce8c1be7e 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h @@ -64,6 +64,11 @@ protected: float get_stroke_vertex_z(void) const; unsigned int get_stroke_mesh_id(void) const; + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BlenderStrokeRenderer") +#endif + }; } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h b/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h index 7419d49ba4d..8a16a2b5c2a 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h +++ b/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h @@ -58,6 +58,11 @@ protected: private: struct Text *_text; + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BlenderStyleModule") +#endif + }; } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.h b/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.h index 1484188851d..b6cb303942a 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.h +++ b/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.h @@ -43,6 +43,11 @@ protected: protected: virtual void loadStandardBrushes(); + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BlenderTextureManager") +#endif + }; } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/geometry/BBox.h b/source/blender/freestyle/intern/geometry/BBox.h index 04fe6118815..794ceba48e7 100644 --- a/source/blender/freestyle/intern/geometry/BBox.h +++ b/source/blender/freestyle/intern/geometry/BBox.h @@ -136,7 +136,6 @@ private: bool _empty; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BBox") #endif }; diff --git a/source/blender/freestyle/intern/geometry/FastGrid.h b/source/blender/freestyle/intern/geometry/FastGrid.h index 510a2b94225..e292589b7cf 100644 --- a/source/blender/freestyle/intern/geometry/FastGrid.h +++ b/source/blender/freestyle/intern/geometry/FastGrid.h @@ -76,6 +76,11 @@ public: protected: Cell **_cells; unsigned _cells_size; + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FastGrid") +#endif + }; } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/geometry/FitCurve.cpp b/source/blender/freestyle/intern/geometry/FitCurve.cpp index a5701ea05e5..e517bf4f196 100644 --- a/source/blender/freestyle/intern/geometry/FitCurve.cpp +++ b/source/blender/freestyle/intern/geometry/FitCurve.cpp @@ -478,7 +478,7 @@ FitCurveWrapper::~FitCurveWrapper() void FitCurveWrapper::DrawBezierCurve(int n, Vector2 *curve) { - for (int i = 0; i < n + 1; ++i) + for (int i = 0; i <= n; ++i) _vertices.push_back(curve[i]); } diff --git a/source/blender/freestyle/intern/geometry/Grid.h b/source/blender/freestyle/intern/geometry/Grid.h index 08b614faa95..a1368f1ea21 100644 --- a/source/blender/freestyle/intern/geometry/Grid.h +++ b/source/blender/freestyle/intern/geometry/Grid.h @@ -89,7 +89,6 @@ private: OccludersSet _occluders; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Cell") #endif }; @@ -372,7 +371,6 @@ protected: OccludersSet _occluders; // List of all occluders inserted in the grid #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Grid") #endif }; @@ -395,7 +393,6 @@ private: OccludersSet::iterator it, end; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:VirtualOccludersSet") #endif }; diff --git a/source/blender/freestyle/intern/geometry/Noise.h b/source/blender/freestyle/intern/geometry/Noise.h index cd1be53a5aa..8798bc45a93 100644 --- a/source/blender/freestyle/intern/geometry/Noise.h +++ b/source/blender/freestyle/intern/geometry/Noise.h @@ -81,7 +81,6 @@ private: // int start; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Noise") #endif }; diff --git a/source/blender/freestyle/intern/geometry/Polygon.h b/source/blender/freestyle/intern/geometry/Polygon.h index cfeae8fd632..d8b891c77cc 100644 --- a/source/blender/freestyle/intern/geometry/Polygon.h +++ b/source/blender/freestyle/intern/geometry/Polygon.h @@ -171,7 +171,6 @@ protected: unsigned _id; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Geometry:Polygon") #endif }; diff --git a/source/blender/freestyle/intern/geometry/SweepLine.h b/source/blender/freestyle/intern/geometry/SweepLine.h index 86058a434bf..039ecd7ebf4 100644 --- a/source/blender/freestyle/intern/geometry/SweepLine.h +++ b/source/blender/freestyle/intern/geometry/SweepLine.h @@ -190,7 +190,6 @@ private: bool _order; // true if A and B are in the same order than _edge.A and _edge.B. false otherwise. #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Segment") #endif }; @@ -337,7 +336,6 @@ private: std::vector<Intersection<Segment<T, Point> > *> _Intersections; // the list of all intersections. #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SweepLine") #endif }; diff --git a/source/blender/freestyle/intern/geometry/VecMat.h b/source/blender/freestyle/intern/geometry/VecMat.h index 1948dadb207..c3aae0601fe 100644 --- a/source/blender/freestyle/intern/geometry/VecMat.h +++ b/source/blender/freestyle/intern/geometry/VecMat.h @@ -278,7 +278,6 @@ protected: }; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:VecMat:Vec") #endif }; @@ -766,7 +765,6 @@ protected: value_type _coord[_SIZE]; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:VecMat:Matrix") #endif }; diff --git a/source/blender/freestyle/intern/geometry/normal_cycle.h b/source/blender/freestyle/intern/geometry/normal_cycle.h index 441fca7ac5f..7a63acdf52a 100644 --- a/source/blender/freestyle/intern/geometry/normal_cycle.h +++ b/source/blender/freestyle/intern/geometry/normal_cycle.h @@ -129,7 +129,6 @@ private: int i_[3]; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:OGF:NormalCycle") #endif }; diff --git a/source/blender/freestyle/intern/image/GaussianFilter.h b/source/blender/freestyle/intern/image/GaussianFilter.h index 313441a07d3..d3175e86382 100644 --- a/source/blender/freestyle/intern/image/GaussianFilter.h +++ b/source/blender/freestyle/intern/image/GaussianFilter.h @@ -115,7 +115,6 @@ protected: void computeMask(); #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:GaussianFilter") #endif }; diff --git a/source/blender/freestyle/intern/image/Image.h b/source/blender/freestyle/intern/image/Image.h index 12be1816c1a..577dc0fb866 100644 --- a/source/blender/freestyle/intern/image/Image.h +++ b/source/blender/freestyle/intern/image/Image.h @@ -173,7 +173,6 @@ protected: unsigned _Oy; // origin of the stored part #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FrsImage") #endif }; diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp index 4fa46b62185..69d0adadc00 100644 --- a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp +++ b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp @@ -135,7 +135,7 @@ static int CurvePoint_init(BPy_CurvePoint *self, PyObject *args, PyObject *kwds) PyDoc_STRVAR(CurvePoint_first_svertex_doc, "The first SVertex upon which the CurvePoint is built.\n" "\n" -":type: int"); +":type: :class:`SVertex`"); static PyObject *CurvePoint_first_svertex_get(BPy_CurvePoint *self, void *UNUSED(closure)) { @@ -158,7 +158,7 @@ static int CurvePoint_first_svertex_set(BPy_CurvePoint *self, PyObject *value, v PyDoc_STRVAR(CurvePoint_second_svertex_doc, "The second SVertex upon which the CurvePoint is built.\n" "\n" -":type: int"); +":type: :class:`SVertex`"); static PyObject *CurvePoint_second_svertex_get(BPy_CurvePoint *self, void *UNUSED(closure)) { diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp index 37c25760bd7..3205a3a3d7e 100644 --- a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp +++ b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp @@ -371,6 +371,7 @@ static PyObject *SVertex_normals_size_get(BPy_SVertex *self, void *UNUSED(closur PyDoc_STRVAR(SVertex_viewvertex_doc, "If this SVertex is also a ViewVertex, this property refers to the\n" "ViewVertex, and None otherwise.\n" +"\n" ":type: :class:`ViewVertex`"); static PyObject *SVertex_viewvertex_get(BPy_SVertex *self, void *UNUSED(closure)) diff --git a/source/blender/freestyle/intern/scene_graph/DrawingStyle.h b/source/blender/freestyle/intern/scene_graph/DrawingStyle.h index 9fbdd0e0fad..192fa76c497 100644 --- a/source/blender/freestyle/intern/scene_graph/DrawingStyle.h +++ b/source/blender/freestyle/intern/scene_graph/DrawingStyle.h @@ -106,7 +106,6 @@ private: bool LightingEnabled; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:DrawingStyle") #endif }; diff --git a/source/blender/freestyle/intern/scene_graph/FrsMaterial.h b/source/blender/freestyle/intern/scene_graph/FrsMaterial.h index 7e9eeda26d5..4d1fc4e69c9 100644 --- a/source/blender/freestyle/intern/scene_graph/FrsMaterial.h +++ b/source/blender/freestyle/intern/scene_graph/FrsMaterial.h @@ -259,7 +259,6 @@ private: float Shininess; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FrsMaterial") #endif }; diff --git a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h index 2995360fb24..1ffddc9b24d 100644 --- a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h +++ b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h @@ -312,6 +312,11 @@ protected: unsigned _TISize; unsigned int _displayList; + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:IndexedFaceSet") +#endif + }; } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/scene_graph/LineRep.h b/source/blender/freestyle/intern/scene_graph/LineRep.h index c5de30309f6..6452e1260ad 100644 --- a/source/blender/freestyle/intern/scene_graph/LineRep.h +++ b/source/blender/freestyle/intern/scene_graph/LineRep.h @@ -148,6 +148,11 @@ private: LINES_STYLE _Style; vector<Vec3r> _vertices; float _width; + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:LineRep") +#endif + }; } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/scene_graph/Node.h b/source/blender/freestyle/intern/scene_graph/Node.h index 47ce6aaf8e6..ba8549f5128 100644 --- a/source/blender/freestyle/intern/scene_graph/Node.h +++ b/source/blender/freestyle/intern/scene_graph/Node.h @@ -106,6 +106,11 @@ protected: private: BBox<Vec3r> _BBox; + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Node") +#endif + }; } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/scene_graph/NodeCamera.h b/source/blender/freestyle/intern/scene_graph/NodeCamera.h index 8e5cf9be52d..ee630e91884 100644 --- a/source/blender/freestyle/intern/scene_graph/NodeCamera.h +++ b/source/blender/freestyle/intern/scene_graph/NodeCamera.h @@ -83,6 +83,11 @@ protected: double projection_matrix_[16]; CameraType camera_type_; + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:NodeCamera") +#endif + }; class LIB_SCENE_GRAPH_EXPORT NodeOrthographicCamera : public NodeCamera @@ -145,6 +150,11 @@ private: double top_; double zNear_; double zFar_; + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:NodeOrthographicCamera") +#endif + }; class LIB_SCENE_GRAPH_EXPORT NodePerspectiveCamera : public NodeCamera @@ -205,6 +215,11 @@ public: * zFar-zNear */ NodePerspectiveCamera(double left, double right, double bottom, double top, double zNear, double zFar); + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:NodePerspectiveCamera") +#endif + }; } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h b/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h index a846b050db1..7e8c6635953 100644 --- a/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h +++ b/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h @@ -101,6 +101,11 @@ public: private: DrawingStyle _DrawingStyle; + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:NodeDrawingStyle") +#endif + }; } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/stroke/Module.h b/source/blender/freestyle/intern/stroke/Module.h index b43c2d6247e..64b6f34afa4 100644 --- a/source/blender/freestyle/intern/stroke/Module.h +++ b/source/blender/freestyle/intern/stroke/Module.h @@ -78,7 +78,6 @@ private: } #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Module") #endif }; diff --git a/source/blender/freestyle/intern/stroke/Operators.h b/source/blender/freestyle/intern/stroke/Operators.h index 61b20f556b5..dcd61b8ce84 100644 --- a/source/blender/freestyle/intern/stroke/Operators.h +++ b/source/blender/freestyle/intern/stroke/Operators.h @@ -270,7 +270,6 @@ private: static StrokesContainer _current_strokes_set; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Operators") #endif }; diff --git a/source/blender/freestyle/intern/stroke/Predicates0D.h b/source/blender/freestyle/intern/stroke/Predicates0D.h index 0f04c0827c3..a6e7cbee042 100644 --- a/source/blender/freestyle/intern/stroke/Predicates0D.h +++ b/source/blender/freestyle/intern/stroke/Predicates0D.h @@ -82,7 +82,6 @@ public: } #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:UnaryPredicate0D") #endif }; @@ -133,7 +132,6 @@ public: } #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BinaryPredicate0D") #endif }; diff --git a/source/blender/freestyle/intern/stroke/Stroke.h b/source/blender/freestyle/intern/stroke/Stroke.h index 5415d003c5e..e7a75728985 100644 --- a/source/blender/freestyle/intern/stroke/Stroke.h +++ b/source/blender/freestyle/intern/stroke/Stroke.h @@ -303,7 +303,6 @@ private: Vec3fMap *_userAttributesVec3f; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:StrokeAttribute") #endif }; diff --git a/source/blender/freestyle/intern/stroke/StrokeRenderer.h b/source/blender/freestyle/intern/stroke/StrokeRenderer.h index e38b7107efd..e5478c81b40 100644 --- a/source/blender/freestyle/intern/stroke/StrokeRenderer.h +++ b/source/blender/freestyle/intern/stroke/StrokeRenderer.h @@ -113,7 +113,6 @@ protected: unsigned int _defaultTextureId; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:TextureManager") #endif }; diff --git a/source/blender/freestyle/intern/stroke/StrokeRep.cpp b/source/blender/freestyle/intern/stroke/StrokeRep.cpp index c2811895147..2615df0a124 100644 --- a/source/blender/freestyle/intern/stroke/StrokeRep.cpp +++ b/source/blender/freestyle/intern/stroke/StrokeRep.cpp @@ -414,10 +414,10 @@ void Strip::cleanUpSingularities (const vector<StrokeVertex*>& iStrokeVertices) cerr << "Stephane dit \"Toto\"" << endl; //traverse all the vertices of the singularity and average them Vec2r avP(0.0, 0.0); - for (j = i - timeSinceSingu1; j < i + 1; j++) + for (j = i - timeSinceSingu1; j <= i; j++) avP = Vec2r(avP + _vertices[2 * j]->point2d()); avP = Vec2r( 1.0 / float(timeSinceSingu1 + 1) * avP); - for (j = i - timeSinceSingu1; j < i + 1; j++) + for (j = i - timeSinceSingu1; j <= i; j++) _vertices[2 * j]->setPoint2d(avP); //_vertex[2 * j] = _vertex[2 * i]; singu1 = false; @@ -435,10 +435,10 @@ void Strip::cleanUpSingularities (const vector<StrokeVertex*>& iStrokeVertices) cerr << "Stephane dit \"Toto\"" << endl; //traverse all the vertices of the singularity and average them Vec2r avP(0.0, 0.0); - for (j = i - timeSinceSingu2; j < i + 1; j++) + for (j = i - timeSinceSingu2; j <= i; j++) avP = Vec2r(avP + _vertices[2 * j + 1]->point2d()); avP = Vec2r(1.0 / float(timeSinceSingu2 + 1) * avP); - for (j = i - timeSinceSingu2; j < i + 1; j++) + for (j = i - timeSinceSingu2; j <= i; j++) _vertices[2 * j + 1]->setPoint2d(avP); //_vertex[2 * j + 1] = _vertex[2 * i + 1]; singu2 = false; diff --git a/source/blender/freestyle/intern/stroke/StrokeRep.h b/source/blender/freestyle/intern/stroke/StrokeRep.h index 38d6716584d..d01b27215fe 100644 --- a/source/blender/freestyle/intern/stroke/StrokeRep.h +++ b/source/blender/freestyle/intern/stroke/StrokeRep.h @@ -120,7 +120,6 @@ protected: float _alpha; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:StrokeVertexRep") #endif }; diff --git a/source/blender/freestyle/intern/stroke/StrokeTesselator.h b/source/blender/freestyle/intern/stroke/StrokeTesselator.h index e8ff75f7a96..661c871a4d5 100644 --- a/source/blender/freestyle/intern/stroke/StrokeTesselator.h +++ b/source/blender/freestyle/intern/stroke/StrokeTesselator.h @@ -74,7 +74,6 @@ private: bool _overloadFrsMaterial; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:StrokeTesselator") #endif }; diff --git a/source/blender/freestyle/intern/stroke/StyleModule.h b/source/blender/freestyle/intern/stroke/StyleModule.h index c34a288c5d6..f1d96283f90 100644 --- a/source/blender/freestyle/intern/stroke/StyleModule.h +++ b/source/blender/freestyle/intern/stroke/StyleModule.h @@ -180,7 +180,6 @@ protected: Interpreter *_inter; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:StyleModule") #endif }; diff --git a/source/blender/freestyle/intern/system/BaseIterator.h b/source/blender/freestyle/intern/system/BaseIterator.h index f27bfb68b9f..9eb06744095 100644 --- a/source/blender/freestyle/intern/system/BaseIterator.h +++ b/source/blender/freestyle/intern/system/BaseIterator.h @@ -109,7 +109,6 @@ protected: IteratorBase() {} #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:IteratorBase") #endif }; diff --git a/source/blender/freestyle/intern/system/BaseObject.h b/source/blender/freestyle/intern/system/BaseObject.h index a9e501be38f..56f52a5fb80 100644 --- a/source/blender/freestyle/intern/system/BaseObject.h +++ b/source/blender/freestyle/intern/system/BaseObject.h @@ -73,7 +73,6 @@ private: unsigned _ref_counter; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BaseObject") #endif }; diff --git a/source/blender/freestyle/intern/system/Exception.h b/source/blender/freestyle/intern/system/Exception.h index d69de7b10dd..dedc4152ae9 100644 --- a/source/blender/freestyle/intern/system/Exception.h +++ b/source/blender/freestyle/intern/system/Exception.h @@ -66,7 +66,6 @@ private: static exception_type _exception; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Exception") #endif }; diff --git a/source/blender/freestyle/intern/system/Id.h b/source/blender/freestyle/intern/system/Id.h index 5260a38c709..9cd45646f1c 100644 --- a/source/blender/freestyle/intern/system/Id.h +++ b/source/blender/freestyle/intern/system/Id.h @@ -131,7 +131,6 @@ private: id_type _second; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Id") #endif }; diff --git a/source/blender/freestyle/intern/system/Interpreter.h b/source/blender/freestyle/intern/system/Interpreter.h index 9b7acc1cf46..e1269f40468 100644 --- a/source/blender/freestyle/intern/system/Interpreter.h +++ b/source/blender/freestyle/intern/system/Interpreter.h @@ -61,7 +61,6 @@ protected: string _language; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Interpreter") #endif }; diff --git a/source/blender/freestyle/intern/system/ProgressBar.h b/source/blender/freestyle/intern/system/ProgressBar.h index 754004d7f81..56dbef59b0e 100644 --- a/source/blender/freestyle/intern/system/ProgressBar.h +++ b/source/blender/freestyle/intern/system/ProgressBar.h @@ -92,7 +92,6 @@ protected: string _label; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ProgressBar") #endif }; diff --git a/source/blender/freestyle/intern/system/PseudoNoise.h b/source/blender/freestyle/intern/system/PseudoNoise.h index ce725723b59..e53d8ed7a7a 100644 --- a/source/blender/freestyle/intern/system/PseudoNoise.h +++ b/source/blender/freestyle/intern/system/PseudoNoise.h @@ -57,7 +57,6 @@ protected: static real _values[NB_VALUE_NOISE]; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:PseudoNoise") #endif }; diff --git a/source/blender/freestyle/intern/system/RandGen.h b/source/blender/freestyle/intern/system/RandGen.h index c3e2b3d99f7..3c8724bcbee 100644 --- a/source/blender/freestyle/intern/system/RandGen.h +++ b/source/blender/freestyle/intern/system/RandGen.h @@ -50,7 +50,6 @@ private: static void next(); #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:RandGen") #endif }; diff --git a/source/blender/freestyle/intern/system/RenderMonitor.h b/source/blender/freestyle/intern/system/RenderMonitor.h index 0453f81e5b5..7910bf13c63 100644 --- a/source/blender/freestyle/intern/system/RenderMonitor.h +++ b/source/blender/freestyle/intern/system/RenderMonitor.h @@ -72,7 +72,6 @@ protected: Render *_re; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:RenderMonitor") #endif }; diff --git a/source/blender/freestyle/intern/system/TimeStamp.h b/source/blender/freestyle/intern/system/TimeStamp.h index 052816c5a85..e809aa71575 100644 --- a/source/blender/freestyle/intern/system/TimeStamp.h +++ b/source/blender/freestyle/intern/system/TimeStamp.h @@ -72,7 +72,6 @@ private: unsigned _time_stamp; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:TimeStamp") #endif }; diff --git a/source/blender/freestyle/intern/system/TimeUtils.h b/source/blender/freestyle/intern/system/TimeUtils.h index 1bdcf2d7d38..bbf4c5a1edb 100644 --- a/source/blender/freestyle/intern/system/TimeUtils.h +++ b/source/blender/freestyle/intern/system/TimeUtils.h @@ -60,7 +60,6 @@ private: clock_t _start; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Chronometer") #endif }; diff --git a/source/blender/freestyle/intern/view_map/BoxGrid.h b/source/blender/freestyle/intern/view_map/BoxGrid.h index 8aa5167732d..92f886ef429 100644 --- a/source/blender/freestyle/intern/view_map/BoxGrid.h +++ b/source/blender/freestyle/intern/view_map/BoxGrid.h @@ -72,7 +72,6 @@ public: WFace *face; #ifdef WITH_CXX_GUARDEDALLOC - public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BoxGrid:OccluderData") #endif }; @@ -137,7 +136,6 @@ public: vector<OccluderData*>::iterator _current, _occludeeCandidate; #ifdef WITH_CXX_GUARDEDALLOC - public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BoxGrid:Iterator") #endif }; @@ -192,7 +190,6 @@ private: bool _enableQI; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BoxGrid") #endif }; diff --git a/source/blender/freestyle/intern/view_map/FEdgeXDetector.h b/source/blender/freestyle/intern/view_map/FEdgeXDetector.h index 59d6e23312f..2bc0cd13e88 100644 --- a/source/blender/freestyle/intern/view_map/FEdgeXDetector.h +++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.h @@ -237,7 +237,6 @@ protected: RenderMonitor *_pRenderMonitor; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FEdgeXDetector") #endif }; diff --git a/source/blender/freestyle/intern/view_map/Functions1D.h b/source/blender/freestyle/intern/view_map/Functions1D.h index a4dd1cd5e03..2d3da151d13 100644 --- a/source/blender/freestyle/intern/view_map/Functions1D.h +++ b/source/blender/freestyle/intern/view_map/Functions1D.h @@ -125,7 +125,6 @@ protected: IntegrationType _integration; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:UnaryFunction1D") #endif }; @@ -172,7 +171,6 @@ protected: IntegrationType _integration; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:UnaryFunction1D_void") #endif }; diff --git a/source/blender/freestyle/intern/view_map/GridDensityProvider.h b/source/blender/freestyle/intern/view_map/GridDensityProvider.h index fe14efbe20f..f14362e3deb 100644 --- a/source/blender/freestyle/intern/view_map/GridDensityProvider.h +++ b/source/blender/freestyle/intern/view_map/GridDensityProvider.h @@ -134,7 +134,6 @@ protected: float _cellOrigin[2]; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:GridDensityProvider") #endif }; diff --git a/source/blender/freestyle/intern/view_map/Interface1D.h b/source/blender/freestyle/intern/view_map/Interface1D.h index 2c1f4956e96..c7beafaf14d 100644 --- a/source/blender/freestyle/intern/view_map/Interface1D.h +++ b/source/blender/freestyle/intern/view_map/Interface1D.h @@ -226,7 +226,6 @@ protected: unsigned _timeStamp; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Interface1D") #endif }; diff --git a/source/blender/freestyle/intern/view_map/OccluderSource.h b/source/blender/freestyle/intern/view_map/OccluderSource.h index b6f30ce9e3a..b916661e04c 100644 --- a/source/blender/freestyle/intern/view_map/OccluderSource.h +++ b/source/blender/freestyle/intern/view_map/OccluderSource.h @@ -72,7 +72,6 @@ protected: void buildCachedPolygon(); #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:OccluderSource") #endif }; diff --git a/source/blender/freestyle/intern/view_map/SphericalGrid.h b/source/blender/freestyle/intern/view_map/SphericalGrid.h index 56d2ae3cf5e..050dcc4c882 100644 --- a/source/blender/freestyle/intern/view_map/SphericalGrid.h +++ b/source/blender/freestyle/intern/view_map/SphericalGrid.h @@ -135,7 +135,6 @@ public: vector<OccluderData*>::iterator _current, _occludeeCandidate; #ifdef WITH_CXX_GUARDEDALLOC - public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SphericalGrid:Iterator") #endif @@ -191,7 +190,6 @@ private: bool _enableQI; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SphericalGrid") #endif }; diff --git a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp index 7693afdce07..c777db6249f 100644 --- a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp +++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp @@ -74,7 +74,7 @@ SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother) _directions = iBrother._directions; _mapping = iBrother._mapping; _imagesPyramids = new ImagePyramid *[_nbOrientations + 1]; // one more map to store the complete visible VM - for (i = 0; i < _nbOrientations + 1; ++i) + for (i = 0; i <= _nbOrientations; ++i) _imagesPyramids[i] = new GaussianPyramid(*(dynamic_cast<GaussianPyramid*>(iBrother._imagesPyramids[i]))); } diff --git a/source/blender/freestyle/intern/view_map/SteerableViewMap.h b/source/blender/freestyle/intern/view_map/SteerableViewMap.h index 9af65765fcd..23681b43c48 100644 --- a/source/blender/freestyle/intern/view_map/SteerableViewMap.h +++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.h @@ -150,7 +150,6 @@ protected: void Build(); #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SteerableViewMap") #endif }; diff --git a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h index b036410a9fe..6efc81efbaf 100644 --- a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h +++ b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h @@ -293,7 +293,6 @@ protected: ViewShape *_pCurrentVShape; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewEdgeXBuilder") #endif }; diff --git a/source/blender/freestyle/intern/view_map/ViewMap.h b/source/blender/freestyle/intern/view_map/ViewMap.h index f684f2b919d..987a5bda9b3 100644 --- a/source/blender/freestyle/intern/view_map/ViewMap.h +++ b/source/blender/freestyle/intern/view_map/ViewMap.h @@ -365,6 +365,11 @@ public: /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge given as argument. */ virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge) = 0; + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewVertex") +#endif + }; /**********************************/ @@ -633,6 +638,11 @@ public: /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge given as argument. */ virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge); + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:TVertex") +#endif + }; @@ -845,6 +855,11 @@ public: /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge given as argument. */ virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge); + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:NonTVertex") +#endif + }; /**********************************/ @@ -1360,6 +1375,11 @@ public: * the sampling value. */ virtual Interface0DIterator pointsEnd(float t = 0.0f); + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewEdge") +#endif + }; diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.h b/source/blender/freestyle/intern/view_map/ViewMapBuilder.h index 05596daa85b..29e393052a3 100644 --- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.h +++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.h @@ -253,7 +253,6 @@ protected: Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices); #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapBuilder") #endif }; diff --git a/source/blender/freestyle/intern/view_map/ViewMapIO.cpp b/source/blender/freestyle/intern/view_map/ViewMapIO.cpp index 5df3e4e0d8f..e78fb894be0 100644 --- a/source/blender/freestyle/intern/view_map/ViewMapIO.cpp +++ b/source/blender/freestyle/intern/view_map/ViewMapIO.cpp @@ -982,7 +982,7 @@ int load(istream& in, ViewMap *vm, ProgressBar *pb) if (fe_s) { bool b; READ(b); - for (READ(fe_rle1), fe_rle2 = 0; fe_rle1 < fe_s + 1; fe_rle2 = fe_rle1, READ(fe_rle1)) { + for (READ(fe_rle1), fe_rle2 = 0; fe_rle1 <= fe_s; fe_rle2 = fe_rle1, READ(fe_rle1)) { if (b) { for (unsigned int i = fe_rle2; i < fe_rle1; i++) { FEdgeSmooth *fes = new FEdgeSmooth; @@ -1007,7 +1007,7 @@ int load(istream& in, ViewMap *vm, ProgressBar *pb) if (vv_s) { Nature::VertexNature nature; READ(nature); - for (READ(vv_rle1), vv_rle2 = 0; vv_rle1 < vv_s + 1; vv_rle2 = vv_rle1, READ(vv_rle1)) { + for (READ(vv_rle1), vv_rle2 = 0; vv_rle1 <= vv_s; vv_rle2 = vv_rle1, READ(vv_rle1)) { if (nature & Nature::T_VERTEX) { for (unsigned int i = vv_rle2; i < vv_rle1; i++) { TVertex *tv = new TVertex(); diff --git a/source/blender/freestyle/intern/view_map/ViewMapIterators.h b/source/blender/freestyle/intern/view_map/ViewMapIterators.h index 72d439da8bd..2794d9028d2 100644 --- a/source/blender/freestyle/intern/view_map/ViewMapIterators.h +++ b/source/blender/freestyle/intern/view_map/ViewMapIterators.h @@ -219,6 +219,11 @@ public: } return 0; } + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:orientedViewEdgeIterator") +#endif + }; } // ViewVertexInternal namespace @@ -390,6 +395,11 @@ private: FEdge *_previous_edge; FEdge *_next_edge; float _t; // curvilinear abscissa + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SVertexIterator") +#endif + }; @@ -561,6 +571,11 @@ protected: bool _orientation; ViewEdge *_edge; ViewEdge *_begin; + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewEdgeIterator") +#endif + }; } // end of namespace ViewEdgeInternal diff --git a/source/blender/freestyle/intern/view_map/ViewMapTesselator.h b/source/blender/freestyle/intern/view_map/ViewMapTesselator.h index d37d0b6e5a5..9c4d214d931 100644 --- a/source/blender/freestyle/intern/view_map/ViewMapTesselator.h +++ b/source/blender/freestyle/intern/view_map/ViewMapTesselator.h @@ -104,7 +104,6 @@ private: bool _overloadFrsMaterial; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapTesselator") #endif }; @@ -121,6 +120,11 @@ protected: { iLine->AddVertex(v->point2D()); } + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapTesselator2D") +#endif + }; /*! Class to tesselate the 3D silhouette */ @@ -135,6 +139,11 @@ protected: { iLine->AddVertex(v->point3D()); } + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapTesselator3D") +#endif + }; // diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.h b/source/blender/freestyle/intern/winged_edge/WEdge.h index e5020f2a7fa..f0692aecd5b 100644 --- a/source/blender/freestyle/intern/winged_edge/WEdge.h +++ b/source/blender/freestyle/intern/winged_edge/WEdge.h @@ -245,7 +245,6 @@ public: virtual void increment(); #ifdef WITH_CXX_GUARDEDALLOC - public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WVertex:incoming_edge_iterator") #endif }; @@ -330,7 +329,6 @@ public: } #ifdef WITH_CXX_GUARDEDALLOC - public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WVertex:face_iterator") #endif }; @@ -1282,7 +1280,6 @@ protected: WFace *face); #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WShape") #endif }; @@ -1327,7 +1324,6 @@ private: vector<WShape *> _wshapes; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WingedEdge") #endif }; diff --git a/source/blender/freestyle/intern/winged_edge/WFillGrid.h b/source/blender/freestyle/intern/winged_edge/WFillGrid.h index ca52f75847c..819bb24ffc2 100644 --- a/source/blender/freestyle/intern/winged_edge/WFillGrid.h +++ b/source/blender/freestyle/intern/winged_edge/WFillGrid.h @@ -84,7 +84,6 @@ private: unsigned _polygon_id; #ifdef WITH_CXX_GUARDEDALLOC -public: MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WFillGrid") #endif }; diff --git a/source/blender/freestyle/intern/winged_edge/WSFillGrid.h b/source/blender/freestyle/intern/winged_edge/WSFillGrid.h index ee693de9ba1..5b33df906a6 100644 --- a/source/blender/freestyle/intern/winged_edge/WSFillGrid.h +++ b/source/blender/freestyle/intern/winged_edge/WSFillGrid.h @@ -77,8 +77,13 @@ private: Grid *_grid; WingedEdge *_winged_edge; unsigned _polygon_id; + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WSFillGrid") +#endif + }; } /* namespace Freestyle */ -#endif // __FREESTYLE_WS_FILL_GRID_H__
\ No newline at end of file +#endif // __FREESTYLE_WS_FILL_GRID_H__ diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.h b/source/blender/freestyle/intern/winged_edge/WXEdge.h index f696e279ad0..364183bbc84 100644 --- a/source/blender/freestyle/intern/winged_edge/WXEdge.h +++ b/source/blender/freestyle/intern/winged_edge/WXEdge.h @@ -95,6 +95,11 @@ public: { return _curvatures; } + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXVertex") +#endif + }; @@ -197,6 +202,11 @@ public: { _order = i; } + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXEdge") +#endif + }; /********************************** @@ -686,6 +696,11 @@ public: (*wxf)->userdata = NULL; } } + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXFace") +#endif + }; @@ -782,6 +797,11 @@ public: } } /*! accessors */ + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXShape") +#endif + }; /* diff --git a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h index 0c3e97f7806..5579989072a 100644 --- a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h +++ b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h @@ -44,6 +44,11 @@ public: protected: virtual void buildWVertices(WShape& shape, const real *vertices, unsigned vsize); + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXEdgeBuilder") +#endif + }; } /* namespace Freestyle */ diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h index d8a045adfa3..d68acaf29c1 100644 --- a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h +++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h @@ -147,8 +147,13 @@ private: WingedEdge *_winged_edge; Matrix44r *_current_matrix; vector<Matrix44r *> _matrices_stack; + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WingedEdgeBuilder") +#endif + }; } /* namespace Freestyle */ -#endif // __FREESTYLE_WINGED_EDGE_BUILDER_H__
\ No newline at end of file +#endif // __FREESTYLE_WINGED_EDGE_BUILDER_H__ diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index 9f6f80585ab..fca8dcc3392 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -122,6 +122,7 @@ typedef struct GPUAttrib { } GPUAttrib; void GPU_global_buffer_pool_free(void); +void GPU_global_buffer_pool_free_unused(void); GPUBuffer *GPU_buffer_alloc(int size); void GPU_buffer_free(GPUBuffer *buffer); diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 4d52afbde93..c54f937f4a9 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -172,6 +172,15 @@ static void gpu_buffer_pool_free(GPUBufferPool *pool) MEM_freeN(pool); } +static void gpu_buffer_pool_free_unused(GPUBufferPool *pool) +{ + if (!pool) + return; + + while (pool->totbuf) + gpu_buffer_pool_delete_last(pool); +} + static GPUBufferPool *gpu_buffer_pool = NULL; static GPUBufferPool *gpu_get_global_buffer_pool(void) { @@ -188,6 +197,11 @@ void GPU_global_buffer_pool_free(void) gpu_buffer_pool = NULL; } +void GPU_global_buffer_pool_free_unused(void) +{ + gpu_buffer_pool_free_unused(gpu_buffer_pool); +} + /* get a GPUBuffer of at least `size' bytes; uses one from the buffer * pool if possible, otherwise creates a new one */ GPUBuffer *GPU_buffer_alloc(int size) @@ -1266,7 +1280,7 @@ struct GPU_Buffers { CCGKey gridkey; CCGElem **grids; const DMFlagMat *grid_flag_mats; - const BLI_bitmap *grid_hidden; + BLI_bitmap * const *grid_hidden; int *grid_indices; int totgrid; int has_hidden; @@ -1686,7 +1700,7 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids, } /* Returns the number of visible quads in the nodes' grids. */ -static int gpu_count_grid_quads(BLI_bitmap *grid_hidden, +static int gpu_count_grid_quads(BLI_bitmap **grid_hidden, int *grid_indices, int totgrid, int gridsize) { @@ -1697,7 +1711,7 @@ static int gpu_count_grid_quads(BLI_bitmap *grid_hidden, * visibility */ for (i = 0, totquad = 0; i < totgrid; i++) { - const BLI_bitmap gh = grid_hidden[grid_indices[i]]; + const BLI_bitmap *gh = grid_hidden[grid_indices[i]]; if (gh) { /* grid hidden are present, have to check each element */ @@ -1732,7 +1746,7 @@ static int gpu_count_grid_quads(BLI_bitmap *grid_hidden, GL_WRITE_ONLY_ARB); \ if (quad_data) { \ for (i = 0; i < totgrid; ++i) { \ - BLI_bitmap gh = NULL; \ + BLI_bitmap *gh = NULL; \ if (grid_hidden) \ gh = grid_hidden[(grid_indices)[i]]; \ \ @@ -1770,7 +1784,7 @@ static GLuint gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned *to static unsigned prev_totquad; /* used in the FILL_QUAD_BUFFER macro */ - const BLI_bitmap *grid_hidden = NULL; + BLI_bitmap * const *grid_hidden = NULL; int *grid_indices = NULL; int totgrid = 1; @@ -1815,7 +1829,7 @@ static GLuint gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned *to } GPU_Buffers *GPU_build_grid_buffers(int *grid_indices, int totgrid, - BLI_bitmap *grid_hidden, int gridsize) + BLI_bitmap **grid_hidden, int gridsize) { GPU_Buffers *buffers; int totquad; @@ -2200,7 +2214,7 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers) for (i = 0; i < buffers->totgrid; ++i) { int g = buffers->grid_indices[i]; CCGElem *grid = buffers->grids[g]; - BLI_bitmap gh = buffers->grid_hidden[g]; + BLI_bitmap *gh = buffers->grid_hidden[g]; /* TODO: could use strips with hiding as well */ diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 9dc98e59c42..e9f9d4a3379 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -1243,8 +1243,7 @@ void GPU_free_unused_buffers(void) image_free_queue = NULL; /* vbo buffers */ - /* it's probably not necessary to free all buffers every frame */ - /* GPU_buffer_pool_free_unused(0); */ + GPU_global_buffer_pool_free_unused(); BLI_unlock_thread(LOCK_OPENGL); } diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index ffd3bba5493..ea7b169a882 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -989,6 +989,8 @@ void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *b glMatrixMode(GL_PROJECTION); glLoadIdentity(); + glDisable(GL_DEPTH_TEST); + GPU_texture_bind(tex, 0); /* Drawing quad */ diff --git a/source/blender/imbuf/intern/bmp.c b/source/blender/imbuf/intern/bmp.c index 856124ab5cb..eb3cfc3ade3 100644 --- a/source/blender/imbuf/intern/bmp.c +++ b/source/blender/imbuf/intern/bmp.c @@ -100,11 +100,11 @@ static int checkbmp(unsigned char *mem) memcpy(&bmi, mem, sizeof(bmi)); u = LITTLE_LONG(bmi.biSize); - /* we only support uncompressed 24 or 32 bits images for now */ + /* we only support uncompressed images for now. */ if (u >= sizeof(BMPINFOHEADER)) { - if ((bmi.biCompression == 0) && (bmi.biClrUsed == 0)) { + if (bmi.biCompression == 0) { u = LITTLE_SHORT(bmi.biBitCount); - if (u >= 16) { + if (u >= 8) { ret_val = 1; } } @@ -125,7 +125,7 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co { struct ImBuf *ibuf = NULL; BMPINFOHEADER bmi; - int x, y, depth, skip, i; + int x, y, depth, ibuf_depth, skip, i; unsigned char *bmp, *rect; unsigned short col; double xppm, yppm; @@ -151,6 +151,13 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co xppm = LITTLE_LONG(bmi.biXPelsPerMeter); yppm = LITTLE_LONG(bmi.biYPelsPerMeter); + if (depth <= 8) { + ibuf_depth = 24; + } + else { + ibuf_depth = depth; + } + #if 0 printf("skip: %d, x: %d y: %d, depth: %d (%x)\n", skip, x, y, depth, bmi.biBitCount); @@ -159,14 +166,33 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co #endif if (flags & IB_test) { - ibuf = IMB_allocImBuf(x, y, depth, 0); + ibuf = IMB_allocImBuf(x, y, ibuf_depth, 0); } else { - ibuf = IMB_allocImBuf(x, y, depth, IB_rect); + ibuf = IMB_allocImBuf(x, y, ibuf_depth, IB_rect); bmp = mem + skip; rect = (unsigned char *) ibuf->rect; - if (depth == 16) { + if (depth == 8) { + const int x_pad = (4 - (x % 4)) % 4; + const char (*palette)[4] = (void *)bmp; + bmp += bmi.biClrUsed * 4; + for (i = y; i > 0; i--) { + int j; + for (j = x; j > 0; j--) { + const char *pcol = palette[bmp[0]]; + rect[0] = pcol[0]; + rect[1] = pcol[1]; + rect[2] = pcol[2]; + + rect[3] = 255; + rect += 4; bmp += 1; + } + /* rows are padded to multiples of 4 */ + bmp += x_pad; + } + } + else if (depth == 16) { for (i = x * y; i > 0; i--) { col = bmp[0] + (bmp[1] << 8); rect[0] = ((col >> 10) & 0x1f) << 3; @@ -179,6 +205,7 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co } else if (depth == 24) { + const int x_pad = x % 4; for (i = y; i > 0; i--) { int j; for (j = x; j > 0; j--) { @@ -190,7 +217,7 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co rect += 4; bmp += 3; } /* for 24-bit images, rows are padded to multiples of 4 */ - bmp += x % 4; + bmp += x_pad; } } else if (depth == 32) { diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 238e68b141c..0167eaccef0 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -2787,9 +2787,9 @@ static void update_glsl_display_processor(const ColorManagedViewSettings *view_s check_glsl_display_processor_changed(view_settings, display_settings, from_colorspace)) { /* Store settings of processor for further comparison. */ - strcpy(global_glsl_state.view, view_settings->view_transform); - strcpy(global_glsl_state.display, display_settings->display_device); - strcpy(global_glsl_state.input, from_colorspace); + BLI_strncpy(global_glsl_state.view, view_settings->view_transform, MAX_COLORSPACE_NAME); + BLI_strncpy(global_glsl_state.display, display_settings->display_device, MAX_COLORSPACE_NAME); + BLI_strncpy(global_glsl_state.input, from_colorspace, MAX_COLORSPACE_NAME); global_glsl_state.exposure = view_settings->exposure; global_glsl_state.gamma = view_settings->gamma; diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c index c66f2d62db2..7acfe8a9dd1 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -366,8 +366,8 @@ static void get_index_dir(struct anim *anim, char *index_dir, size_t index_dir_l if (!anim->index_dir[0]) { char fname[FILE_MAXFILE]; BLI_split_dirfile(anim->name, index_dir, fname, index_dir_len, sizeof(fname)); - BLI_join_dirfile(index_dir, index_dir_len, index_dir, "BL_proxy"); - BLI_join_dirfile(index_dir, index_dir_len, index_dir, fname); + BLI_path_append(index_dir, index_dir_len, "BL_proxy"); + BLI_path_append(index_dir, index_dir_len, fname); } else { BLI_strncpy(index_dir, anim->index_dir, index_dir_len); diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c index 59b78109aaf..18268043a04 100644 --- a/source/blender/imbuf/intern/thumbs.c +++ b/source/blender/imbuf/intern/thumbs.c @@ -67,35 +67,40 @@ # include <unistd.h> #endif -#define URI_MAX FILE_MAX * 3 + 8 +#define URI_MAX (FILE_MAX * 3 + 8) static int get_thumb_dir(char *dir, ThumbSize size) { + char *s = dir; + const char *subdir; #ifdef WIN32 wchar_t dir_16[MAX_PATH]; /* yes, applications shouldn't store data there, but so does GIMP :)*/ SHGetSpecialFolderPathW(0, dir_16, CSIDL_PROFILE, 0); conv_utf_16_to_8(dir_16, dir, FILE_MAX); - - + s += strlen(dir); #else const char *home = getenv("HOME"); if (!home) return 0; - BLI_strncpy(dir, home, FILE_MAX); + s += BLI_strncpy_rlen(s, home, FILE_MAX); #endif switch (size) { case THB_NORMAL: - strcat(dir, "/.thumbnails/normal/"); + subdir = "/.thumbnails/normal/"; break; case THB_LARGE: - strcat(dir, "/.thumbnails/large/"); + subdir = "/.thumbnails/large/"; break; case THB_FAIL: - strcat(dir, "/.thumbnails/fail/blender/"); + subdir = "/.thumbnails/fail/blender/"; break; default: return 0; /* unknown size */ } + + s += BLI_strncpy_rlen(s, subdir, FILE_MAX - (s - dir)); + (void)s; + return 1; } @@ -195,20 +200,20 @@ static int uri_from_filename(const char *path, char *uri) strcat(orig_uri, vol); dirstart += 2; } -#else - BLI_strncpy(orig_uri, "file://", FILE_MAX); -#endif strcat(orig_uri, dirstart); BLI_char_switch(orig_uri, '\\', '/'); +#else + BLI_snprintf(orig_uri, URI_MAX, "file://%s", dirstart); +#endif #ifdef WITH_ICONV { - char uri_utf8[FILE_MAX * 3 + 8]; - escape_uri_string(orig_uri, uri_utf8, FILE_MAX * 3 + 8, UNSAFE_PATH); + char uri_utf8[URI_MAX]; + escape_uri_string(orig_uri, uri_utf8, URI_MAX, UNSAFE_PATH); BLI_string_to_utf8(uri_utf8, uri, NULL); } #else - escape_uri_string(orig_uri, uri, FILE_MAX * 3 + 8, UNSAFE_PATH); + escape_uri_string(orig_uri, uri, URI_MAX, UNSAFE_PATH); #endif return 1; } @@ -396,7 +401,7 @@ ImBuf *IMB_thumb_create(const char *path, ThumbSize size, ThumbSource source, Im ImBuf *IMB_thumb_read(const char *path, ThumbSize size) { char thumb[FILE_MAX]; - char uri[FILE_MAX * 3 + 8]; + char uri[URI_MAX]; ImBuf *img = NULL; if (!uri_from_filename(path, uri)) { @@ -413,7 +418,7 @@ ImBuf *IMB_thumb_read(const char *path, ThumbSize size) void IMB_thumb_delete(const char *path, ThumbSize size) { char thumb[FILE_MAX]; - char uri[FILE_MAX * 3 + 8]; + char uri[URI_MAX]; if (!uri_from_filename(path, uri)) { return; @@ -433,7 +438,7 @@ void IMB_thumb_delete(const char *path, ThumbSize size) ImBuf *IMB_thumb_manage(const char *path, ThumbSize size, ThumbSource source) { char thumb[FILE_MAX]; - char uri[FILE_MAX * 3 + 8]; + char uri[URI_MAX]; struct stat st; ImBuf *img = NULL; diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 4ec5879cfac..a4b0e61d544 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -253,11 +253,11 @@ static void ffmpeg_log_callback(void *ptr, int level, const char *format, va_lis { if (ELEM(level, AV_LOG_FATAL, AV_LOG_ERROR)) { size_t n; - va_list arg2; + va_list args_cpy; - va_copy(arg2, arg); - - n = BLI_vsnprintf(ffmpeg_last_error, sizeof(ffmpeg_last_error), format, arg2); + va_copy(args_cpy, arg); + n = BLI_vsnprintf(ffmpeg_last_error, sizeof(ffmpeg_last_error), format, args_cpy); + va_end(args_cpy); /* strip trailing \n */ ffmpeg_last_error[n - 1] = '\0'; diff --git a/source/blender/makesdna/DNA_dynamicpaint_types.h b/source/blender/makesdna/DNA_dynamicpaint_types.h index 1f2a589dc27..d2b95c959b3 100644 --- a/source/blender/makesdna/DNA_dynamicpaint_types.h +++ b/source/blender/makesdna/DNA_dynamicpaint_types.h @@ -125,7 +125,8 @@ typedef struct DynamicPaintSurface { float influence_scale, radius_scale; /* wave settings */ - float wave_damping, wave_speed, wave_timescale, wave_spring; + float wave_damping, wave_speed, wave_timescale, wave_spring, wave_smoothness; + int pad2; char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ char image_output_path[1024]; /* 1024 = FILE_MAX */ diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h index 456196771a6..dae520f458d 100644 --- a/source/blender/makesdna/DNA_image_types.h +++ b/source/blender/makesdna/DNA_image_types.h @@ -106,7 +106,7 @@ typedef struct Image { /* for generated images */ int gen_x, gen_y; char gen_type, gen_flag; - char gen_pad[2]; + short gen_depth; /* display aspect - for UV editing images resized for faster openGL display */ float aspx, aspy; diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 947bf593310..e37d1368892 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -33,7 +33,6 @@ #define __DNA_MESH_TYPES_H__ #include "DNA_defs.h" -#include "DNA_listBase.h" #include "DNA_ID.h" #include "DNA_customdata_types.h" diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index a76f57a3e7c..5e65369b32d 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -282,16 +282,23 @@ typedef struct BevelModifierData { short val_flags; /* flags used to interpret the bevel value */ short lim_flags; /* flags to tell the tool how to limit the bevel */ short e_flags; /* flags to direct how edge weights are applied to verts */ - float bevel_angle; /* if the BME_BEVEL_ANGLE is set, this will be how "sharp" an edge must be before it gets beveled */ - char defgrp_name[64]; /* if the BME_BEVEL_VWEIGHT option is set, this will be the name of the vert group, MAX_VGROUP_NAME */ + float bevel_angle; /* if the MOD_BEVEL_ANGLE is set, this will be how "sharp" an edge must be before it gets beveled */ + char defgrp_name[64]; /* if the MOD_BEVEL_VWEIGHT option is set, this will be the name of the vert group, MAX_VGROUP_NAME */ } BevelModifierData; -typedef struct BMeshModifierData { - ModifierData modifier; - - float pad; - int type; -} BMeshModifierData; +#define MOD_BEVEL_VERT (1 << 1) +// #define MOD_BEVEL_RADIUS (1 << 2) +#define MOD_BEVEL_ANGLE (1 << 3) +#define MOD_BEVEL_WEIGHT (1 << 4) +#define MOD_BEVEL_VGROUP (1 << 5) +#define MOD_BEVEL_EMIN (1 << 7) +#define MOD_BEVEL_EMAX (1 << 8) +// #define MOD_BEVEL_RUNNING (1 << 9) +// #define MOD_BEVEL_RES (1 << 10) +// #define MOD_BEVEL_EVEN (1 << 11) /* this is a new setting not related to old (trunk bmesh bevel code) but adding +// * here because they are mixed - campbell */ +// #define MOD_BEVEL_DIST (1 << 12) /* same as above */ +#define MOD_BEVEL_OVERLAP_OK (1 << 13) /* Smoke modifier flags */ @@ -714,8 +721,7 @@ typedef struct SimpleDeformModifierData { char mode; /* deform function */ char axis; /* lock axis (for taper and strech) */ - char originOpts; /* originOptions */ - char pad; + char pad[2]; } SimpleDeformModifierData; @@ -727,12 +733,6 @@ typedef struct SimpleDeformModifierData { #define MOD_SIMPLEDEFORM_LOCK_AXIS_X (1<<0) #define MOD_SIMPLEDEFORM_LOCK_AXIS_Y (1<<1) -/* indicates whether simple deform should use the local - * coordinates or global coordinates of origin */ -/* XXX, this should have never been an option, all other modifiers work relatively - * (so moving both objects makes no change!) - Campbell */ -#define MOD_SIMPLEDEFORM_ORIGIN_LOCAL (1<<0) - #define MOD_UVPROJECT_MAX 10 typedef struct ShapeKeyModifierData { diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 8a9a95a9935..9ff4392242e 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -788,6 +788,12 @@ typedef struct NodeShaderAttribute { char name[64]; } NodeShaderAttribute; +typedef struct NodeShaderVectTransform { + int type; + int convert_from, convert_to; + int pad; +} NodeShaderVectTransform; + /* TEX_output */ typedef struct TexNodeOutput { char name[64]; @@ -869,6 +875,15 @@ typedef struct NodeShaderNormalMap { #define SHD_GLOSSY_SHARP 1 #define SHD_GLOSSY_GGX 2 +/* vector transform */ +#define SHD_VECT_TRANSFORM_TYPE_VECTOR 0 +#define SHD_VECT_TRANSFORM_TYPE_POINT 1 +#define SHD_VECT_TRANSFORM_TYPE_NORMAL 2 + +#define SHD_VECT_TRANSFORM_SPACE_WORLD 0 +#define SHD_VECT_TRANSFORM_SPACE_OBJECT 1 +#define SHD_VECT_TRANSFORM_SPACE_CAMERA 2 + /* toon modes */ #define SHD_TOON_DIFFUSE 0 #define SHD_TOON_GLOSSY 1 diff --git a/source/blender/makesdna/DNA_outliner_types.h b/source/blender/makesdna/DNA_outliner_types.h index 17124a724fe..53061b55e2d 100644 --- a/source/blender/makesdna/DNA_outliner_types.h +++ b/source/blender/makesdna/DNA_outliner_types.h @@ -32,7 +32,7 @@ #ifndef __DNA_OUTLINER_TYPES_H__ #define __DNA_OUTLINER_TYPES_H__ -#include "DNA_listBase.h" +#include "DNA_defs.h" struct ID; @@ -41,9 +41,12 @@ typedef struct TreeStoreElem { struct ID *id; } TreeStoreElem; +/* used only to store data in in blend files */ typedef struct TreeStore { - int totelem, usedelem; - TreeStoreElem *data; + int totelem DNA_DEPRECATED; /* was previously used for memory preallocation */ + int usedelem; /* number of elements in data array */ + TreeStoreElem *data; /* elements to be packed from mempool in writefile.c + * or extracted to mempool in readfile.c */ } TreeStore; /* TreeStoreElem->flag */ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 5e877ed697b..ceb745cf90a 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -209,34 +209,37 @@ typedef struct SceneRenderLayer { #define SCE_LAY_NEG_ZMASK 0x80000 /* srl->passflag */ -#define SCE_PASS_COMBINED (1<<0) -#define SCE_PASS_Z (1<<1) -#define SCE_PASS_RGBA (1<<2) -#define SCE_PASS_DIFFUSE (1<<3) -#define SCE_PASS_SPEC (1<<4) -#define SCE_PASS_SHADOW (1<<5) -#define SCE_PASS_AO (1<<6) -#define SCE_PASS_REFLECT (1<<7) -#define SCE_PASS_NORMAL (1<<8) -#define SCE_PASS_VECTOR (1<<9) -#define SCE_PASS_REFRACT (1<<10) -#define SCE_PASS_INDEXOB (1<<11) -#define SCE_PASS_UV (1<<12) -#define SCE_PASS_INDIRECT (1<<13) -#define SCE_PASS_MIST (1<<14) -#define SCE_PASS_RAYHITS (1<<15) -#define SCE_PASS_EMIT (1<<16) -#define SCE_PASS_ENVIRONMENT (1<<17) -#define SCE_PASS_INDEXMA (1<<18) -#define SCE_PASS_DIFFUSE_DIRECT (1<<19) -#define SCE_PASS_DIFFUSE_INDIRECT (1<<20) -#define SCE_PASS_DIFFUSE_COLOR (1<<21) -#define SCE_PASS_GLOSSY_DIRECT (1<<22) -#define SCE_PASS_GLOSSY_INDIRECT (1<<23) -#define SCE_PASS_GLOSSY_COLOR (1<<24) -#define SCE_PASS_TRANSM_DIRECT (1<<25) -#define SCE_PASS_TRANSM_INDIRECT (1<<26) -#define SCE_PASS_TRANSM_COLOR (1<<27) +#define SCE_PASS_COMBINED (1<<0) +#define SCE_PASS_Z (1<<1) +#define SCE_PASS_RGBA (1<<2) +#define SCE_PASS_DIFFUSE (1<<3) +#define SCE_PASS_SPEC (1<<4) +#define SCE_PASS_SHADOW (1<<5) +#define SCE_PASS_AO (1<<6) +#define SCE_PASS_REFLECT (1<<7) +#define SCE_PASS_NORMAL (1<<8) +#define SCE_PASS_VECTOR (1<<9) +#define SCE_PASS_REFRACT (1<<10) +#define SCE_PASS_INDEXOB (1<<11) +#define SCE_PASS_UV (1<<12) +#define SCE_PASS_INDIRECT (1<<13) +#define SCE_PASS_MIST (1<<14) +#define SCE_PASS_RAYHITS (1<<15) +#define SCE_PASS_EMIT (1<<16) +#define SCE_PASS_ENVIRONMENT (1<<17) +#define SCE_PASS_INDEXMA (1<<18) +#define SCE_PASS_DIFFUSE_DIRECT (1<<19) +#define SCE_PASS_DIFFUSE_INDIRECT (1<<20) +#define SCE_PASS_DIFFUSE_COLOR (1<<21) +#define SCE_PASS_GLOSSY_DIRECT (1<<22) +#define SCE_PASS_GLOSSY_INDIRECT (1<<23) +#define SCE_PASS_GLOSSY_COLOR (1<<24) +#define SCE_PASS_TRANSM_DIRECT (1<<25) +#define SCE_PASS_TRANSM_INDIRECT (1<<26) +#define SCE_PASS_TRANSM_COLOR (1<<27) +#define SCE_PASS_SUBSURFACE_DIRECT (1<<28) +#define SCE_PASS_SUBSURFACE_INDIRECT (1<<29) +#define SCE_PASS_SUBSURFACE_COLOR (1<<30) /* note, srl->passflag is treestore element 'nr' in outliner, short still... */ @@ -652,7 +655,8 @@ typedef struct GameData { short mode, matmode; short occlusionRes; /* resolution of occlusion Z buffer in pixel */ short physicsEngine; - short exitkey, pad; + short exitkey; + short vsync; /* Controls vsync: off, on, or adaptive (if supported) */ short ticrate, maxlogicstep, physubstep, maxphystep; short obstacleSimulation; short raster_storage; @@ -688,6 +692,11 @@ typedef struct GameData { #define RAS_STORE_VA 2 #define RAS_STORE_VBO 3 +/* vsync */ +#define VSYNC_OFF 0 +#define VSYNC_ON 1 +#define VSYNC_ADAPTIVE 2 + /* GameData.flag */ #define GAME_RESTRICT_ANIM_UPDATES (1 << 0) #define GAME_ENABLE_ALL_FRAMES (1 << 1) diff --git a/source/blender/makesdna/DNA_sound_types.h b/source/blender/makesdna/DNA_sound_types.h index 6dc45e4a6de..040942d6cea 100644 --- a/source/blender/makesdna/DNA_sound_types.h +++ b/source/blender/makesdna/DNA_sound_types.h @@ -33,7 +33,6 @@ #ifndef __DNA_SOUND_TYPES_H__ #define __DNA_SOUND_TYPES_H__ -#include "DNA_listBase.h" #include "DNA_ID.h" /* stupid... could easily be solved */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 2d87cb1d890..c562a1fefae 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -72,6 +72,8 @@ struct wmTimer; struct MovieClip; struct MovieClipScopes; struct Mask; +struct GHash; +struct BLI_mempool; /* SpaceLink (Base) ==================================== */ @@ -244,13 +246,14 @@ typedef struct SpaceOops { View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */ ListBase tree; - struct TreeStore *treestore; + struct BLI_mempool *treestore; /* search stuff */ char search_string[32]; struct TreeStoreElem search_tse; short flag, outlinevis, storeflag, search_flags; + struct GHash *treehash; } SpaceOops; diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript index 3b322491559..2d0c4260c97 100644 --- a/source/blender/makesrna/SConscript +++ b/source/blender/makesrna/SConscript @@ -130,10 +130,6 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', ' if env['WITH_BF_INTERNATIONAL']: defs.append('WITH_INTERNATIONAL') -if env['WITH_BF_FREESTYLE']: - incs += ' ../freestyle' - defs.append('WITH_FREESTYLE') - rnalib = env.BlenderLib ( 'bf_rna', objs, Split(incs), defines=defs, libtype=['core','player'], priority = [165,20] ) Return ('rnalib') diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index af14e959c11..592c518e9c0 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -280,11 +280,6 @@ blender_include_dirs( ../../../../intern/smoke/extern ) -if(WITH_FREESTYLE) - # TO BE REMOVED when the trunk merger is done - add_definitions(-DWITH_FREESTYLE) -endif() - blender_include_dirs_sys( ${GLEW_INCLUDE_PATH} ) diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript index 49528db0022..10b6a8c8d10 100644 --- a/source/blender/makesrna/intern/SConscript +++ b/source/blender/makesrna/intern/SConscript @@ -38,8 +38,6 @@ root_build_dir=normpath(env['BF_BUILDDIR']) source_files = env.Glob('*.c') source_files.remove('rna_access.c') -if not env['WITH_BF_FREESTYLE']: - source_files.remove('rna_linestyle.c') generated_files = source_files[:] generated_files.remove('rna_define.c') @@ -149,10 +147,6 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', ' if env['WITH_BF_INTERNATIONAL']: defs.append('WITH_INTERNATIONAL') -if env['WITH_BF_FREESTYLE']: - # TO BE REMOVED when the trunk merger is done - defs.append('WITH_FREESTYLE') - if not env['BF_DEBUG']: defs.append('NDEBUG') diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index faf348302e4..c158facca7c 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -177,8 +177,8 @@ static int replace_if_different(char *tmpfile, const char *dep_files[]) if (len_new != len_org) { - fclose(fp_new); - fclose(fp_org); + fclose(fp_new); fp_new = NULL; + fclose(fp_org); fp_org = NULL; REN_IF_DIFF; } @@ -191,8 +191,8 @@ static int replace_if_different(char *tmpfile, const char *dep_files[]) if (fread(arr_org, sizeof(char), len_org, fp_org) != len_org) fprintf(stderr, "%s:%d, error reading file %s for comparison.\n", __FILE__, __LINE__, orgfile); - fclose(fp_new); - fclose(fp_org); + fclose(fp_new); fp_new = NULL; + fclose(fp_org); fp_org = NULL; cmp = memcmp(arr_new, arr_org, len_new); @@ -319,15 +319,15 @@ static void rna_print_c_string(FILE *f, const char *str) static void rna_print_data_get(FILE *f, PropertyDefRNA *dp) { if (dp->dnastructfromname && dp->dnastructfromprop) - fprintf(f, " %s *data= (%s*)(((%s*)ptr->data)->%s);\n", dp->dnastructname, dp->dnastructname, + fprintf(f, " %s *data = (%s *)(((%s *)ptr->data)->%s);\n", dp->dnastructname, dp->dnastructname, dp->dnastructfromname, dp->dnastructfromprop); else - fprintf(f, " %s *data= (%s*)(ptr->data);\n", dp->dnastructname, dp->dnastructname); + fprintf(f, " %s *data = (%s *)(ptr->data);\n", dp->dnastructname, dp->dnastructname); } static void rna_print_id_get(FILE *f, PropertyDefRNA *UNUSED(dp)) { - fprintf(f, " ID *id= ptr->id.data;\n"); + fprintf(f, " ID *id = ptr->id.data;\n"); } static void rna_construct_function_name(char *buffer, int size, const char *structname, const char *propname, const char *type) @@ -646,14 +646,15 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr if (prop->flag & PROP_DYNAMIC) { char *lenfunc = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "get_length"); - fprintf(f, " int i, arraylen[RNA_MAX_ARRAY_DIMENSION];\n"); - fprintf(f, " int len= %s(ptr, arraylen);\n\n", lenfunc); - fprintf(f, " for (i=0; i < len; i++) {\n"); + fprintf(f, " unsigned int arraylen[RNA_MAX_ARRAY_DIMENSION];\n"); + fprintf(f, " unsigned int i;\n"); + fprintf(f, " unsigned int len = %s(ptr, arraylen);\n\n", lenfunc); + fprintf(f, " for (i = 0; i < len; i++) {\n"); MEM_freeN(lenfunc); } else { - fprintf(f, " int i;\n\n"); - fprintf(f, " for (i=0; i < %u; i++) {\n", prop->totarraylength); + fprintf(f, " unsigned int i;\n\n"); + fprintf(f, " for (i = 0; i < %u; i++) {\n", prop->totarraylength); } if (dp->dnaarraylength == 1) { @@ -674,11 +675,11 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr fprintf(f, ") != 0);\n"); } else if (rna_color_quantize(prop, dp)) { - fprintf(f, " values[i] = (%s)(data->%s[i]*(1.0f / 255.0f));\n", + fprintf(f, " values[i] = (%s)(data->%s[i] * (1.0f / 255.0f));\n", rna_type_type(prop), dp->dnaname); } else if (dp->dnatype) { - fprintf(f, " values[i] = (%s)%s(((%s*)data->%s)[i]);\n", + fprintf(f, " values[i] = (%s)%s(((%s *)data->%s)[i]);\n", rna_type_type(prop), (dp->booleannegative) ? "!" : "", dp->dnatype, dp->dnaname); } else { @@ -897,15 +898,15 @@ static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *pr char *lenfunc = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "set_length"); fprintf(f, " int i, arraylen[RNA_MAX_ARRAY_DIMENSION];\n"); - fprintf(f, " int len= %s(ptr, arraylen);\n\n", lenfunc); + fprintf(f, " int len = %s(ptr, arraylen);\n\n", lenfunc); rna_clamp_value_range(f, prop); - fprintf(f, " for (i=0; i < len; i++) {\n"); + fprintf(f, " for (i = 0; i < len; i++) {\n"); MEM_freeN(lenfunc); } else { fprintf(f, " int i;\n\n"); rna_clamp_value_range(f, prop); - fprintf(f, " for (i=0; i < %u; i++) {\n", prop->totarraylength); + fprintf(f, " for (i = 0; i < %u; i++) {\n", prop->totarraylength); } if (dp->dnaarraylength == 1) { @@ -934,7 +935,7 @@ static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *pr } else { if (dp->dnatype) - fprintf(f, " ((%s*)data->%s)[i] = %s", dp->dnatype, dp->dnaname, + fprintf(f, " ((%s *)data->%s)[i] = %s", dp->dnatype, dp->dnaname, (dp->booleannegative) ? "!" : ""); else fprintf(f, " (data->%s)[i] = %s", dp->dnaname, (dp->booleannegative) ? "!" : ""); @@ -1072,8 +1073,8 @@ static char *rna_def_property_begin_func(FILE *f, StructRNA *srna, PropertyRNA * rna_print_data_get(f, dp); fprintf(f, "\n memset(iter, 0, sizeof(*iter));\n"); - fprintf(f, " iter->parent= *ptr;\n"); - fprintf(f, " iter->prop= (PropertyRNA *)&rna_%s_%s;\n", srna->identifier, prop->identifier); + fprintf(f, " iter->parent = *ptr;\n"); + fprintf(f, " iter->prop = (PropertyRNA *)&rna_%s_%s;\n", srna->identifier, prop->identifier); if (dp->dnalengthname || dp->dnalengthfixed) { if (manualfunc) { @@ -1100,7 +1101,7 @@ static char *rna_def_property_begin_func(FILE *f, StructRNA *srna, PropertyRNA * getfunc = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "get"); fprintf(f, "\n if (iter->valid)\n"); - fprintf(f, " iter->ptr= %s(iter);\n", getfunc); + fprintf(f, " iter->ptr = %s(iter);\n", getfunc); fprintf(f, "}\n\n"); @@ -1139,14 +1140,14 @@ static char *rna_def_property_lookup_int_func(FILE *f, StructRNA *srna, Property return func; } - fprintf(f, " int found= 0;\n"); + fprintf(f, " int found = 0;\n"); fprintf(f, " CollectionPropertyIterator iter;\n\n"); fprintf(f, " %s_%s_begin(&iter, ptr);\n\n", srna->identifier, rna_safe_id(prop->identifier)); fprintf(f, " if (iter.valid) {\n"); if (strcmp(nextfunc, "rna_iterator_array_next") == 0) { - fprintf(f, " ArrayIterator *internal= iter.internal;\n"); + fprintf(f, " ArrayIterator *internal = iter.internal;\n"); fprintf(f, " if (index < 0 || index >= internal->length) {\n"); fprintf(f, "#ifdef __GNUC__\n"); fprintf(f, " printf(\"Array iterator out of range: %%s (index %%d)\\n\", __func__, index);\n"); @@ -1158,25 +1159,25 @@ static char *rna_def_property_lookup_int_func(FILE *f, StructRNA *srna, Property fprintf(f, " while (index-- > 0 && iter.valid) {\n"); fprintf(f, " rna_iterator_array_next(&iter);\n"); fprintf(f, " }\n"); - fprintf(f, " found= (index == -1 && iter.valid);\n"); + fprintf(f, " found = (index == -1 && iter.valid);\n"); fprintf(f, " }\n"); fprintf(f, " else {\n"); - fprintf(f, " internal->ptr += internal->itemsize*index;\n"); - fprintf(f, " found= 1;\n"); + fprintf(f, " internal->ptr += internal->itemsize * index;\n"); + fprintf(f, " found = 1;\n"); fprintf(f, " }\n"); } else if (strcmp(nextfunc, "rna_iterator_listbase_next") == 0) { - fprintf(f, " ListBaseIterator *internal= iter.internal;\n"); + fprintf(f, " ListBaseIterator *internal = iter.internal;\n"); fprintf(f, " if (internal->skip) {\n"); fprintf(f, " while (index-- > 0 && iter.valid) {\n"); fprintf(f, " rna_iterator_listbase_next(&iter);\n"); fprintf(f, " }\n"); - fprintf(f, " found= (index == -1 && iter.valid);\n"); + fprintf(f, " found = (index == -1 && iter.valid);\n"); fprintf(f, " }\n"); fprintf(f, " else {\n"); fprintf(f, " while (index-- > 0 && internal->link)\n"); - fprintf(f, " internal->link= internal->link->next;\n"); - fprintf(f, " found= (index == -1 && internal->link);\n"); + fprintf(f, " internal->link = internal->link->next;\n"); + fprintf(f, " found = (index == -1 && internal->link);\n"); fprintf(f, " }\n"); } @@ -1318,7 +1319,7 @@ static char *rna_def_property_next_func(FILE *f, StructRNA *srna, PropertyRNA *p getfunc = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "get"); fprintf(f, "\n if (iter->valid)\n"); - fprintf(f, " iter->ptr= %s(iter);\n", getfunc); + fprintf(f, " iter->ptr = %s(iter);\n", getfunc); fprintf(f, "}\n\n"); @@ -2202,7 +2203,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA else if ((type == PROP_POINTER) && (flag & PROP_RNAPTR) && !(flag & PROP_THICK_WRAP)) ptrstr = "*"; /* PROP_THICK_WRAP strings are pre-allocated on the ParameterList stack, - * but type name for string props is already char*, so leave empty */ + * but type name for string props is already (char *), so leave empty */ else if (type == PROP_STRING && (flag & PROP_THICK_WRAP)) ptrstr = ""; else @@ -2225,19 +2226,19 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA /* assign self */ if (func->flag & FUNC_USE_SELF_ID) { - fprintf(f, "\t_selfid= (struct ID*)_ptr->id.data;\n"); + fprintf(f, "\t_selfid = (struct ID *)_ptr->id.data;\n"); } if ((func->flag & FUNC_NO_SELF) == 0) { - if (dsrna->dnaname) fprintf(f, "\t_self= (struct %s *)_ptr->data;\n", dsrna->dnaname); - else fprintf(f, "\t_self= (struct %s *)_ptr->data;\n", srna->identifier); + if (dsrna->dnaname) fprintf(f, "\t_self = (struct %s *)_ptr->data;\n", dsrna->dnaname); + else fprintf(f, "\t_self = (struct %s *)_ptr->data;\n", srna->identifier); } else if (func->flag & FUNC_USE_SELF_TYPE) { - fprintf(f, "\t_type= _ptr->type;\n"); + fprintf(f, "\t_type = _ptr->type;\n"); } if (has_data) { - fprintf(f, "\t_data= (char *)_parms->data;\n"); + fprintf(f, "\t_data = (char *)_parms->data;\n"); } dparm = dfunc->cont.properties.first; @@ -2248,7 +2249,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA cptr = ((type == PROP_POINTER) && !(flag & PROP_RNAPTR)); if (dparm->prop == func->c_ret) - fprintf(f, "\t_retdata= _data;\n"); + fprintf(f, "\t_retdata = _data;\n"); else { const char *data_str; if (cptr || (flag & PROP_DYNAMIC)) { @@ -2275,7 +2276,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA /* this must be kept in sync with RNA_parameter_length_get_data, * we could just call the function directly, but this is faster */ if (flag & PROP_DYNAMIC) { - fprintf(f, "\t%s_len= %s((int *)_data);\n", dparm->prop->identifier, pout ? "" : "*"); + fprintf(f, "\t%s_len = %s((int *)_data);\n", dparm->prop->identifier, pout ? "" : "*"); data_str = "(&(((char *)_data)[sizeof(void *)]))"; } else { @@ -2286,12 +2287,12 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA if (!pout) fprintf(f, "%s", valstr); - fprintf(f, "((%s%s%s)%s);\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), + fprintf(f, "((%s%s %s)%s);\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, data_str); } if (dparm->next) - fprintf(f, "\t_data += %d;\n", rna_parameter_size_alloc(dparm->prop)); + fprintf(f, "\t_data += %d;\n", rna_parameter_size(dparm->prop)); } if (dfunc->call) { @@ -2356,7 +2357,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA dparm = rna_find_parameter_def(func->c_ret); ptrstr = (((dparm->prop->type == PROP_POINTER) && !(dparm->prop->flag & PROP_RNAPTR)) || (dparm->prop->arraydimension)) ? "*" : ""; - fprintf(f, "\t*((%s%s%s*)_retdata) = %s;\n", rna_type_struct(dparm->prop), + fprintf(f, "\t*((%s%s %s*)_retdata) = %s;\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, func->c_ret->identifier); } } @@ -2915,9 +2916,9 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr fprintf(f, ", %d, ", prop->flag); rna_print_c_string(f, prop->name); fprintf(f, ",\n\t"); rna_print_c_string(f, prop->description); fprintf(f, ",\n\t"); - fprintf(f, "%d,\n", prop->icon); - rna_print_c_string(f, prop->translation_context); fprintf(f, ",\n\t"); - fprintf(f, "\t%s, %s|%s, %s, %u, {%u, %u, %u}, %u,\n", + fprintf(f, "%d, ", prop->icon); + rna_print_c_string(f, prop->translation_context); fprintf(f, ",\n"); + fprintf(f, "\t%s, %s | %s, %s, %u, {%u, %u, %u}, %u,\n", RNA_property_typename(prop->type), rna_property_subtypename(prop->subtype), rna_property_subtype_unit(prop->subtype), @@ -3155,14 +3156,14 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE else fprintf(f, "NULL}},\n"); fprintf(f, "\t"); rna_print_c_string(f, srna->identifier); - fprintf(f, "\t, NULL,NULL\n"); /* PyType - Cant initialize here */ + fprintf(f, ", NULL, NULL"); /* PyType - Cant initialize here */ fprintf(f, ", %d, ", srna->flag); rna_print_c_string(f, srna->name); - fprintf(f, ", "); + fprintf(f, ",\n\t"); rna_print_c_string(f, srna->description); - fprintf(f, ", "); + fprintf(f, ",\n\t"); rna_print_c_string(f, srna->translation_context); - fprintf(f, ",\n\t%d,\n", srna->icon); + fprintf(f, ", %d,\n", srna->icon); prop = srna->nameproperty; if (prop) { @@ -3392,7 +3393,7 @@ static void rna_generate_header(BlenderRNA *UNUSED(brna), FILE *f) fprintf(f, " CollectionPropertyIterator rna_macro_iter; \\\n"); fprintf(f, " for (property##_begin(&rna_macro_iter, sptr); rna_macro_iter.valid; " "property##_next(&rna_macro_iter)) { \\\n"); - fprintf(f, " itemptr= rna_macro_iter.ptr;\n\n"); + fprintf(f, " itemptr = rna_macro_iter.ptr;\n\n"); fprintf(f, "#define FOREACH_END(property) \\\n"); fprintf(f, " } \\\n"); @@ -3495,7 +3496,7 @@ static const char *cpp_classes = "" "\n" "#define STRING_PROPERTY(sname, identifier) \\\n" " inline std::string sname::identifier(void) { \\\n" -" int len= sname##_##identifier##_length(&ptr); \\\n" +" int len = sname##_##identifier##_length(&ptr); \\\n" " std::string str; str.resize(len); \\\n" " sname##_##identifier##_get(&ptr, &str[0]); return str; } \\\n" " inline void sname::identifier(const std::string& value) { \\\n" @@ -3604,7 +3605,7 @@ static const char *cpp_classes = "" "\n" " Array() {}\n" " Array(const Array<T, Tsize>& other) { memcpy(data, other.data, sizeof(T) * Tsize); }\n" -" const Array<T, Tsize>& operator=(const Array<T, Tsize>& other) { memcpy(data, other.data, sizeof(T) * Tsize); " +" const Array<T, Tsize>& operator = (const Array<T, Tsize>& other) { memcpy(data, other.data, sizeof(T) * Tsize); " "return *this; }\n" "\n" " operator T*() { return data; }\n" @@ -3619,7 +3620,7 @@ static const char *cpp_classes = "" " DynamicArray() : data(NULL), length(0) {}\n" " DynamicArray(int new_length) : data(NULL), length(new_length) { data = (float *)malloc(sizeof(T) * new_length); }\n" " DynamicArray(const DynamicArray<T>& other) { copy_from(other); }\n" -" const DynamicArray<T>& operator=(const DynamicArray<T>& other) { copy_from(other); return *this; }\n" +" const DynamicArray<T>& operator = (const DynamicArray<T>& other) { copy_from(other); return *this; }\n" "\n" " ~DynamicArray() { if (data) free(data); }\n" "\n" @@ -3644,7 +3645,7 @@ static const char *cpp_classes = "" "template<typename T, TBeginFunc Tbegin, TNextFunc Tnext, TEndFunc Tend>\n" "class CollectionIterator {\n" "public:\n" -" CollectionIterator() : t(iter.ptr), init(false) { iter.valid= false; }\n" +" CollectionIterator() : t(iter.ptr), init(false) { iter.valid = false; }\n" " ~CollectionIterator(void) { if (init) Tend(&iter); };\n" "\n" " operator bool(void)\n" @@ -3653,7 +3654,7 @@ static const char *cpp_classes = "" "\n" " T& operator*(void) { return t; }\n" " T* operator->(void) { return &t; }\n" -" bool operator==(const CollectionIterator<T, Tbegin, Tnext, Tend>& other) " +" bool operator == (const CollectionIterator<T, Tbegin, Tnext, Tend>& other) " "{ return iter.valid == other.iter.valid; }\n" " bool operator!=(const CollectionIterator<T, Tbegin, Tnext, Tend>& other) " "{ return iter.valid != other.iter.valid; }\n" @@ -3662,7 +3663,7 @@ static const char *cpp_classes = "" " { if (init) Tend(&iter); Tbegin(&iter, (PointerRNA *)&ptr.ptr); t = T(iter.ptr); init = true; }\n" "\n" "private:\n" -" const CollectionIterator<T, Tbegin, Tnext, Tend>& operator=" +" const CollectionIterator<T, Tbegin, Tnext, Tend>& operator = " "(const CollectionIterator<T, Tbegin, Tnext, Tend>& copy) {}\n" "" " CollectionPropertyIterator iter;\n" diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 0489f85a37f..26febf217a6 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -347,15 +347,32 @@ int rna_IDMaterials_assign_int(PointerRNA *ptr, int key, const PointerRNA *assig static void rna_IDMaterials_append_id(ID *id, Material *ma) { - material_append_id(id, ma); + BKE_material_append_id(id, ma); WM_main_add_notifier(NC_OBJECT | ND_DRAW, id); WM_main_add_notifier(NC_OBJECT | ND_OB_SHADING, id); } -static Material *rna_IDMaterials_pop_id(ID *id, int index_i, int remove_material_slot) +static Material *rna_IDMaterials_pop_id(ID *id, ReportList *reports, int index_i, int remove_material_slot) { - Material *ma = material_pop_id(id, index_i, remove_material_slot); + Material *ma; + short *totcol = give_totcolp_id(id); + const short totcol_orig = *totcol; + if (index_i < 0) { + index_i += (*totcol); + } + + if ((index_i < 0) || (index_i >= (*totcol))) { + BKE_report(reports, RPT_ERROR, "Index out of range"); + return NULL; + } + + ma = BKE_material_pop_id(id, index_i, remove_material_slot); + + if (*totcol == totcol_orig) { + BKE_report(reports, RPT_ERROR, "No material to removed"); + return NULL; + } DAG_id_tag_update(id, OB_RECALC_DATA); WM_main_add_notifier(NC_OBJECT | ND_DRAW, id); @@ -364,6 +381,15 @@ static Material *rna_IDMaterials_pop_id(ID *id, int index_i, int remove_material return ma; } +static void rna_IDMaterials_clear_id(ID *id, int remove_material_slot) +{ + BKE_material_clear_id(id, remove_material_slot); + + DAG_id_tag_update(id, OB_RECALC_DATA); + WM_main_add_notifier(NC_OBJECT | ND_DRAW, id); + WM_main_add_notifier(NC_OBJECT | ND_OB_SHADING, id); +} + static void rna_Library_filepath_set(PointerRNA *ptr, const char *value) { Library *lib = (Library *)ptr->data; @@ -476,12 +502,16 @@ static void rna_def_ID_materials(BlenderRNA *brna) RNA_def_property_flag(parm, PROP_REQUIRED); func = RNA_def_function(srna, "pop", "rna_IDMaterials_pop_id"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a material from the data block"); - parm = RNA_def_int(func, "index", 0, 0, MAXMAT, "", "Index of material to remove", 0, MAXMAT); - RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_int(func, "index", -1, -MAXMAT, MAXMAT, "", "Index of material to remove", 0, MAXMAT); RNA_def_boolean(func, "update_data", 0, "", "Update data by re-adjusting the material slots assigned"); parm = RNA_def_pointer(func, "material", "Material", "", "Material to remove"); RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "clear", "rna_IDMaterials_clear_id"); + RNA_def_function_ui_description(func, "Remove all materials from the data block"); + RNA_def_boolean(func, "update_data", 0, "", "Update data by re-adjusting the material slots assigned"); } static void rna_def_ID(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 5499386dcf1..f3e561cde0a 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -5378,7 +5378,7 @@ ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *UNUSE /* allocate data */ for (parm = func->cont.properties.first; parm; parm = parm->next) { - alloc_size += rna_parameter_size_alloc(parm); + alloc_size += rna_parameter_size(parm); if (parm->flag & PROP_OUTPUT) parms->ret_count++; @@ -5440,7 +5440,7 @@ ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *UNUSE } } - data = ((char *)data) + rna_parameter_size_alloc(parm); + data = ((char *)data) + rna_parameter_size(parm); } return parms; @@ -5462,7 +5462,7 @@ void RNA_parameter_list_free(ParameterList *parms) MEM_freeN(data_alloc->array); } - tot += rna_parameter_size_alloc(parm); + tot += rna_parameter_size(parm); } MEM_freeN(parms->data); @@ -5497,7 +5497,7 @@ void RNA_parameter_list_begin(ParameterList *parms, ParameterIterator *iter) iter->offset = 0; if (iter->valid) { - iter->size = rna_parameter_size_alloc(iter->parm); + iter->size = rna_parameter_size(iter->parm); iter->data = (((char *)iter->parms->data)); /* +iter->offset, always 0 */ } } @@ -5509,7 +5509,7 @@ void RNA_parameter_list_next(ParameterIterator *iter) iter->valid = iter->parm != NULL; if (iter->valid) { - iter->size = rna_parameter_size_alloc(iter->parm); + iter->size = rna_parameter_size(iter->parm); iter->data = (((char *)iter->parms->data) + iter->offset); } } @@ -6392,6 +6392,7 @@ bool RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop, bool i PointerRNA propptr_b = RNA_property_pointer_get(b, prop); return RNA_struct_equals(&propptr_a, &propptr_b, is_strict); } + break; } default: diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index fd151ccebb9..a832a8cdf96 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -398,16 +398,7 @@ static void rna_EditBone_parent_set(PointerRNA *ptr, PointerRNA value) static void rna_EditBone_matrix_get(PointerRNA *ptr, float *values) { EditBone *ebone = (EditBone *)(ptr->data); - - float delta[3], tmat[3][3], mat[4][4]; - - /* Find the current bone matrix */ - sub_v3_v3v3(delta, ebone->tail, ebone->head); - vec_roll_to_mat3(delta, ebone->roll, tmat); - copy_m4_m3(mat, tmat); - copy_v3_v3(mat[3], ebone->head); - - memcpy(values, mat, 16 * sizeof(float)); + ED_armature_ebone_to_mat4(ebone, (float(*)[4])values); } static void rna_Armature_editbone_transform_update(Main *bmain, Scene *scene, PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index c1707048612..5d68a6905a3 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -1086,19 +1086,19 @@ static void rna_def_brush(BlenderRNA *brna) prop = RNA_def_property(srna, "texture_overlay_alpha", PROP_INT, PROP_PERCENTAGE); RNA_def_property_int_sdna(prop, NULL, "texture_overlay_alpha"); - RNA_def_property_range(prop, 1, 100); + RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "Texture Overlay Alpha", ""); RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "mask_overlay_alpha", PROP_INT, PROP_PERCENTAGE); RNA_def_property_int_sdna(prop, NULL, "mask_overlay_alpha"); - RNA_def_property_range(prop, 1, 100); + RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "Mask Texture Overlay Alpha", ""); RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "cursor_overlay_alpha", PROP_INT, PROP_PERCENTAGE); RNA_def_property_int_sdna(prop, NULL, "cursor_overlay_alpha"); - RNA_def_property_range(prop, 1, 100); + RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "Mask Texture Overlay Alpha", ""); RNA_def_property_update(prop, 0, "rna_Brush_update"); diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index ec61c543a9f..ebd06475c79 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -288,6 +288,7 @@ static char *rna_ColorRampElement_path(PointerRNA *ptr) if (RNA_path_resolve(&ramp_ptr, "color_ramp", &ramp_ptr, &prop)) { COLRAMP_GETPATH; } + break; } } } diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 969e715bebf..723f158bb50 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -3039,13 +3039,13 @@ void RNA_def_function_ui_description(FunctionRNA *func, const char *description) int rna_parameter_size(PropertyRNA *parm) { PropertyType ptype = parm->type; - int len = parm->totarraylength; /* only supports fixed length at the moment */ + int len = parm->totarraylength; - if (len > 0) { - /* XXX in other parts is mentioned that strings can be dynamic as well */ - if (parm->flag & PROP_DYNAMIC) - return sizeof(void *); + /* XXX in other parts is mentioned that strings can be dynamic as well */ + if (parm->flag & PROP_DYNAMIC) + return sizeof(ParameterDynAlloc); + if (len > 0) { switch (ptype) { case PROP_BOOLEAN: case PROP_INT: @@ -3106,18 +3106,6 @@ int rna_parameter_size(PropertyRNA *parm) return sizeof(void *); } -/* this function returns the size of the memory allocated for the parameter, - * useful for instance for memory alignment or for storing additional information */ -int rna_parameter_size_alloc(PropertyRNA *parm) -{ - int size = rna_parameter_size(parm); - - if (parm->flag & PROP_DYNAMIC) - size += sizeof(((ParameterDynAlloc *)NULL)->array_tot); - - return size; -} - /* Dynamic Enums */ void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item) diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c index fb16dd0c5a1..c716c3263d1 100644 --- a/source/blender/makesrna/intern/rna_dynamicpaint.c +++ b/source/blender/makesrna/intern/rna_dynamicpaint.c @@ -710,6 +710,12 @@ static void rna_def_canvas_surface(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.01, 1.0, 1, 2); RNA_def_property_ui_text(prop, "Spring", "Spring force that pulls water level back to zero"); + prop = RNA_def_property(srna, "wave_smoothness", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 10.0); + RNA_def_property_ui_range(prop, 0.1, 5.0, 1, 2); + RNA_def_property_ui_text(prop, "Smoothness", "Limit maximum steepness of wave slope between simulation points " + "(use higher values for smoother waves at expense of reduced detail)"); + prop = RNA_def_property(srna, "use_wave_open_border", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_WAVE_OPEN_BORDERS); RNA_def_property_ui_text(prop, "Open Borders", "Pass waves through mesh edges"); diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index efe6c08cafe..439bc51896f 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -118,11 +118,9 @@ static void rna_GPencilLayer_info_set(PointerRNA *ptr, const char *value) static void rna_GPencil_stroke_point_add(bGPDstroke *stroke, int count) { if (count > 0) { - if (stroke->points == NULL) - stroke->points = MEM_callocN(sizeof(bGPDspoint) * count, "gp_stroke_points"); - else - stroke->points = MEM_recallocN(stroke->points, sizeof(bGPDspoint) * (stroke->totpoints + count)); - + stroke->points = MEM_recallocN_id(stroke->points, + sizeof(bGPDspoint) * (stroke->totpoints + count), + "gp_stroke_points"); stroke->totpoints += count; } } diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index d1cfb01abfb..72985f7b6e6 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -402,7 +402,6 @@ PointerRNA rna_pointer_inherit_refine(struct PointerRNA *ptr, struct StructRNA * /* Functions */ int rna_parameter_size(struct PropertyRNA *parm); -int rna_parameter_size_alloc(struct PropertyRNA *parm); struct Mesh *rna_Main_meshes_new_from_object( struct Main *bmain, struct ReportList *reports, struct Scene *sce, diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 51aad755e77..35d8a0fb433 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -37,7 +37,6 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" -#include "BLI_array.h" #include "BLI_math_base.h" #include "BLI_math_rotation.h" #include "BLI_utildefines.h" diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c index 898825820ac..11f0e48012b 100644 --- a/source/blender/makesrna/intern/rna_meta.c +++ b/source/blender/makesrna/intern/rna_meta.c @@ -164,6 +164,22 @@ static int rna_Meta_is_editmode_get(PointerRNA *ptr) return (mb->editelems != NULL); } +static char *rna_MetaElement_path(PointerRNA *ptr) +{ + MetaBall *mb = ptr->id.data; + MetaElem *ml = ptr->data; + int index = -1; + + if (mb->editelems) + index = BLI_findindex(mb->editelems, ml); + if (index == -1) + index = BLI_findindex(&mb->elems, ml); + if (index == -1) + return NULL; + + return BLI_sprintfN("elements[%d]", index); +} + #else static void rna_def_metaelement(BlenderRNA *brna) @@ -174,6 +190,7 @@ static void rna_def_metaelement(BlenderRNA *brna) srna = RNA_def_struct(brna, "MetaElement", NULL); RNA_def_struct_sdna(srna, "MetaElem"); RNA_def_struct_ui_text(srna, "Meta Element", "Blobby element in a Metaball datablock"); + RNA_def_struct_path_func(srna, "rna_MetaElement_path"); RNA_def_struct_ui_icon(srna, ICON_OUTLINER_DATA_META); /* enums */ diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index f4f557e1985..1c764d396f7 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -43,7 +43,6 @@ #include "BLF_translation.h" #include "BKE_animsys.h" -#include "BKE_bmesh.h" /* For BevelModifierData */ #include "BKE_dynamicpaint.h" #include "BKE_multires.h" #include "BKE_smoke.h" /* For smokeModifier_free & smokeModifier_createType */ @@ -2315,10 +2314,10 @@ static void rna_def_modifier_bevel(BlenderRNA *brna) static EnumPropertyItem prop_limit_method_items[] = { {0, "NONE", 0, "None", "Bevel the entire mesh by a constant amount"}, - {BME_BEVEL_ANGLE, "ANGLE", 0, "Angle", "Only bevel edges with sharp enough angles between faces"}, - {BME_BEVEL_WEIGHT, "WEIGHT", 0, "Weight", + {MOD_BEVEL_ANGLE, "ANGLE", 0, "Angle", "Only bevel edges with sharp enough angles between faces"}, + {MOD_BEVEL_WEIGHT, "WEIGHT", 0, "Weight", "Use bevel weights to determine how much bevel is applied in edge mode"}, - {BME_BEVEL_VGROUP, "VGROUP", 0, "Vertex Group", + {MOD_BEVEL_VGROUP, "VGROUP", 0, "Vertex Group", "Use vertex group weights to determine how much bevel is applied in vertex mode"}, {0, NULL, 0, NULL, NULL} }; @@ -2326,8 +2325,8 @@ static void rna_def_modifier_bevel(BlenderRNA *brna) /* TO BE DEPRECATED */ static EnumPropertyItem prop_edge_weight_method_items[] = { {0, "AVERAGE", 0, "Average", ""}, - {BME_BEVEL_EMIN, "SHARPEST", 0, "Sharpest", ""}, - {BME_BEVEL_EMAX, "LARGEST", 0, "Largest", ""}, + {MOD_BEVEL_EMIN, "SHARPEST", 0, "Sharpest", ""}, + {MOD_BEVEL_EMAX, "LARGEST", 0, "Largest", ""}, {0, NULL, 0, NULL, NULL} }; @@ -2350,7 +2349,7 @@ static void rna_def_modifier_bevel(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop = RNA_def_property(srna, "use_only_vertices", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flags", BME_BEVEL_VERT); + RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_BEVEL_VERT); RNA_def_property_ui_text(prop, "Only Vertices", "Bevel verts/corners, not edges"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); @@ -2367,22 +2366,14 @@ static void rna_def_modifier_bevel(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Edge Weight Method", "What edge weight to use for weighting a vertex"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); -#if 1 /* expose as radians */ prop = RNA_def_property(srna, "angle_limit", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_funcs(prop, "rna_BevelModifier_angle_limit_get", "rna_BevelModifier_angle_limit_set", NULL); RNA_def_property_range(prop, 0, DEG2RAD(180)); RNA_def_property_ui_range(prop, 0, DEG2RAD(180), 100, 2); -#else - prop = RNA_def_property(srna, "angle_limit", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "bevel_angle"); - RNA_def_property_range(prop, 0, 180); - RNA_def_property_ui_range(prop, 0, 180, 100, 2); -#endif RNA_def_property_ui_text(prop, "Angle", "Angle above which to bevel edges"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); -#ifdef USE_BM_BEVEL_OP_AS_MOD prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "defgrp_name"); RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name"); @@ -2390,11 +2381,9 @@ static void rna_def_modifier_bevel(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop = RNA_def_property(srna, "use_clamp_overlap", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "flags", BME_BEVEL_OVERLAP_OK); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flags", MOD_BEVEL_OVERLAP_OK); RNA_def_property_ui_text(prop, "Clamp Overlap", "Clamp the width to avoid overlap"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); -#endif - } static void rna_def_modifier_shrinkwrap(BlenderRNA *brna) @@ -2607,11 +2596,6 @@ static void rna_def_modifier_simpledeform(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK); RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); - prop = RNA_def_property(srna, "use_relative", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "originOpts", MOD_SIMPLEDEFORM_ORIGIN_LOCAL); - RNA_def_property_ui_text(prop, "Relative", "Set the origin of deform space to be relative to the object"); - RNA_def_property_update(prop, 0, "rna_Modifier_update"); - prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); RNA_def_property_ui_range(prop, -10, 10, 1, 3); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 0c31f042f93..535c279c02f 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3509,6 +3509,42 @@ static void def_sh_tex_coord(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } +static void def_sh_vect_transform(StructRNA *srna) +{ + static EnumPropertyItem prop_vect_type_items[] = { + {SHD_VECT_TRANSFORM_TYPE_VECTOR, "VECTOR", 0, "Vector", ""}, + {SHD_VECT_TRANSFORM_TYPE_POINT, "POINT", 0, "Point", ""}, + {SHD_VECT_TRANSFORM_TYPE_NORMAL, "NORMAL", 0, "Normal", ""}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem prop_vect_space_items[] = { + {SHD_VECT_TRANSFORM_SPACE_WORLD, "WORLD", 0, "World", ""}, + {SHD_VECT_TRANSFORM_SPACE_OBJECT, "OBJECT", 0, "Object", ""}, + {SHD_VECT_TRANSFORM_SPACE_CAMERA, "CAMERA", 0, "Camera", ""}, + {0, NULL, 0, NULL, NULL} + }; + + PropertyRNA *prop; + + RNA_def_struct_sdna_from(srna, "NodeShaderVectTransform", "storage"); + + prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, prop_vect_type_items); + RNA_def_property_ui_text(prop, "Type", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); + + prop = RNA_def_property(srna, "convert_from", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, prop_vect_space_items); + RNA_def_property_ui_text(prop, "Convert From", "Space to convert from"); + RNA_def_property_update(prop, 0, "rna_Node_update"); + + prop = RNA_def_property(srna, "convert_to", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, prop_vect_space_items); + RNA_def_property_ui_text(prop, "Convert To", "Space to convert to"); + RNA_def_property_update(prop, 0, "rna_Node_update"); +} + static void def_sh_tex_wireframe(StructRNA *srna) { PropertyRNA *prop; @@ -4032,7 +4068,7 @@ static void def_cmp_render_layers(StructRNA *srna) RNA_def_property_pointer_sdna(prop, NULL, "id"); RNA_def_property_pointer_funcs(prop, NULL, "rna_Node_scene_set", NULL, NULL); RNA_def_property_struct_type(prop, "Scene"); - RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK); + RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Scene", ""); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index a4e532660f1..25ca231e58d 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -259,6 +259,21 @@ static void rna_Mesh_assign_verts_to_group(Object *ob, bDeformGroup *group, int } #endif +/* don't call inside a loop */ +static int dm_tessface_to_poly_index(DerivedMesh *dm, int tessface_index) +{ + if (tessface_index != ORIGINDEX_NONE) { + /* double lookup */ + const int *index_mf_to_mpoly; + if ((index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX))) { + const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + return DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, tessface_index); + } + } + + return ORIGINDEX_NONE; +} + /* BMESH_TODO, return polygon index, not tessface */ static void rna_Object_ray_cast(Object *ob, ReportList *reports, float ray_start[3], float ray_end[3], float r_location[3], float r_normal[3], int *index) @@ -291,7 +306,7 @@ static void rna_Object_ray_cast(Object *ob, ReportList *reports, float ray_start if (hit.dist <= dist) { copy_v3_v3(r_location, hit.co); copy_v3_v3(r_normal, hit.no); - *index = hit.index; + *index = dm_tessface_to_poly_index(ob->derivedFinal, hit.index); return; } } @@ -330,7 +345,7 @@ static void rna_Object_closest_point_on_mesh(Object *ob, ReportList *reports, fl if (BLI_bvhtree_find_nearest(treeData.tree, point_co, &nearest, treeData.nearest_callback, &treeData) != -1) { copy_v3_v3(n_location, nearest.co); copy_v3_v3(n_normal, nearest.no); - *index = nearest.index; + *index = dm_tessface_to_poly_index(ob->derivedFinal, nearest.index); return; } } diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 06d8f4faf04..1d2aa08e7cd 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -184,6 +184,7 @@ static void rna_Cache_idname_change(Main *UNUSED(bmain), Scene *UNUSED(scene), P BKE_ptcache_load_external(pid); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_main_add_notifier(NC_OBJECT | ND_POINTCACHE, ob); } else { for (pid = pidlist.first; pid; pid = pid->next) { diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 64b4e019c27..82cdfcdd631 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -570,6 +570,9 @@ static void rna_def_render_pass(BlenderRNA *brna) {SCE_PASS_TRANSM_DIRECT, "TRANSMISSION_DIRECT", 0, "Transmission Direct", ""}, {SCE_PASS_TRANSM_INDIRECT, "TRANSMISSION_INDIRECT", 0, "Transmission Indirect", ""}, {SCE_PASS_TRANSM_COLOR, "TRANSMISSION_COLOR", 0, "Transmission Color", ""}, + {SCE_PASS_SUBSURFACE_DIRECT, "SUBSURFACE_DIRECT", 0, "Subsurface Direct", ""}, + {SCE_PASS_SUBSURFACE_INDIRECT, "SUBSURFACE_INDIRECT", 0, "Subsurface Indirect", ""}, + {SCE_PASS_SUBSURFACE_COLOR, "SUBSURFACE_COLOR", 0, "Subsurface Color", ""}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index d6dc2162720..83dbd79024e 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2555,6 +2555,24 @@ void rna_def_render_layer_common(StructRNA *srna, int scene) RNA_def_property_ui_text(prop, "Transmission Color", "Deliver transmission color pass"); if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update"); else RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop = RNA_def_property(srna, "use_pass_subsurface_direct", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_SUBSURFACE_DIRECT); + RNA_def_property_ui_text(prop, "Subsurface Direct", "Deliver subsurface direct pass"); + if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update"); + else RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop = RNA_def_property(srna, "use_pass_subsurface_indirect", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_SUBSURFACE_INDIRECT); + RNA_def_property_ui_text(prop, "Subsurface Indirect", "Deliver subsurface indirect pass"); + if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update"); + else RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop = RNA_def_property(srna, "use_pass_subsurface_color", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_SUBSURFACE_COLOR); + RNA_def_property_ui_text(prop, "Subsurface Color", "Deliver subsurface color pass"); + if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update"); + else RNA_def_property_clear_flag(prop, PROP_EDITABLE); } static void rna_def_freestyle_linesets(BlenderRNA *brna, PropertyRNA *cprop) @@ -3126,8 +3144,15 @@ static void rna_def_scene_game_data(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem vsync_items[] = { + {VSYNC_OFF, "OFF", 0, "Off", "Disable vsync"}, + {VSYNC_ON, "ON", 0, "On", "Enable vsync"}, + {VSYNC_ADAPTIVE, "ADAPTIVE", 0, "Adaptive", "Enable adaptive vsync (if supported)"}, + {0, NULL, 0, NULL, NULL} + }; + static EnumPropertyItem storage_items[] = { - {RAS_STORE_AUTO, "AUTO", 0, "Auto Select", "Chooses the best supported mode"}, + {RAS_STORE_AUTO, "AUTO", 0, "Auto Select", "Choose the best supported mode"}, {RAS_STORE_IMMEDIATE, "IMMEDIATE", 0, "Immediate Mode", "Slowest performance, requires OpenGL (any version)"}, {RAS_STORE_VA, "VERTEX_ARRAY", 0, "Vertex Arrays", "Better performance, requires at least OpenGL 1.1"}, #if 0 /* XXX VBOS are currently disabled since they cannot beat vertex array with display lists in performance. */ @@ -3152,6 +3177,11 @@ static void rna_def_scene_game_data(BlenderRNA *brna) RNA_def_property_range(prop, 4, 10000); RNA_def_property_ui_text(prop, "Resolution Y", "Number of vertical pixels in the screen"); RNA_def_property_update(prop, NC_SCENE, NULL); + + prop = RNA_def_property(srna, "vsync", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "vsync"); + RNA_def_property_enum_items(prop, vsync_items); + RNA_def_property_ui_text(prop, "Vsync", "Change vsync settings"); prop = RNA_def_property(srna, "samples", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "aasamples"); diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 3713cb817f5..b48f434abe9 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -42,7 +42,6 @@ #include "BKE_deform.h" #include "BKE_modifier.h" #include "BKE_mesh.h" -#include "BKE_bmesh.h" /* only for defines */ #include "MOD_util.h" @@ -91,8 +90,6 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) return dataMask; } -#ifdef USE_BM_BEVEL_OP_AS_MOD - /* * This calls the new bevel code (added since 2.64) */ @@ -110,13 +107,13 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob, MDeformVert *dvert = NULL; BevelModifierData *bmd = (BevelModifierData *) md; const float threshold = cosf((bmd->bevel_angle + 0.00001f) * (float)M_PI / 180.0f); - const bool vertex_only = (bmd->flags & BME_BEVEL_VERT) != 0; - const bool do_clamp = !(bmd->flags & BME_BEVEL_OVERLAP_OK); + const bool vertex_only = (bmd->flags & MOD_BEVEL_VERT) != 0; + const bool do_clamp = !(bmd->flags & MOD_BEVEL_OVERLAP_OK); bm = DM_to_bmesh(dm, true); if (vertex_only) { - if ((bmd->lim_flags & BME_BEVEL_VGROUP) && bmd->defgrp_name[0]) { + if ((bmd->lim_flags & MOD_BEVEL_VGROUP) && bmd->defgrp_name[0]) { modifier_get_vgroup(ob, dm, bmd->defgrp_name, &dvert, &vgroup); } BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) { @@ -131,7 +128,7 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob, BM_elem_flag_enable(v, BM_ELEM_TAG); } } - else if (bmd->lim_flags & BME_BEVEL_ANGLE) { + else if (bmd->lim_flags & MOD_BEVEL_ANGLE) { BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { /* check for 1 edge having 2 face users */ BMLoop *l_a, *l_b; @@ -148,7 +145,7 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob, /* crummy, is there a way just to operator on all? - campbell */ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { if (BM_edge_is_manifold(e)) { - if (bmd->lim_flags & BME_BEVEL_WEIGHT) { + if (bmd->lim_flags & MOD_BEVEL_WEIGHT) { weight = BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT); if (weight == 0.0f) continue; @@ -161,7 +158,7 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob, } BM_mesh_bevel(bm, bmd->value, bmd->res, - vertex_only, bmd->lim_flags & BME_BEVEL_WEIGHT, do_clamp, + vertex_only, bmd->lim_flags & MOD_BEVEL_WEIGHT, do_clamp, dvert, vgroup); result = CDDM_from_bmesh(bm, TRUE); @@ -176,46 +173,6 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob, return result; } - -#else /* from trunk, see note above */ - -static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), - DerivedMesh *derivedData, - ModifierApplyFlag UNUSED(flag)) -{ - DerivedMesh *result; - BMesh *bm; - - /*bDeformGroup *def;*/ - int /*i,*/ options, defgrp_index = -1; - BevelModifierData *bmd = (BevelModifierData *) md; - - options = bmd->flags | bmd->val_flags | bmd->lim_flags | bmd->e_flags; - -#if 0 - if ((options & BME_BEVEL_VWEIGHT) && bmd->defgrp_name[0]) { - defgrp_index = defgroup_name_index(ob, bmd->defgrp_name); - if (defgrp_index == -1) { - options &= ~BME_BEVEL_VWEIGHT; - } - } -#endif - - bm = DM_to_bmesh(derivedData); - BME_bevel(bm, bmd->value, bmd->res, options, defgrp_index, DEG2RADF(bmd->bevel_angle), NULL); - result = CDDM_from_bmesh(bm, TRUE); - BM_mesh_free(bm); - - /* until we allow for dirty normal flag, always calc, - * note: calculating on the CDDM is faster then the BMesh equivalent */ - result->dirty |= DM_DIRTY_NORMALS; - - return result; -} - -#endif - - ModifierTypeInfo modifierType_Bevel = { /* name */ "Bevel", /* structName */ "BevelModifierData", diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c index 02ec6108733..98fab9c06ff 100644 --- a/source/blender/modifiers/intern/MOD_boolean_util.c +++ b/source/blender/modifiers/intern/MOD_boolean_util.c @@ -519,8 +519,8 @@ static DerivedMesh *NewBooleanDerivedMesh_intern( DerivedMesh *result = NULL; - if (dm == NULL || dm_select == NULL) return 0; - if (!dm->getNumTessFaces(dm) || !dm_select->getNumTessFaces(dm_select)) return 0; + if (dm == NULL || dm_select == NULL) return NULL; + if (!dm->getNumTessFaces(dm) || !dm_select->getNumTessFaces(dm_select)) return NULL; /* we map the final object back into ob's local coordinate space. For this * we need to compute the inverse transform from global to ob (inv_mat), diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c index ec3212d4cbb..81f139e48ce 100644 --- a/source/blender/modifiers/intern/MOD_cloth.c +++ b/source/blender/modifiers/intern/MOD_cloth.c @@ -72,7 +72,6 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, { DerivedMesh *dm; ClothModifierData *clmd = (ClothModifierData *) md; - DerivedMesh *result = NULL; /* check for alloc failing */ if (!clmd->sim_parms || !clmd->coll_parms) { @@ -92,11 +91,6 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, clothModifier_do(clmd, md->scene, ob, dm, vertexCos); - if (result) { - result->getVertCos(result, vertexCos); - result->release(result); - } - dm->release(dm); } diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index 6c75f1d4be9..9fdb40e71dc 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -127,6 +127,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } calc_face_normal = true; break; + default: + return dm; } if (dmd->face_count <= 3) { diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c index e37fc56d08c..b3d3e65e120 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -44,7 +44,6 @@ #include "BKE_modifier.h" #include "bmesh.h" -#include "tools/bmesh_edgesplit.h" #include "DNA_object_types.h" @@ -91,7 +90,7 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd) } } - BM_mesh_edgesplit(bm, FALSE, TRUE); + BM_mesh_edgesplit(bm, false, true, false); /* BM_mesh_validate(bm); */ /* for troubleshooting */ diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c index 1abe1e97a23..3843ee6f535 100644 --- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c +++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c @@ -366,7 +366,7 @@ static void init_laplacian_matrix(LaplacianSystem *sys) v1 = sys->vertexCos[idv1]; v2 = sys->vertexCos[idv2]; v3 = sys->vertexCos[idv3]; - v4 = has_4_vert ? sys->vertexCos[idv4] : 0; + v4 = has_4_vert ? sys->vertexCos[idv4] : NULL; if (has_4_vert) { areaf = area_quad_v3(v1, v2, v3, sys->vertexCos[sys->mfaces[i].v4]); diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c index d50e69217f6..1b9fcd9f34e 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.c @@ -37,7 +37,6 @@ #include "DNA_object_types.h" #include "BLI_math.h" -#include "BLI_array.h" #include "BKE_cdderivedmesh.h" #include "BKE_mesh.h" diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index 7c9a88622ed..40a4d5e0986 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -318,8 +318,8 @@ static DerivedMesh *generate_ocean_geometry(OceanModifierData *omd) /* create vertices */ #pragma omp parallel for private(x, y) if (rx > OMP_MIN_RES) - for (y = 0; y < res_y + 1; y++) { - for (x = 0; x < res_x + 1; x++) { + for (y = 0; y <= res_y; y++) { + for (x = 0; x <= res_x; x++) { const int i = y * (res_x + 1) + x; float *co = mverts[i].co; co[0] = ox + (x * sx); @@ -426,6 +426,11 @@ static DerivedMesh *doOcean(ModifierData *md, Object *ob, const float size_co_inv = 1.0f / (omd->size * omd->spatial_size); + /* can happen in when size is small, avoid bad array lookups later and quit now */ + if (!finite(size_co_inv)) { + return derivedData; + } + /* update modifier */ if (omd->refresh & MOD_OCEAN_REFRESH_ADD) omd->ocean = BKE_add_ocean(); @@ -531,7 +536,7 @@ static DerivedMesh *doOcean(ModifierData *md, Object *ob, } } - #undef OCEAN_CO +#undef OCEAN_CO return dm; } @@ -552,8 +557,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, { DerivedMesh *result; - CDDM_calc_normals(derivedData); - result = doOcean(md, ob, derivedData, 0); if (result != derivedData) diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index 588c98c9827..d260312fe3d 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -166,14 +166,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object /* Calculate matrixs do convert between coordinate spaces */ if (smd->origin) { transf = &tmp_transf; - - if (smd->originOpts & MOD_SIMPLEDEFORM_ORIGIN_LOCAL) { - space_transform_from_matrixs(transf, ob->obmat, smd->origin->obmat); - } - else { - copy_m4_m4(transf->local2target, smd->origin->obmat); - invert_m4_m4(transf->target2local, transf->local2target); - } + space_transform_from_matrixs(transf, ob->obmat, smd->origin->obmat); } /* Setup vars, @@ -252,7 +245,6 @@ static void initData(ModifierData *md) SimpleDeformModifierData *smd = (SimpleDeformModifierData *) md; smd->mode = MOD_SIMPLEDEFORM_MODE_TWIST; - smd->originOpts = MOD_SIMPLEDEFORM_ORIGIN_LOCAL; smd->axis = 0; smd->origin = NULL; @@ -269,9 +261,8 @@ static void copyData(ModifierData *md, ModifierData *target) tsmd->mode = smd->mode; tsmd->axis = smd->axis; tsmd->origin = smd->origin; - tsmd->originOpts = smd->originOpts; tsmd->factor = smd->factor; - memcpy(tsmd->limit, smd->limit, sizeof(tsmd->limit)); + copy_v2_v2(tsmd->limit, smd->limit); BLI_strncpy(tsmd->vgroup_name, smd->vgroup_name, sizeof(tsmd->vgroup_name)); } diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index daf0e5c9dc3..83ac9f34df3 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -411,7 +411,7 @@ static Frame **collect_hull_frames(int v, SkinNode *frames, int nbr, i; (*tothullframe) = emap[v].count; - hull_frames = MEM_callocN(sizeof(Frame * *) * (*tothullframe), + hull_frames = MEM_callocN(sizeof(Frame *) * (*tothullframe), "hull_from_frames.hull_frames"); i = 0; for (nbr = 0; nbr < emap[v].count; nbr++) { @@ -690,7 +690,7 @@ static void build_emats_stack(BLI_Stack *stack, int *visited_e, EMat *emat, /* Add neighbors to stack */ for (i = 0; i < emap[v].count; i++) { /* Add neighbors to stack */ - memcpy(stack_elem.mat, emat[e].mat, sizeof(float) * 3 * 3); + copy_m3_m3(stack_elem.mat, emat[e].mat); stack_elem.e = emap[v].indices[i]; stack_elem.parent_v = v; BLI_stack_push(stack, &stack_elem); @@ -1039,7 +1039,7 @@ static int isect_ray_poly(const float ray_start[3], v_first = v; else if (v_prev != v_first) { float dist; - int curhit; + bool curhit; curhit = isect_ray_tri_v3(ray_start, ray_dir, v_first->co, v_prev->co, v->co, @@ -1751,7 +1751,7 @@ static void skin_set_orig_indices(DerivedMesh *dm) totpoly = dm->getNumPolys(dm); orig = CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, - CD_CALLOC, 0, totpoly); + CD_CALLOC, NULL, totpoly); for (i = 0; i < totpoly; i++) orig[i] = ORIGINDEX_NONE; } diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c index 3429acdcea4..4fac201377a 100644 --- a/source/blender/modifiers/intern/MOD_warp.c +++ b/source/blender/modifiers/intern/MOD_warp.c @@ -368,8 +368,8 @@ ModifierTypeInfo modifierType_Warp = { /* deformMatrices */ NULL, /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, - /* applyModifier */ 0, - /* applyModifierEM */ 0, + /* applyModifier */ NULL, + /* applyModifierEM */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, /* freeData */ freeData, diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c index 8ad9e26f788..e2267addd53 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.c +++ b/source/blender/modifiers/intern/MOD_weightvg_util.c @@ -135,6 +135,7 @@ void weightvg_do_mask(int num, const int *indices, float *org_w, const float *ne /* See mapping note below... */ MappingInfoModifierData t_map; float (*v_co)[3]; + int numVerts = dm->getNumVerts(dm); /* Use new generic get_texture_coords, but do not modify our DNA struct for it... * XXX Why use a ModifierData stuff here ? Why not a simple, generic struct for parameters ? @@ -145,9 +146,9 @@ void weightvg_do_mask(int num, const int *indices, float *org_w, const float *ne t_map.map_object = tex_map_object; BLI_strncpy(t_map.uvlayer_name, tex_uvlayer_name, sizeof(t_map.uvlayer_name)); t_map.texmapping = tex_mapping; - v_co = MEM_mallocN(sizeof(*v_co) * num, "WeightVG Modifier, TEX mode, v_co"); + v_co = MEM_mallocN(sizeof(*v_co) * numVerts, "WeightVG Modifier, TEX mode, v_co"); dm->getVertCos(dm, v_co); - tex_co = MEM_callocN(sizeof(*tex_co) * num, "WeightVG Modifier, TEX mode, tex_co"); + tex_co = MEM_callocN(sizeof(*tex_co) * numVerts, "WeightVG Modifier, TEX mode, tex_co"); get_texture_coords(&t_map, ob, dm, v_co, tex_co, num); MEM_freeN(v_co); diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c index 959e4d4f59d..c8da0eb6de7 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -253,7 +253,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der RNG *rng = NULL; if (wmd->falloff_type == MOD_WVG_MAPPING_RANDOM) - rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name)); + rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name + 2)); weightvg_do_map(numVerts, new_w, wmd->falloff_type, wmd->cmap_curve, rng); diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c index f0e9a26f10a..63267538528 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -216,7 +216,7 @@ static void do_map(Object *ob, float *weights, const int nidx, const float min_d RNG *rng = NULL; if (mode == MOD_WVG_MAPPING_RANDOM) - rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name)); + rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name + 2)); weightvg_do_map(nidx, weights, mode, NULL, rng); diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index cc1a5f8cee9..64261246e3d 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -140,13 +140,16 @@ set(SRC shader/nodes/node_shader_output.c shader/nodes/node_shader_rgb.c shader/nodes/node_shader_sepcombRGB.c + shader/nodes/node_shader_sepcombHSV.c shader/nodes/node_shader_squeeze.c shader/nodes/node_shader_texture.c shader/nodes/node_shader_valToRgb.c shader/nodes/node_shader_value.c shader/nodes/node_shader_wireframe.c shader/nodes/node_shader_wavelength.c + shader/nodes/node_shader_blackbody.c shader/nodes/node_shader_vectMath.c + shader/nodes/node_shader_vectTransform.c shader/nodes/node_shader_add_shader.c shader/nodes/node_shader_ambient_occlusion.c shader/nodes/node_shader_attribute.c diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h index edb0ba6f475..ec39d81618d 100644 --- a/source/blender/nodes/NOD_shader.h +++ b/source/blender/nodes/NOD_shader.h @@ -70,6 +70,8 @@ void register_node_type_sh_material_ext(void); void register_node_type_sh_invert(void); void register_node_type_sh_seprgb(void); void register_node_type_sh_combrgb(void); +void register_node_type_sh_sephsv(void); +void register_node_type_sh_combhsv(void); void register_node_type_sh_hue_sat(void); void register_node_type_sh_tex_brick(void); @@ -81,6 +83,7 @@ void register_node_type_sh_object_info(void); void register_node_type_sh_fresnel(void); void register_node_type_sh_wireframe(void); void register_node_type_sh_wavelength(void); +void register_node_type_sh_blackbody(void); void register_node_type_sh_layer_weight(void); void register_node_type_sh_tex_coord(void); void register_node_type_sh_particle_info(void); @@ -88,6 +91,7 @@ void register_node_type_sh_hair_info(void); void register_node_type_sh_script(void); void register_node_type_sh_normal_map(void); void register_node_type_sh_tangent(void); +void register_node_type_sh_vect_transform(void); void register_node_type_sh_ambient_occlusion(void); void register_node_type_sh_background(void); diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 69f2a0ae955..0b526fcde0e 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -97,6 +97,7 @@ DefNode( ShaderNode, SH_NODE_PARTICLE_INFO, 0, "PA DefNode( ShaderNode, SH_NODE_HAIR_INFO, 0, "HAIR_INFO", HairInfo, "Hair Info", "" ) DefNode( ShaderNode, SH_NODE_WIREFRAME, def_sh_tex_wireframe, "WIREFRAME", Wireframe, "Wireframe", "" ) DefNode( ShaderNode, SH_NODE_WAVELENGTH, 0, "WAVELENGTH", Wavelength, "Wavelength", "" ) +DefNode( ShaderNode, SH_NODE_BLACKBODY, 0, "BLACKBODY", Blackbody, "Blackbody", "" ) DefNode( ShaderNode, SH_NODE_BUMP, def_sh_bump, "BUMP", Bump, "Bump", "" ) DefNode( ShaderNode, SH_NODE_NORMAL_MAP, def_sh_normal_map, "NORMAL_MAP", NormalMap, "Normal Map", "" ) DefNode( ShaderNode, SH_NODE_TANGENT, def_sh_tangent, "TANGENT", Tangent, "Tangent", "" ) @@ -113,6 +114,9 @@ DefNode( ShaderNode, SH_NODE_TEX_VORONOI, def_sh_tex_voronoi, "TE DefNode( ShaderNode, SH_NODE_TEX_CHECKER, def_sh_tex_checker, "TEX_CHECKER", TexChecker, "Checker Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_BRICK, def_sh_tex_brick, "TEX_BRICK", TexBrick, "Brick Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_COORD, def_sh_tex_coord, "TEX_COORD", TexCoord, "Texture Coordinate","" ) +DefNode( ShaderNode, SH_NODE_VECT_TRANSFORM, def_sh_vect_transform, "VECT_TRANSFORM", VectorTransform, "Vector Transform", "" ) +DefNode( ShaderNode, SH_NODE_SEPHSV, 0, "SEPHSV", SeparateHSV, "Separate HSV", "" ) +DefNode( ShaderNode, SH_NODE_COMBHSV, 0, "COMBHSV", CombineHSV, "Combine HSV", "" ) DefNode( CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" ) DefNode( CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" ) diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c index 41f1f81e048..d073abf112a 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.c +++ b/source/blender/nodes/composite/nodes/node_composite_image.c @@ -72,6 +72,9 @@ static bNodeSocketTemplate cmp_node_rlayers_out[] = { { SOCK_RGBA, 0, N_("Transmission Direct"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_RGBA, 0, N_("Transmission Indirect"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_RGBA, 0, N_("Transmission Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, N_("Subsurface Direct"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, N_("Subsurface Indirect"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 0, N_("Subsurface Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { -1, 0, "" } }; @@ -152,6 +155,13 @@ static void cmp_node_image_add_render_pass_outputs(bNodeTree *ntree, bNode *node cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRANSM_INDIRECT, RRES_OUT_TRANSM_INDIRECT); if (passflag & SCE_PASS_TRANSM_COLOR) cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRANSM_COLOR, RRES_OUT_TRANSM_COLOR); + + if (passflag & SCE_PASS_SUBSURFACE_DIRECT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SUBSURFACE_DIRECT, RRES_OUT_SUBSURFACE_DIRECT); + if (passflag & SCE_PASS_SUBSURFACE_INDIRECT) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SUBSURFACE_INDIRECT, RRES_OUT_SUBSURFACE_INDIRECT); + if (passflag & SCE_PASS_SUBSURFACE_COLOR) + cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SUBSURFACE_COLOR, RRES_OUT_SUBSURFACE_COLOR); } static void cmp_node_image_add_multilayer_outputs(bNodeTree *ntree, bNode *node, RenderLayer *rl) @@ -373,7 +383,8 @@ void node_cmp_rlayers_force_hidden_passes(bNode *node) bNodeSocket *sock; /* must always have valid scene pointer */ - BLI_assert(scene != NULL); + if (!scene) + return; srl = BLI_findlink(&scene->r.layers, node->custom1); if (!srl) @@ -384,35 +395,38 @@ void node_cmp_rlayers_force_hidden_passes(bNode *node) for (sock = node->outputs.first; sock; sock = sock->next) sock->flag &= ~SOCK_UNAVAIL; - set_output_visible(node, passflag, RRES_OUT_IMAGE, SCE_PASS_COMBINED); - set_output_visible(node, passflag, RRES_OUT_ALPHA, SCE_PASS_COMBINED); - - set_output_visible(node, passflag, RRES_OUT_Z, SCE_PASS_Z); - set_output_visible(node, passflag, RRES_OUT_NORMAL, SCE_PASS_NORMAL); - set_output_visible(node, passflag, RRES_OUT_VEC, SCE_PASS_VECTOR); - set_output_visible(node, passflag, RRES_OUT_UV, SCE_PASS_UV); - set_output_visible(node, passflag, RRES_OUT_RGBA, SCE_PASS_RGBA); - set_output_visible(node, passflag, RRES_OUT_DIFF, SCE_PASS_DIFFUSE); - set_output_visible(node, passflag, RRES_OUT_SPEC, SCE_PASS_SPEC); - set_output_visible(node, passflag, RRES_OUT_SHADOW, SCE_PASS_SHADOW); - set_output_visible(node, passflag, RRES_OUT_AO, SCE_PASS_AO); - set_output_visible(node, passflag, RRES_OUT_REFLECT, SCE_PASS_REFLECT); - set_output_visible(node, passflag, RRES_OUT_REFRACT, SCE_PASS_REFRACT); - set_output_visible(node, passflag, RRES_OUT_INDIRECT, SCE_PASS_INDIRECT); - set_output_visible(node, passflag, RRES_OUT_INDEXOB, SCE_PASS_INDEXOB); - set_output_visible(node, passflag, RRES_OUT_INDEXMA, SCE_PASS_INDEXMA); - set_output_visible(node, passflag, RRES_OUT_MIST, SCE_PASS_MIST); - set_output_visible(node, passflag, RRES_OUT_EMIT, SCE_PASS_EMIT); - set_output_visible(node, passflag, RRES_OUT_ENV, SCE_PASS_ENVIRONMENT); - set_output_visible(node, passflag, RRES_OUT_DIFF_DIRECT, SCE_PASS_DIFFUSE_DIRECT); - set_output_visible(node, passflag, RRES_OUT_DIFF_INDIRECT, SCE_PASS_DIFFUSE_INDIRECT); - set_output_visible(node, passflag, RRES_OUT_DIFF_COLOR, SCE_PASS_DIFFUSE_COLOR); - set_output_visible(node, passflag, RRES_OUT_GLOSSY_DIRECT, SCE_PASS_GLOSSY_DIRECT); - set_output_visible(node, passflag, RRES_OUT_GLOSSY_INDIRECT, SCE_PASS_GLOSSY_INDIRECT); - set_output_visible(node, passflag, RRES_OUT_GLOSSY_COLOR, SCE_PASS_GLOSSY_COLOR); - set_output_visible(node, passflag, RRES_OUT_TRANSM_DIRECT, SCE_PASS_TRANSM_DIRECT); - set_output_visible(node, passflag, RRES_OUT_TRANSM_INDIRECT, SCE_PASS_TRANSM_INDIRECT); - set_output_visible(node, passflag, RRES_OUT_TRANSM_COLOR, SCE_PASS_TRANSM_COLOR); + set_output_visible(node, passflag, RRES_OUT_IMAGE, SCE_PASS_COMBINED); + set_output_visible(node, passflag, RRES_OUT_ALPHA, SCE_PASS_COMBINED); + + set_output_visible(node, passflag, RRES_OUT_Z, SCE_PASS_Z); + set_output_visible(node, passflag, RRES_OUT_NORMAL, SCE_PASS_NORMAL); + set_output_visible(node, passflag, RRES_OUT_VEC, SCE_PASS_VECTOR); + set_output_visible(node, passflag, RRES_OUT_UV, SCE_PASS_UV); + set_output_visible(node, passflag, RRES_OUT_RGBA, SCE_PASS_RGBA); + set_output_visible(node, passflag, RRES_OUT_DIFF, SCE_PASS_DIFFUSE); + set_output_visible(node, passflag, RRES_OUT_SPEC, SCE_PASS_SPEC); + set_output_visible(node, passflag, RRES_OUT_SHADOW, SCE_PASS_SHADOW); + set_output_visible(node, passflag, RRES_OUT_AO, SCE_PASS_AO); + set_output_visible(node, passflag, RRES_OUT_REFLECT, SCE_PASS_REFLECT); + set_output_visible(node, passflag, RRES_OUT_REFRACT, SCE_PASS_REFRACT); + set_output_visible(node, passflag, RRES_OUT_INDIRECT, SCE_PASS_INDIRECT); + set_output_visible(node, passflag, RRES_OUT_INDEXOB, SCE_PASS_INDEXOB); + set_output_visible(node, passflag, RRES_OUT_INDEXMA, SCE_PASS_INDEXMA); + set_output_visible(node, passflag, RRES_OUT_MIST, SCE_PASS_MIST); + set_output_visible(node, passflag, RRES_OUT_EMIT, SCE_PASS_EMIT); + set_output_visible(node, passflag, RRES_OUT_ENV, SCE_PASS_ENVIRONMENT); + set_output_visible(node, passflag, RRES_OUT_DIFF_DIRECT, SCE_PASS_DIFFUSE_DIRECT); + set_output_visible(node, passflag, RRES_OUT_DIFF_INDIRECT, SCE_PASS_DIFFUSE_INDIRECT); + set_output_visible(node, passflag, RRES_OUT_DIFF_COLOR, SCE_PASS_DIFFUSE_COLOR); + set_output_visible(node, passflag, RRES_OUT_GLOSSY_DIRECT, SCE_PASS_GLOSSY_DIRECT); + set_output_visible(node, passflag, RRES_OUT_GLOSSY_INDIRECT, SCE_PASS_GLOSSY_INDIRECT); + set_output_visible(node, passflag, RRES_OUT_GLOSSY_COLOR, SCE_PASS_GLOSSY_COLOR); + set_output_visible(node, passflag, RRES_OUT_TRANSM_DIRECT, SCE_PASS_TRANSM_DIRECT); + set_output_visible(node, passflag, RRES_OUT_TRANSM_INDIRECT, SCE_PASS_TRANSM_INDIRECT); + set_output_visible(node, passflag, RRES_OUT_TRANSM_COLOR, SCE_PASS_TRANSM_COLOR); + set_output_visible(node, passflag, RRES_OUT_SUBSURFACE_DIRECT, SCE_PASS_SUBSURFACE_DIRECT); + set_output_visible(node, passflag, RRES_OUT_SUBSURFACE_INDIRECT, SCE_PASS_SUBSURFACE_INDIRECT); + set_output_visible(node, passflag, RRES_OUT_SUBSURFACE_COLOR, SCE_PASS_SUBSURFACE_COLOR); } static void node_composit_init_rlayers(const bContext *C, PointerRNA *ptr) diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index 36b27094cc4..a8133460628 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -267,6 +267,7 @@ static void node_reroute_inherit_type_recursive(bNodeTree *ntree, bNode *node) bNodeSocket *output = node->outputs.first; bNodeLink *link; int type = SOCK_FLOAT; + const char *type_idname = nodeStaticSocketType(type, PROP_NONE); /* XXX it would be a little bit more efficient to restrict actual updates * to rerout nodes connected to an updated node, but there's no reliable flag @@ -292,21 +293,37 @@ static void node_reroute_inherit_type_recursive(bNodeTree *ntree, bNode *node) } /* determine socket type from unambiguous input/output connection if possible */ - if (input->limit == 1 && input->link) + if (input->limit == 1 && input->link) { type = input->link->fromsock->type; - else if (output->limit == 1 && output->link) + type_idname = nodeStaticSocketType(type, PROP_NONE); + } + else if (output->limit == 1 && output->link) { type = output->link->tosock->type; + type_idname = nodeStaticSocketType(type, PROP_NONE); + } - /* arbitrary, could also test output->type, both are the same */ if (input->type != type) { - PointerRNA input_ptr, output_ptr; - /* same type for input/output */ - RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, input, &input_ptr); - RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, output, &output_ptr); - - RNA_enum_set(&input_ptr, "type", type); - RNA_enum_set(&output_ptr, "type", type); + bNodeSocket *ninput = nodeAddSocket(ntree, node, SOCK_IN, type_idname, "input", "Input"); + for (link = ntree->links.first; link; link = link->next) { + if (link->tosock == input) { + link->tosock = ninput; + ninput->link = link; + } + } + nodeRemoveSocket(ntree, node, input); } + + if (output->type != type) { + bNodeSocket *noutput = nodeAddSocket(ntree, node, SOCK_OUT, type_idname, "output", "Output"); + for (link = ntree->links.first; link; link = link->next) { + if (link->fromsock == output) { + link->fromsock = noutput; + } + } + nodeRemoveSocket(ntree, node, output); + } + + nodeUpdateInternalLinks(ntree, node); } /* Global update function for Reroute node types. diff --git a/source/blender/nodes/intern/node_exec.c b/source/blender/nodes/intern/node_exec.c index d18dddd4ff4..2b6318679e0 100644 --- a/source/blender/nodes/intern/node_exec.c +++ b/source/blender/nodes/intern/node_exec.c @@ -98,6 +98,10 @@ static void node_init_output_index(bNodeSocket *sock, int *index, ListBase *inte for (link = internal_links->first; link; link = link->next) { if (link->tosock == sock) { sock->stack_index = link->fromsock->stack_index; + /* set the link pointer to indicate that this socket + * should not overwrite the stack value! + */ + sock->link = link; break; } } diff --git a/source/blender/nodes/shader/nodes/node_shader_blackbody.c b/source/blender/nodes/shader/nodes/node_shader_blackbody.c new file mode 100644 index 00000000000..af89a959554 --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_blackbody.c @@ -0,0 +1,54 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../node_shader_util.h" + +/* **************** Blackbody ******************** */ +static bNodeSocketTemplate sh_node_blackbody_in[] = { + { SOCK_FLOAT, 1, N_("Temperature"), 1500.0f, 0.0f, 0.0f, 0.0f, 800.0f, 12000.0f}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate sh_node_blackbody_out[] = { + { SOCK_RGBA, 0, N_("Color")}, + { -1, 0, "" } +}; + +/* node type definition */ +void register_node_type_sh_blackbody(void) +{ + static bNodeType ntype; + + sh_node_type_base(&ntype, SH_NODE_BLACKBODY, "Blackbody", NODE_CLASS_CONVERTOR, 0); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_size_preset(&ntype, NODE_SIZE_MIDDLE); + node_type_socket_templates(&ntype, sh_node_blackbody_in, sh_node_blackbody_out); + node_type_init(&ntype, NULL); + node_type_storage(&ntype, "", NULL, NULL); + + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/shader/nodes/node_shader_light_path.c b/source/blender/nodes/shader/nodes/node_shader_light_path.c index 63713eb1e02..9d769b284b1 100644 --- a/source/blender/nodes/shader/nodes/node_shader_light_path.c +++ b/source/blender/nodes/shader/nodes/node_shader_light_path.c @@ -38,6 +38,7 @@ static bNodeSocketTemplate sh_node_light_path_out[] = { { SOCK_FLOAT, 0, N_("Is Reflection Ray"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 0, N_("Is Transmission Ray"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 0, N_("Ray Length"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 0, N_("Ray Depth"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { -1, 0, "" } }; diff --git a/source/blender/nodes/shader/nodes/node_shader_math.c b/source/blender/nodes/shader/nodes/node_shader_math.c index b0570a7d673..49a7de47fc3 100644 --- a/source/blender/nodes/shader/nodes/node_shader_math.c +++ b/source/blender/nodes/shader/nodes/node_shader_math.c @@ -232,6 +232,7 @@ static int gpu_shader_math(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED( case 13: case 15: case 16: + case 17: GPU_stack_link(mat, names[node->custom1], in, out); break; case 4: diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c b/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c new file mode 100644 index 00000000000..707e295241a --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c @@ -0,0 +1,80 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2013 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/shader/nodes/node_shader_sepcombHSV.c + * \ingroup shdnodes + */ + + +#include "node_shader_util.h" + +/* **************** SEPARATE HSV ******************** */ +static bNodeSocketTemplate sh_node_sephsv_in[] = { + { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f}, + { -1, 0, "" } +}; +static bNodeSocketTemplate sh_node_sephsv_out[] = { + { SOCK_FLOAT, 0, N_("H")}, + { SOCK_FLOAT, 0, N_("S")}, + { SOCK_FLOAT, 0, N_("V")}, + { -1, 0, "" } +}; + +void register_node_type_sh_sephsv(void) +{ + static bNodeType ntype; + + sh_node_type_base(&ntype, SH_NODE_SEPHSV, "Separate HSV", NODE_CLASS_CONVERTOR, 0); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_socket_templates(&ntype, sh_node_sephsv_in, sh_node_sephsv_out); + + nodeRegisterType(&ntype); +} + + +/* **************** COMBINE HSV ******************** */ +static bNodeSocketTemplate sh_node_combhsv_in[] = { + { SOCK_FLOAT, 1, N_("H"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED}, + { SOCK_FLOAT, 1, N_("S"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED}, + { SOCK_FLOAT, 1, N_("V"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED}, + { -1, 0, "" } +}; +static bNodeSocketTemplate sh_node_combhsv_out[] = { + { SOCK_RGBA, 0, N_("Color")}, + { -1, 0, "" } +}; + +void register_node_type_sh_combhsv(void) +{ + static bNodeType ntype; + + sh_node_type_base(&ntype, SH_NODE_COMBHSV, "Combine HSV", NODE_CLASS_CONVERTOR, 0); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_socket_templates(&ntype, sh_node_combhsv_in, sh_node_combhsv_out); + + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c index 6a77b0d3eb1..3bdc3813fd7 100644 --- a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c +++ b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c @@ -31,7 +31,7 @@ static bNodeSocketTemplate sh_node_subsurface_scattering_in[] = { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_FLOAT, 1, N_("Scale"), 1.0, 0.0f, 0.0f, 0.0f, 0.0f, 1000000.0f}, + { SOCK_FLOAT, 1, N_("Scale"), 1.0, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, { SOCK_VECTOR, 1, N_("Radius"), 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f}, //{ SOCK_FLOAT, 1, N_("IOR"), 1.3f, 0.0f, 0.0f, 0.0f, 1.0f, 1000.0f}, { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, diff --git a/source/blender/nodes/shader/nodes/node_shader_vectTransform.c b/source/blender/nodes/shader/nodes/node_shader_vectTransform.c new file mode 100644 index 00000000000..40c70b9e23d --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_vectTransform.c @@ -0,0 +1,66 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2013 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/shader/nodes/node_shader_vectTransform.c + * \ingroup shdnodes + */ + + #include "../node_shader_util.h" + +/* **************** Vector Transform ******************** */ +static bNodeSocketTemplate sh_node_vect_transform_in[] = { + { SOCK_VECTOR, 1, N_("Vector"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate sh_node_vect_transform_out[] = { + { SOCK_VECTOR, 0, N_("Vector")}, + { -1, 0, "" } +}; + +static void node_shader_init_vect_transform(bNodeTree *UNUSED(ntree), bNode *node) +{ + NodeShaderVectTransform *vect = MEM_callocN(sizeof(NodeShaderVectTransform), "NodeShaderVectTransform"); + + /* Convert World into Object Space per default */ + vect->convert_to = 1; + + node->storage = vect; +} + +void register_node_type_sh_vect_transform(void) +{ + static bNodeType ntype; + + sh_node_type_base(&ntype, SH_NODE_VECT_TRANSFORM, "Vector Transform", NODE_CLASS_CONVERTOR, 0); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_init(&ntype, node_shader_init_vect_transform); + node_type_socket_templates(&ntype, sh_node_vect_transform_in, sh_node_vect_transform_out); + node_type_storage(&ntype, "NodeShaderVectTransform", node_free_standard_storage, node_copy_standard_storage); + + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c index 859636ed4e5..5e863da9635 100644 --- a/source/blender/nodes/texture/node_texture_tree.c +++ b/source/blender/nodes/texture/node_texture_tree.c @@ -283,10 +283,12 @@ void ntreeTexEndExecTree_internal(bNodeTreeExec *exec) void ntreeTexEndExecTree(bNodeTreeExec *exec) { if (exec) { + /* exec may get freed, so assign ntree */ + bNodeTree *ntree = exec->nodetree; ntreeTexEndExecTree_internal(exec); /* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */ - exec->nodetree->execdata = NULL; + ntree->execdata = NULL; } } diff --git a/source/blender/nodes/texture/nodes/node_texture_output.c b/source/blender/nodes/texture/nodes/node_texture_output.c index 235cb560a99..37e527f611a 100644 --- a/source/blender/nodes/texture/nodes/node_texture_output.c +++ b/source/blender/nodes/texture/nodes/node_texture_output.c @@ -80,12 +80,13 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe static void unique_name(bNode *node) { TexNodeOutput *tno = (TexNodeOutput *)node->storage; - char *new_name = NULL; + char new_name[sizeof(tno->name)]; int new_len = 0; int suffix; bNode *i; char *name = tno->name; + new_name[0] = '\0'; i = node; while (i->prev) i = i->prev; for (; i; i = i->next) { @@ -96,7 +97,7 @@ static void unique_name(bNode *node) continue; } - if (!new_name) { + if (new_name[0] == '\0') { int len = strlen(name); if (len >= 4 && sscanf(name + len - 4, ".%03d", &suffix) == 1) { new_len = len; @@ -107,17 +108,15 @@ static void unique_name(bNode *node) if (new_len > (sizeof(tno->name) - 1)) new_len = (sizeof(tno->name) - 1); } - - new_name = MEM_mallocN(new_len + 1, "new_name"); - strcpy(new_name, name); + + BLI_strncpy(new_name, name, sizeof(tno->name)); name = new_name; } sprintf(new_name + new_len - 4, ".%03d", ++suffix); } - if (new_name) { - strcpy(tno->name, new_name); - MEM_freeN(new_name); + if (new_name[0] != '\0') { + BLI_strncpy(tno->name, new_name, sizeof(tno->name)); } } diff --git a/source/blender/python/bmesh/bmesh_py_ops.c b/source/blender/python/bmesh/bmesh_py_ops.c index 8826baf81b7..4fc0160bbd6 100644 --- a/source/blender/python/bmesh/bmesh_py_ops.c +++ b/source/blender/python/bmesh/bmesh_py_ops.c @@ -50,7 +50,7 @@ /* bmesh operator 'bmesh.ops.*' callable types * ******************************************* */ -PyTypeObject bmesh_op_Type; +static PyTypeObject bmesh_op_Type; static PyObject *bpy_bmesh_op_CreatePyObject(const char *opname) { @@ -140,7 +140,7 @@ static PyGetSetDef bpy_bmesh_op_getseters[] = { /* Types * ===== */ -PyTypeObject bmesh_op_Type = { +static PyTypeObject bmesh_op_Type = { PyVarObject_HEAD_INIT(NULL, 0) "BMeshOpFunc", /* tp_name */ sizeof(BPy_BMeshOpFunc), /* tp_basicsize */ diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c index b8572baa7f9..06b11f02b2a 100644 --- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c @@ -310,7 +310,7 @@ static int mathutils_bmloopcol_set_index(BaseMathObject *bmo, int subtype, int i return mathutils_bmloopcol_set(bmo, subtype); } -Mathutils_Callback mathutils_bmloopcol_cb = { +static Mathutils_Callback mathutils_bmloopcol_cb = { mathutils_bmloopcol_check, mathutils_bmloopcol_get, mathutils_bmloopcol_set, diff --git a/source/blender/python/bmesh/bmesh_py_utils.c b/source/blender/python/bmesh/bmesh_py_utils.c index 55c97b66ffb..d228e1a0646 100644 --- a/source/blender/python/bmesh/bmesh_py_utils.c +++ b/source/blender/python/bmesh/bmesh_py_utils.c @@ -245,14 +245,10 @@ static PyObject *bpy_bm_utils_vert_separate(PyObject *UNUSED(self), PyObject *ar return NULL; } - if (BM_vert_separate(bm, py_vert->v, &elem, &elem_len, edge_array, edge_array_len)) { - /* return collected verts */ - ret = BPy_BMElem_Array_As_Tuple(bm, (BMHeader **)elem, elem_len); - MEM_freeN(elem); - } - else { - ret = PyTuple_New(0); - } + BM_vert_separate(bm, py_vert->v, &elem, &elem_len, edge_array, edge_array_len); + /* return collected verts */ + ret = BPy_BMElem_Array_As_Tuple(bm, (BMHeader **)elem, elem_len); + MEM_freeN(elem); PyMem_FREE(edge_array); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 9f7c589630a..3cd030e9b08 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -5948,7 +5948,7 @@ PyTypeObject pyrna_func_Type = { static void pyrna_prop_collection_iter_dealloc(BPy_PropertyCollectionIterRNA *self); static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self); -PyTypeObject pyrna_prop_collection_iter_Type = { +static PyTypeObject pyrna_prop_collection_iter_Type = { PyVarObject_HEAD_INIT(NULL, 0) "bpy_prop_collection_iter", /* tp_name */ sizeof(BPy_PropertyCollectionIterRNA), /* tp_basicsize */ diff --git a/source/blender/quicktime/apple/quicktime_export.c b/source/blender/quicktime/apple/quicktime_export.c index ce4f3063082..52ef21e4f39 100644 --- a/source/blender/quicktime/apple/quicktime_export.c +++ b/source/blender/quicktime/apple/quicktime_export.c @@ -768,7 +768,7 @@ int get_qtcodec_settings(RenderData *rd, ReportList *reports) return err; } -static int request_qtcodec_settings(bContext *C, wmOperator *op) +static int request_qtcodec_settings_exec(bContext *C, wmOperator *op) { OSErr err = noErr; Scene *scene = CTX_data_scene(C); @@ -893,11 +893,11 @@ static int ED_operator_setqtcodec(bContext *C) #if defined(__APPLE__) && defined(GHOST_COCOA) /* Need to set up a Cocoa NSAutoReleasePool to avoid memory leak * And it must be done in an objC file, so use a GHOST_SystemCocoa.mm function for that */ -extern int cocoa_request_qtcodec_settings(bContext *C, wmOperator *op); +extern int cocoa_request_qtcodec_settings_exec(bContext *C, wmOperator *op); int fromcocoa_request_qtcodec_settings(bContext *C, wmOperator *op) { - return request_qtcodec_settings(C, op); + return request_qtcodec_settings_exec(C, op); } #endif @@ -911,9 +911,9 @@ void SCENE_OT_render_data_set_quicktime_codec(wmOperatorType *ot) /* api callbacks */ #if defined(__APPLE__) && defined(GHOST_COCOA) - ot->exec = cocoa_request_qtcodec_settings; + ot->exec = cocoa_request_qtcodec_settings_exec; #else - ot->exec = request_qtcodec_settings; + ot->exec = request_qtcodec_settings_exec; #endif ot->poll = ED_operator_setqtcodec; diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h index ca9897b652c..ec30c3241ab 100644 --- a/source/blender/render/intern/include/zbuf.h +++ b/source/blender/render/intern/include/zbuf.h @@ -120,8 +120,9 @@ typedef struct ZSpan { } ZSpan; /* exported to shadbuf.c */ -void zbufclip4(struct ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, float *f4, - int c1, int c2, int c3, int c4); +void zbufclip4(struct ZSpan *zspan, int obi, int zvlnr, + const float f1[4], const float f2[4], const float f3[4], const float f4[4], + const int c1, const int c2, const int c3, const int c4); void zbuf_free_span(struct ZSpan *zspan); void freepsA(struct ListBase *lb); @@ -130,10 +131,13 @@ void zspan_scanconvert(struct ZSpan *zpan, void *handle, float *v1, float *v2, f void (*func)(void *, int, int, float, float) ); /* exported to edge render... */ -void zbufclip(struct ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3); +void zbufclip(struct ZSpan *zspan, int obi, int zvlnr, + const float f1[4], const float f2[4], const float f3[4], + const int c1, const int c2, const int c3); void zbuf_alloc_span(struct ZSpan *zspan, int rectx, int recty, float clipcrop); void zbufclipwire(struct ZSpan *zspan, int obi, int zvlnr, int ec, - float *ho1, float *ho2, float *ho3, float *ho4, int c1, int c2, int c3, int c4); + const float ho1[4], const float ho2[4], const float ho3[4], const float ho4[4], + const int c1, const int c2, const int c3, const int c4); /* exported to shadeinput.c */ void zbuf_make_winmat(Render *re, float winmat[4][4]); diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp index e4fd5a6d41e..2f668ba62d0 100644 --- a/source/blender/render/intern/raytrace/rayobject_octree.cpp +++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp @@ -521,7 +521,7 @@ static void octree_fill_rayface(Octree *oc, RayFace *face) copy_v3_v3(co1, face->v1); copy_v3_v3(co2, face->v2); copy_v3_v3(co3, face->v3); - if (face->v4) + if (RE_rayface_isQuad(face)) copy_v3_v3(co4, face->v4); for (c = 0; c < 3; c++) { diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c index a15d24ebe42..564cca09834 100644 --- a/source/blender/render/intern/source/bake.c +++ b/source/blender/render/intern/source/bake.c @@ -577,7 +577,7 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v) if (bs->type == RE_BAKE_NORMALS && R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) bake_shade(handle, ob, shi, quad, x, y, u, v, tvn, ttang); else - bake_shade(handle, ob, shi, quad, x, y, u, v, 0, 0); + bake_shade(handle, ob, shi, quad, x, y, u, v, NULL, NULL); } static int get_next_bake_face(BakeShade *bs) diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 7d842c1026b..ab888ba198b 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -726,7 +726,7 @@ static int as_testvertex(VlakRen *vlr, VertRen *UNUSED(ver), ASvert *asv, float float inp; int a; - if (vlr==0) return 0; + if (vlr == NULL) return 0; asf= asv->faces.first; while (asf) { @@ -803,7 +803,7 @@ static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[4][4], int totvert= obr->totvert; /* we now test all vertices, when faces have a normal too much different: they get a new vertex */ for (a=0, asv=asverts; a<totvert; a++, asv++) { - if (asv && asv->totface>1) { + if (asv->totface > 1) { ver= RE_findOrAddVert(obr, a); asf= asv->faces.first; @@ -1289,7 +1289,7 @@ static void static_particle_wire(ObjectRen *obr, Material *ma, const float vec[3 static void particle_curve(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, ParticleStrandData *sd, const float loc[3], const float loc1[3], int seed, float *pa_co) { - HaloRen *har=0; + HaloRen *har = NULL; if (ma->material_type == MA_TYPE_WIRE) static_particle_wire(obr, ma, loc, loc1, sd->first, sd->line); @@ -1466,7 +1466,7 @@ static void particle_normal_ren(short ren_as, ParticleSettings *part, Render *re default: { - HaloRen *har=0; + HaloRen *har = NULL; har = RE_inithalo_particle(re, obr, dm, ma, loc, NULL, sd->orco, sd->uvco, hasize, 0.0, seed, pa_co); @@ -1516,22 +1516,22 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem { Object *ob= obr->ob; // Object *tob=0; - Material *ma=0; + Material *ma = NULL; ParticleSystemModifierData *psmd; - ParticleSystem *tpsys=0; - ParticleSettings *part, *tpart=0; - ParticleData *pars, *pa=0, *tpa=0; - ParticleKey *states=0; + ParticleSystem *tpsys = NULL; + ParticleSettings *part, *tpart = NULL; + ParticleData *pars, *pa = NULL, *tpa = NULL; + ParticleKey *states = NULL; ParticleKey state; - ParticleCacheKey *cache=0; + ParticleCacheKey *cache = NULL; ParticleBillboardData bb; - ParticleSimulationData sim = {0}; + ParticleSimulationData sim = {NULL}; ParticleStrandData sd; - StrandBuffer *strandbuf=0; - StrandVert *svert=0; - StrandBound *sbound= 0; - StrandRen *strand=0; - RNG *rng= 0; + StrandBuffer *strandbuf = NULL; + StrandVert *svert = NULL; + StrandBound *sbound = NULL; + StrandRen *strand = NULL; + RNG *rng = NULL; float loc[3], loc1[3], loc0[3], mat[4][4], nmat[3][3], co[3], nor[3], duplimat[4][4]; float strandlen=0.0f, curlen=0.0f; float hasize, pa_size, r_tilt, r_length; @@ -1542,7 +1542,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem int totchild=0, step_nbr; int seed, path_nbr=0, orco1=0, num; int totface; - char **uv_name=0; + char **uv_name = NULL; const int *index_mf_to_mpoly = NULL; const int *index_mp_to_orig = NULL; @@ -1735,7 +1735,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem } } - if (sd.orco == 0) { + if (sd.orco == NULL) { sd.orco = MEM_mallocN(3 * sizeof(float), "particle orco"); orco1 = 1; } @@ -1760,10 +1760,17 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem /* get orco */ if (tpsys && part->phystype == PART_PHYS_NO) { tpa = tpsys->particles + pa->num; - psys_particle_on_emitter(psmd, tpart->from, tpa->num, pa->num_dmcache, tpa->fuv, tpa->foffset, co, nor, 0, 0, sd.orco, 0); + psys_particle_on_emitter( + psmd, + tpart->from, tpa->num, pa->num_dmcache, tpa->fuv, + tpa->foffset, co, nor, NULL, NULL, sd.orco, NULL); + } + else { + psys_particle_on_emitter( + psmd, + part->from, pa->num, pa->num_dmcache, + pa->fuv, pa->foffset, co, nor, NULL, NULL, sd.orco, NULL); } - else - psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, nor, 0, 0, sd.orco, 0); /* get uvco & mcol */ num= pa->num_dmcache; @@ -1808,15 +1815,17 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem /* get orco */ if (part->childtype == PART_CHILD_FACES) { - psys_particle_on_emitter(psmd, - PART_FROM_FACE, cpa->num, DMCACHE_ISCHILD, - cpa->fuv, cpa->foffset, co, nor, 0, 0, sd.orco, 0); + psys_particle_on_emitter( + psmd, + PART_FROM_FACE, cpa->num, DMCACHE_ISCHILD, + cpa->fuv, cpa->foffset, co, nor, NULL, NULL, sd.orco, NULL); } else { ParticleData *par = psys->particles + cpa->parent; - psys_particle_on_emitter(psmd, part->from, - par->num, DMCACHE_ISCHILD, par->fuv, - par->foffset, co, nor, 0, 0, sd.orco, 0); + psys_particle_on_emitter( + psmd, + part->from, par->num, DMCACHE_ISCHILD, par->fuv, + par->foffset, co, nor, NULL, NULL, sd.orco, NULL); } /* get uvco & mcol */ @@ -2419,7 +2428,7 @@ static void init_render_mball(Render *re, ObjectRen *obr) BKE_displist_make_mball_forRender(re->scene, ob, &dispbase); dl= dispbase.first; - if (dl==0) return; + if (dl == NULL) return; data= dl->verts; nors= dl->nors; @@ -2464,7 +2473,7 @@ static void init_render_mball(Render *re, ObjectRen *obr) vlr->v1= RE_findOrAddVert(obr, index[0]); vlr->v2= RE_findOrAddVert(obr, index[1]); vlr->v3= RE_findOrAddVert(obr, index[2]); - vlr->v4= 0; + vlr->v4 = NULL; if (negative_scale) normal_tri_v3(vlr->n, vlr->v1->co, vlr->v2->co, vlr->v3->co); @@ -2729,7 +2738,7 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr, vlr->v2= RE_findOrAddVert(obr, vertofs+v2); vlr->v3= RE_findOrAddVert(obr, vertofs+v3); if (v4) vlr->v4= RE_findOrAddVert(obr, vertofs+v4); - else vlr->v4= 0; + else vlr->v4 = NULL; /* render normals are inverted in render */ if (vlr->v4) @@ -2787,7 +2796,7 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr, static void init_render_surf(Render *re, ObjectRen *obr, int timeoffset) { Object *ob= obr->ob; - Nurb *nu=0; + Nurb *nu = NULL; Curve *cu; ListBase displist= {NULL, NULL}; DispList *dl; @@ -2798,7 +2807,7 @@ static void init_render_surf(Render *re, ObjectRen *obr, int timeoffset) cu= ob->data; nu= cu->nurb.first; - if (nu==0) return; + if (nu == NULL) return; mul_m4_m4m4(mat, re->viewmat, ob->obmat); invert_m4_m4(ob->imat, mat); @@ -3311,7 +3320,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) DerivedMesh *dm; CustomDataMask mask; float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3], - float *orco=0; + float *orco = NULL; int need_orco=0, need_stress=0, need_nmap_tangent=0, need_tangent=0, need_origindex=0; int a, a1, ok, vertofs; int end, do_autosmooth = FALSE, totvert = 0; @@ -3526,8 +3535,8 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) vlr->v1= RE_findOrAddVert(obr, vertofs+v1); vlr->v2= RE_findOrAddVert(obr, vertofs+v2); vlr->v3= RE_findOrAddVert(obr, vertofs+v3); - if (v4) vlr->v4= RE_findOrAddVert(obr, vertofs+v4); - else vlr->v4= 0; + if (v4) vlr->v4 = RE_findOrAddVert(obr, vertofs+v4); + else vlr->v4 = NULL; #ifdef WITH_FREESTYLE /* Freestyle edge/face marks */ @@ -4706,14 +4715,12 @@ static void set_dupli_tex_mat(Render *re, ObjectInstanceRen *obi, DupliObject *d obi->duplitexmat= BLI_memarena_alloc(re->memArena, sizeof(float)*4*4); invert_m4_m4(imat, dob->mat); - mul_serie_m4(obi->duplitexmat, re->viewmat, dob->omat, imat, re->viewinv, 0, 0, 0, 0); + mul_serie_m4(obi->duplitexmat, re->viewmat, dob->omat, imat, re->viewinv, + NULL, NULL, NULL, NULL); } - if (dob) { - copy_v3_v3(obi->dupliorco, dob->orco); - obi->dupliuv[0]= dob->uv[0]; - obi->dupliuv[1]= dob->uv[1]; - } + copy_v3_v3(obi->dupliorco, dob->orco); + copy_v2_v2(obi->dupliuv, dob->uv); } static void init_render_object_data(Render *re, ObjectRen *obr, int timeoffset) @@ -4810,6 +4817,9 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject * if (ob->particlesystem.first) { psysindex= 1; for (psys=ob->particlesystem.first; psys; psys=psys->next, psysindex++) { + if (!psys_check_enabled(ob, psys)) + continue; + obr= RE_addRenderObject(re, ob, par, index, psysindex, ob->lay); if ((dob && !dob->animated) || (ob->transflag & OB_RENDER_DUPLI)) { obr->flag |= R_INSTANCEABLE; @@ -5068,7 +5078,7 @@ static void add_group_render_dupli_obs(Render *re, Group *group, int nolamps, in if (ob->flag & OB_DONE) { if (ob->transflag & OB_RENDER_DUPLI) { if (allow_render_object(re, ob, nolamps, onlyselected, actob)) { - init_render_object(re, ob, NULL, 0, timeoffset); + init_render_object(re, ob, NULL, NULL, timeoffset); ob->transflag &= ~OB_RENDER_DUPLI; if (ob->dup_group) @@ -5128,7 +5138,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp * it still needs to create the ObjectRen containing the data */ if (ob->transflag & OB_RENDER_DUPLI) { if (allow_render_object(re, ob, nolamps, onlyselected, actob)) { - init_render_object(re, ob, NULL, 0, timeoffset); + init_render_object(re, ob, NULL, NULL, timeoffset); ob->transflag &= ~OB_RENDER_DUPLI; } } @@ -5236,10 +5246,10 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp free_object_duplilist(lb); if (allow_render_object(re, ob, nolamps, onlyselected, actob)) - init_render_object(re, ob, NULL, 0, timeoffset); + init_render_object(re, ob, NULL, NULL, timeoffset); } else if (allow_render_object(re, ob, nolamps, onlyselected, actob)) - init_render_object(re, ob, NULL, 0, timeoffset); + init_render_object(re, ob, NULL, NULL, timeoffset); } if (re->test_break(re->tbh)) break; @@ -5327,7 +5337,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l set_node_shader_lamp_loop(shade_material_loop); /* MAKE RENDER DATA */ - database_init_objects(re, lay, 0, 0, 0, 0); + database_init_objects(re, lay, 0, 0, NULL, 0); if (!re->test_break(re->tbh)) { set_material_lightgroups(re); @@ -5486,7 +5496,7 @@ static void database_fromscene_vectors(Render *re, Scene *scene, unsigned int la } /* MAKE RENDER DATA */ - database_init_objects(re, lay, 0, 0, 0, timeoffset); + database_init_objects(re, lay, 0, 0, NULL, timeoffset); if (!re->test_break(re->tbh)) project_renderdata(re, projectverto, re->r.mode & R_PANORAMA, 0, 1); diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 3cd9020fb89..b5bc5ea768b 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -245,9 +245,7 @@ static void envmap_transmatrix(float mat[4][4], int part) copy_m4_m4(tmat, mat); eul_to_mat4(rotmat, eul); - mul_serie_m4(mat, tmat, rotmat, - NULL, NULL, NULL, - NULL, NULL, NULL); + mul_m4_m4m4(mat, tmat, rotmat); } /* ------------------------------------------------------------------------- */ diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 616dd623b94..ea22423985b 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -311,7 +311,7 @@ void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char else if (info && info[0]) BLI_strncpy(engine->text, info, sizeof(engine->text)); else if (stats && stats[0]) - BLI_strncpy(engine->text, info, sizeof(engine->text)); + BLI_strncpy(engine->text, stats, sizeof(engine->text)); } void RE_engine_update_progress(RenderEngine *engine, float progress) diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index d4d4a703d6c..6cac2fa3fa6 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -541,8 +541,8 @@ void RE_parts_free(Render *re) void RE_parts_clamp(Render *re) { /* part size */ - re->partx = min_ii(re->r.tilex, re->rectx); - re->party = min_ii(re->r.tiley, re->recty); + re->partx = max_ii(1, min_ii(re->r.tilex, re->rectx)); + re->party = max_ii(1, min_ii(re->r.tiley, re->recty)); } void RE_parts_init(Render *re, int do_crop) diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c index e81359e8fca..a2fa37fd7ea 100644 --- a/source/blender/render/intern/source/multires_bake.c +++ b/source/blender/render/intern/source/multires_bake.c @@ -776,7 +776,7 @@ static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, get_ccgdm_data(lores_dm, hires_dm, height_data->orig_index_mf_to_mpoly, height_data->orig_index_mp_to_orig, - lvl, face_index, uv[0], uv[1], p1, 0); + lvl, face_index, uv[0], uv[1], p1, NULL); if (height_data->ssdm) { get_ccgdm_data(lores_dm, height_data->ssdm, diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index 50f9d6caff6..a16c4b24682 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -371,7 +371,7 @@ static void occ_sum_occlusion(OcclusionTree *tree, OccNode *node) for (b = 0; b < TOTCHILD; b++) { if (node->childflag & (1 << b)) { a = node->child[b].face; - occ_face(&tree->face[a], 0, 0, &area); + occ_face(&tree->face[a], NULL, NULL, &area); occ += area * tree->occlusion[a]; if (indirect) madd_v3_v3fl(rad, tree->rad[a], area); totarea += area; @@ -521,7 +521,7 @@ static void *exec_occ_build(void *data) occ_build_recursive(othread->tree, othread->node, othread->begin, othread->end, othread->depth); - return 0; + return NULL; } static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, int end, int depth) @@ -567,7 +567,7 @@ static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, i node->child[b].node = child; /* keep track of maximum depth for stack */ - if (depth + 1 > tree->maxdepth) + if (depth >= tree->maxdepth) tree->maxdepth = depth + 1; if (tree->dothreadedbuild) @@ -1244,7 +1244,7 @@ static void *exec_strandsurface_sample(void *data) copy_v3_v3(othread->faceindirect[a], indirect); } - return 0; + return NULL; } void make_occ_tree(Render *re) diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 848e94c8d4b..899c9b335be 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1927,6 +1927,8 @@ static void do_render_composite_fields_blur_3d(Render *re) do_render_fields_blur_3d(re); } else { + re->i.cfra = re->r.cfra; + /* ensure new result gets added, like for regular renders */ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index e86ae7ea063..d4d6bfa5b7f 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -107,6 +107,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa { DerivedMesh* dm; ParticleKey state; + ParticleCacheKey *cache; ParticleSimulationData sim= {NULL}; ParticleData *pa=NULL; float cfra = BKE_scene_frame_get(re->scene); @@ -153,44 +154,62 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa for (i=0, pa=psys->particles; i < total_particles; i++, pa++) { - state.time = cfra; - if (psys_get_particle_state(&sim, i, &state, 0)) { - - copy_v3_v3(partco, state.co); - - if (pd->psys_cache_space == TEX_PD_OBJECTSPACE) - mul_m4_v3(ob->imat, partco); - else if (pd->psys_cache_space == TEX_PD_OBJECTLOC) { - sub_v3_v3(partco, ob->loc); - } - else { - /* TEX_PD_WORLDSPACE */ - } - - BLI_bvhtree_insert(pd->point_tree, i, partco, 1); - - if (data_used & POINT_DATA_VEL) { - pd->point_data[i*3 + 0] = state.vel[0]; - pd->point_data[i*3 + 1] = state.vel[1]; - pd->point_data[i*3 + 2] = state.vel[2]; - } + if (psys->part->type == PART_HAIR) { + /* hair particles */ + if (i < psys->totpart && psys->pathcache) + cache = psys->pathcache[i]; + else if (i >= psys->totpart && psys->childcache) + cache = psys->childcache[i - psys->totpart]; + else + continue; + + cache += cache->steps; /* use endpoint */ + + copy_v3_v3(state.co, cache->co); + zero_v3(state.vel); + state.time = 0.0f; + } + else { + /* emitter particles */ + state.time = cfra; + + if (!psys_get_particle_state(&sim, i, &state, 0)) + continue; + if (data_used & POINT_DATA_LIFE) { - float pa_time; - if (i < psys->totpart) { - pa_time = (cfra - pa->time)/pa->lifetime; + state.time = (cfra - pa->time)/pa->lifetime; } else { ChildParticle *cpa= (psys->child + i) - psys->totpart; float pa_birthtime, pa_dietime; - pa_time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime); + state.time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime); } - - pd->point_data[offset + i] = pa_time; - } } + + copy_v3_v3(partco, state.co); + + if (pd->psys_cache_space == TEX_PD_OBJECTSPACE) + mul_m4_v3(ob->imat, partco); + else if (pd->psys_cache_space == TEX_PD_OBJECTLOC) { + sub_v3_v3(partco, ob->loc); + } + else { + /* TEX_PD_WORLDSPACE */ + } + + BLI_bvhtree_insert(pd->point_tree, i, partco, 1); + + if (data_used & POINT_DATA_VEL) { + pd->point_data[i*3 + 0] = state.vel[0]; + pd->point_data[i*3 + 1] = state.vel[1]; + pd->point_data[i*3 + 2] = state.vel[2]; + } + if (data_used & POINT_DATA_LIFE) { + pd->point_data[offset + i] = state.time; + } } BLI_bvhtree_balance(pd->point_tree); @@ -198,7 +217,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa if (psys->lattice) { end_latt_deform(psys->lattice); - psys->lattice=0; + psys->lattice = NULL; } psys_render_restore(ob, psys); diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index e77920dde26..7ae64d499fa 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -731,7 +731,7 @@ static void ray_fadeout(Isect *is, ShadeInput *shi, float col[3], const float bl * note: 'col' must be initialized */ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, const float start[3], const float dir[3], float col[4], ObjectInstanceRen *obi, VlakRen *vlr, int traflag) { - ShadeInput shi= {0}; + ShadeInput shi = {NULL}; Isect isec; float dist_mir = origshi->mat->dist_mir; @@ -741,7 +741,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, con isec.mode= RE_RAY_MIRROR; isec.check = RE_CHECK_VLR_RENDER; isec.skip = RE_SKIP_VLR_NEIGHBOUR; - isec.hint = 0; + isec.hint = NULL; isec.orig.ob = obi; isec.orig.face = vlr; @@ -1866,10 +1866,10 @@ static void ray_ao_qmc(ShadeInput *shi, float ao[3], float env[3]) isec.orig.face = shi->vlr; isec.check = RE_CHECK_VLR_NON_SOLID_MATERIAL; isec.skip = RE_SKIP_VLR_NEIGHBOUR; - isec.hint = 0; + isec.hint = NULL; - isec.hit.ob = 0; - isec.hit.face = 0; + isec.hit.ob = NULL; + isec.hit.face = NULL; isec.last_hit = NULL; @@ -2013,10 +2013,10 @@ static void ray_ao_spheresamp(ShadeInput *shi, float ao[3], float env[3]) isec.orig.face = shi->vlr; isec.check = RE_CHECK_VLR_RENDER; isec.skip = RE_SKIP_VLR_NEIGHBOUR; - isec.hint = 0; + isec.hint = NULL; - isec.hit.ob = 0; - isec.hit.face = 0; + isec.hit.ob = NULL; + isec.hit.face = NULL; isec.last_hit = NULL; @@ -2468,7 +2468,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float shadfac[4]) RE_RC_INIT(isec, *shi); if (shi->mat->mode & MA_SHADOW_TRA) isec.mode= RE_RAY_SHADOW_TRA; else isec.mode= RE_RAY_SHADOW; - isec.hint = 0; + isec.hint = NULL; if (lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) isec.lay= lar->lay; diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index f719e09769d..1f740e3f483 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -279,6 +279,24 @@ static const char *get_pass_name(int passtype, int channel) if (channel == 1) return "TransCol.G"; return "TransCol.B"; } + if (passtype == SCE_PASS_SUBSURFACE_DIRECT) { + if (channel == -1) return "SubsurfaceDir"; + if (channel == 0) return "SubsurfaceDir.R"; + if (channel == 1) return "SubsurfaceDir.G"; + return "SubsurfaceDir.B"; + } + if (passtype == SCE_PASS_SUBSURFACE_INDIRECT) { + if (channel == -1) return "SubsurfaceInd"; + if (channel == 0) return "SubsurfaceInd.R"; + if (channel == 1) return "SubsurfaceInd.G"; + return "SubsurfaceInd.B"; + } + if (passtype == SCE_PASS_SUBSURFACE_COLOR) { + if (channel == -1) return "SubsurfaceCol"; + if (channel == 0) return "SubsurfaceCol.R"; + if (channel == 1) return "SubsurfaceCol.G"; + return "SubsurfaceCol.B"; + } return "Unknown"; } @@ -368,6 +386,15 @@ static int passtype_from_name(const char *str) if (strcmp(str, "TransCol") == 0) return SCE_PASS_TRANSM_COLOR; + + if (strcmp(str, "SubsurfaceDir") == 0) + return SCE_PASS_SUBSURFACE_DIRECT; + + if (strcmp(str, "SubsurfaceInd") == 0) + return SCE_PASS_SUBSURFACE_INDIRECT; + + if (strcmp(str, "SubsurfaceCol") == 0) + return SCE_PASS_SUBSURFACE_COLOR; return 0; } @@ -538,6 +565,12 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_INDIRECT); if (srl->passflag & SCE_PASS_TRANSM_COLOR) render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_COLOR); + if (srl->passflag & SCE_PASS_SUBSURFACE_DIRECT) + render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_DIRECT); + if (srl->passflag & SCE_PASS_SUBSURFACE_INDIRECT) + render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_INDIRECT); + if (srl->passflag & SCE_PASS_SUBSURFACE_COLOR) + render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_COLOR); } /* sss, previewrender and envmap don't do layers, so we make a default one */ if (rr->layers.first == NULL && !(layername && layername[0])) { diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index ad923a4172c..49052150fe3 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -2163,7 +2163,7 @@ void do_material_tex(ShadeInput *shi, Render *re) mtex= shi->mat->mtex[tex_nr]; tex= mtex->tex; - if (tex==0) continue; + if (tex == NULL) continue; found_deriv_map = (tex->type==TEX_IMAGE) && (tex->imaflag & TEX_DERIVATIVEMAP); use_compat_bump= (mtex->texflag & MTEX_COMPAT_BUMP); @@ -2686,7 +2686,7 @@ void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_ if (shi->mat->mtex[tex_nr]) { mtex= shi->mat->mtex[tex_nr]; tex= mtex->tex; - if (tex==0) continue; + if (tex == NULL) continue; /* only process if this texture is mapped * to one that we're interested in */ @@ -3028,7 +3028,7 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h mtex= R.wrld.mtex[tex_nr]; tex= mtex->tex; - if (tex==0) continue; + if (tex == NULL) continue; /* if (mtex->mapto==0) continue; */ /* which coords */ @@ -3609,7 +3609,7 @@ Material *RE_init_sample_material(Material *orig_mat, Scene *scene) } if (tex->type==TEX_POINTDENSITY) { /* set dummy values for render and do cache */ - Render dummy_re = {0}; + Render dummy_re = {NULL}; dummy_re.scene = scene; unit_m4(dummy_re.viewinv); unit_m4(dummy_re.viewmat); @@ -3668,8 +3668,8 @@ void RE_sample_material_color(Material *mat, float color[3], float *alpha, const int v1, v2, v3; MVert *mvert; float uv[3], normal[3]; - ShadeInput shi = {0}; - Render re = {0}; + ShadeInput shi = {NULL}; + Render re = {NULL}; /* Get face data */ mvert = orcoDm->getVertArray(orcoDm); @@ -3752,7 +3752,7 @@ void RE_sample_material_color(Material *mat, float color[3], float *alpha, const *alpha = shi.alpha; } else if (mat->material_type == MA_TYPE_VOLUME) { - ObjectInstanceRen obi = {0}; + ObjectInstanceRen obi = {NULL}; obi.ob = ob; shi.obi = &obi; unit_m4(re.viewinv); diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index 6453c03c596..0d85cfe78b7 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -1026,7 +1026,7 @@ static float readdeepshadowbuf(ShadBuf *shb, ShadSampleBuf *shsample, int bias, if (biast != 0.0f) { /* in soft bias area */ - biasv= readdeepvisibility(shsample->deepbuf[ofs], tot, zs, 0, 0); + biasv = readdeepvisibility(shsample->deepbuf[ofs], tot, zs, 0, NULL); biast= biast*biast; return (1.0f-biast)*v + biast*biasv; @@ -2045,7 +2045,7 @@ static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root) if (vlr->v4) zbufclipwire(&zspan, i, a+1, vlr->ec, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4); else - zbufclipwire(&zspan, i, a+1, vlr->ec, hoco[0], hoco[1], hoco[2], 0, c1, c2, c3, 0); + zbufclipwire(&zspan, i, a+1, vlr->ec, hoco[0], hoco[1], hoco[2], NULL, c1, c2, c3, 0); } else if (vlr->v4) { if (vlr->flag & R_STRAND) diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index 0a9c1fa666e..f2d4a7afd94 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -783,7 +783,7 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBa ObjectRen *obr; ObjectInstanceRen *obi; ZSpan zspan; - StrandRen *strand=0; + StrandRen *strand = NULL; StrandVert *svert; StrandBound *sbound; StrandPart spart; diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index 0aa1bcfef34..3f19e77946c 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -156,7 +156,7 @@ static void load_frame_image_sequence(VoxelData *vd, Tex *tex) int x = 0, y = 0, z = 0; float *rf; - if (!ima || !tiuser) return; + if (!ima) return; if (iuser.frames == 0) return; ima->source = IMA_SRC_SEQUENCE; diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 2f45ad756d3..d65db9d47f8 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -121,7 +121,7 @@ static void zbuf_init_span(ZSpan *zspan) zspan->minp1= zspan->maxp1= zspan->minp2= zspan->maxp2= NULL; } -static void zbuf_add_to_span(ZSpan *zspan, const float *v1, const float *v2) +static void zbuf_add_to_span(ZSpan *zspan, const float v1[2], const float v2[2]) { const float *minv, *maxv; float *span; @@ -504,7 +504,7 @@ static void zbuflineAc(ZSpan *zspan, int obi, int zvlnr, const float vec1[3], co if (apn->p[2]==zvlnr && apn->obi[2]==obi) {apn->mask[2]|= mask; break; } if (apn->p[3]==0) {apn->obi[3]= obi; apn->p[3]= zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; } if (apn->p[3]==zvlnr && apn->obi[3]==obi) {apn->mask[3]|= mask; break; } - if (apn->next==0) apn->next= addpsA(zspan); + if (apn->next == NULL) apn->next = addpsA(zspan); apn= apn->next; } } @@ -575,7 +575,7 @@ static void zbuflineAc(ZSpan *zspan, int obi, int zvlnr, const float vec1[3], co if (apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; } if (apn->p[3]==0) {apn->obi[3]= obi; apn->p[3]= zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; } if (apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; } - if (apn->next==0) apn->next= addpsA(zspan); + if (apn->next == NULL) apn->next = addpsA(zspan); apn= apn->next; } } @@ -909,7 +909,9 @@ void hoco_to_zco(ZSpan *zspan, float zco[3], const float hoco[4]) zco[2]= 0x7FFFFFFF *(hoco[2]*div); } -void zbufclipwire(ZSpan *zspan, int obi, int zvlnr, int ec, float *ho1, float *ho2, float *ho3, float *ho4, int c1, int c2, int c3, int c4) +void zbufclipwire(ZSpan *zspan, int obi, int zvlnr, int ec, + const float ho1[4], const float ho2[4], const float ho3[4], const float ho4[4], + int c1, int c2, int c3, int c4) { float vez[20]; int and, or; @@ -1845,7 +1847,9 @@ void zbuf_make_winmat(Render *re, float winmat[4][4]) /* do zbuffering and clip, f1 f2 f3 are hocos, c1 c2 c3 are clipping flags */ -void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3) +void zbufclip(ZSpan *zspan, int obi, int zvlnr, + const float f1[4], const float f2[4], const float f3[4], + const int c1, const int c2, const int c3) { float *vlzp[32][3], lambda[3][2]; float vez[400], *trias[40]; @@ -1856,6 +1860,7 @@ void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, } else { /* clipping */ int arg, v, b, clipflag[3], b1, b2, b3, c4, clve=3, clvlo, clvl=1; + float *fp; vez[0]= f1[0]; vez[1]= f1[1]; vez[2]= f1[2]; vez[3]= f1[3]; vez[4]= f2[0]; vez[5]= f2[1]; vez[6]= f2[2]; vez[7]= f2[3]; @@ -1936,16 +1941,16 @@ void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, } } - /* warning, this should never happen! */ - if (clve>38 || clvl>31) printf("clip overflow: clve clvl %d %d\n", clve, clvl); + /* warning, clip overflow, this should never happen! */ + BLI_assert(!(clve > 38 || clvl > 31)); /* perspective division */ - f1=vez; - for (c1=0;c1<clve;c1++) { - hoco_to_zco(zspan, f1, f1); - f1+=4; + fp = vez; + for (b = 0; b < clve; b++) { + hoco_to_zco(zspan, fp, fp); + fp += 4; } - for (b=1;b<clvl;b++) { + for (b = 1; b < clvl; b++) { if (vlzp[b][0]) { zspan->zbuffunc(zspan, obi, zvlnr, vlzp[b][0], vlzp[b][1], vlzp[b][2], NULL); } @@ -1961,7 +1966,9 @@ void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, zspan->zbuffunc(zspan, obi, zvlnr, vez, vez+4, vez+8, NULL); } -void zbufclip4(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, float *f4, int c1, int c2, int c3, int c4) +void zbufclip4(ZSpan *zspan, int obi, int zvlnr, + const float f1[4], const float f2[4], const float f3[4], const float f4[4], + const int c1, const int c2, const int c3, const int c4) { float vez[16]; @@ -2068,7 +2075,7 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart * ZSpan zspans[16], *zspan; /* 16 = RE_MAX_OSA */ VlakRen *vlr= NULL; VertRen *v1, *v2, *v3, *v4; - Material *ma=0; + Material *ma = NULL; ObjectInstanceRen *obi; ObjectRen *obr; float obwinmat[4][4], winmat[4][4], bounds[4]; @@ -2238,7 +2245,7 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart * if (v4) zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, ho4, c1, c2, c3, c4); else - zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, 0, c1, c2, c3, 0); + zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, NULL, c1, c2, c3, 0); } else { /* strands allow to be filled in as quad */ @@ -2375,7 +2382,7 @@ void zbuffer_shadow(Render *re, float winmat[4][4], LampRen *lar, int *rectz, in zbufclipwire(&zspan, 0, a+1, vlr->ec, ho1, ho2, ho3, ho4, c1, c2, c3, c4); } else - zbufclipwire(&zspan, 0, a+1, vlr->ec, ho1, ho2, ho3, 0, c1, c2, c3, 0); + zbufclipwire(&zspan, 0, a+1, vlr->ec, ho1, ho2, ho3, NULL, c1, c2, c3, 0); } else { if (vlr->v4) { @@ -2539,7 +2546,7 @@ void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(vo ObjectRen *obr; VlakRen *vlr= NULL; VertRen *v1, *v2, *v3, *v4; - Material *ma=0, *sss_ma= R.sss_mat; + Material *ma = NULL, *sss_ma = R.sss_mat; float obwinmat[4][4], winmat[4][4], bounds[4]; float ho1[4], ho2[4], ho3[4], ho4[4]={0}; int i, v, zvlnr, c1, c2, c3, c4=0; @@ -3399,7 +3406,7 @@ static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase * if (v4) zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, ho4, c1, c2, c3, c4); else - zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, 0, c1, c2, c3, 0); + zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, NULL, c1, c2, c3, 0); } else { if (v4 && (vlr->flag & R_STRAND)) { diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 7cb24daaaef..8894be111e7 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -187,6 +187,8 @@ __attribute__ ((format(printf, 3, 4))) ; void wm_event_add(struct wmWindow *win, const struct wmEvent *event_to_add); +void wm_event_init_from_window(struct wmWindow *win, struct wmEvent *event); + /* at maximum, every timestep seconds it triggers event_type events */ struct wmTimer *WM_event_add_timer(struct wmWindowManager *wm, struct wmWindow *win, int event_type, double timestep); @@ -340,7 +342,7 @@ ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid); /* Set a subwindow active in pixelspace view, with optional scissor subset */ void wmSubWindowSet (struct wmWindow *win, int swinid); -void wmSubWindowScissorSet (struct wmWindow *win, int swinid, struct rcti *srct); +void wmSubWindowScissorSet (struct wmWindow *win, int swinid, const struct rcti *srct, bool srct_pad); /* OpenGL utilities with safety check + working in modelview matrix mode */ void wmFrustum (float x1, float x2, float y1, float y2, float n, float f); diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 3e9dc0f10c8..dac62d624b5 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -569,7 +569,7 @@ static void wm_draw_region_blend(wmWindow *win, ARegion *ar) /* region blend always is 1, except when blend timer is running */ if (fac < 1.0f) { - wmSubWindowScissorSet(win, win->screen->mainwin, &ar->winrct); + wmSubWindowScissorSet(win, win->screen->mainwin, &ar->winrct, true); glEnable(GL_BLEND); wm_triple_draw_textures(win, win->drawdata, 1.0f - fac); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index f8546ad441a..b4f193bdbe6 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -132,6 +132,14 @@ void wm_event_free_all(wmWindow *win) } } +void wm_event_init_from_window(wmWindow *win, wmEvent *event) +{ + /* make sure we don't copy any owned pointers */ + BLI_assert(win->eventstate->tablet_data == NULL); + + *event = *(win->eventstate); +} + /* ********************* notifiers, listeners *************** */ static int wm_test_duplicate_notifier(wmWindowManager *wm, unsigned int type, void *reference) @@ -274,7 +282,7 @@ void wm_event_do_notifiers(bContext *C) } if (note->window == win || - (note->window == NULL && (note->reference == NULL || note->reference == CTX_data_scene(C)))) + (note->window == NULL && (note->reference == NULL || note->reference == win->screen->scene))) { if (note->category == NC_SCENE) { if (note->data == ND_FRAME) @@ -282,7 +290,7 @@ void wm_event_do_notifiers(bContext *C) } } if (ELEM5(note->category, NC_SCENE, NC_OBJECT, NC_GEOM, NC_SCENE, NC_WM)) { - ED_info_stats_clear(CTX_data_scene(C)); + ED_info_stats_clear(win->screen->scene); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO, NULL); } } @@ -445,7 +453,9 @@ static void wm_handler_ui_cancel(bContext *C) nexthandler = handler->next; if (handler->ui_handle) { - wmEvent event = *(win->eventstate); + wmEvent event; + + wm_event_init_from_window(win, &event); event.type = EVT_BUT_CANCEL; handler->ui_handle(C, &event, handler->ui_userdata); } @@ -972,7 +982,7 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, WM_operator_last_properties_init(op); } - if ((G.debug & G_DEBUG_HANDLERS) && event && event->type != MOUSEMOVE) { + if ((G.debug & G_DEBUG_HANDLERS) && ((event == NULL) || (event->type != MOUSEMOVE))) { printf("%s: handle evt %d win %d op %s\n", __func__, event ? event->type : 0, CTX_wm_screen(C)->subwinactive, ot->idname); } diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 13230f48a15..ff805579b44 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -795,6 +795,7 @@ const char *WM_key_event_string(short type) int WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, const int len) { char buf[128]; + char *p = buf; buf[0] = 0; @@ -803,28 +804,28 @@ int WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, const int len) kmi->alt == KM_ANY && kmi->oskey == KM_ANY) { - strcat(buf, "Any "); + p += BLI_strcpy_rlen(p, "Any "); } else { if (kmi->shift) - strcat(buf, "Shift "); + p += BLI_strcpy_rlen(p, "Shift "); if (kmi->ctrl) - strcat(buf, "Ctrl "); + p += BLI_strcpy_rlen(p, "Ctrl "); if (kmi->alt) - strcat(buf, "Alt "); + p += BLI_strcpy_rlen(p, "Alt "); if (kmi->oskey) - strcat(buf, "Cmd "); + p += BLI_strcpy_rlen(p, "Cmd "); } if (kmi->keymodifier) { - strcat(buf, WM_key_event_string(kmi->keymodifier)); - strcat(buf, " "); + p += BLI_strcpy_rlen(p, WM_key_event_string(kmi->keymodifier)); + p += BLI_strcpy_rlen(p, " "); } - strcat(buf, WM_key_event_string(kmi->type)); + p += BLI_strcpy_rlen(p, WM_key_event_string(kmi->type)); return BLI_strncpy_rlen(str, buf, len); } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index ddc48ce6332..f1a9f6dc007 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -978,7 +978,7 @@ static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op) uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */ uiEndBlock(C, block); - event = *(win->eventstate); /* XXX huh huh? make api call */ + wm_event_init_from_window(win, &event); event.type = EVT_BUT_OPEN; event.val = KM_PRESS; event.customdata = but; @@ -1751,7 +1751,7 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *UNUSED(arg_ uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */ uiEndBlock(C, block); - event = *(win->eventstate); /* XXX huh huh? make api call */ + wm_event_init_from_window(win, &event); event.type = EVT_BUT_OPEN; event.val = KM_PRESS; event.customdata = but; @@ -2614,7 +2614,7 @@ static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot) ot->poll = WM_operator_winactive; } -static int wm_exit_blender_op(bContext *C, wmOperator *op) +static int wm_exit_blender_exec(bContext *C, wmOperator *op) { WM_operator_free(op); @@ -2630,7 +2630,7 @@ static void WM_OT_quit_blender(wmOperatorType *ot) ot->description = "Quit Blender"; ot->invoke = WM_operator_confirm; - ot->exec = wm_exit_blender_op; + ot->exec = wm_exit_blender_exec; ot->poll = WM_operator_winactive; } @@ -2638,7 +2638,7 @@ static void WM_OT_quit_blender(wmOperatorType *ot) #if defined(WIN32) -static int wm_console_toggle_op(bContext *UNUSED(C), wmOperator *UNUSED(op)) +static int wm_console_toggle_exec(bContext *UNUSED(C), wmOperator *UNUSED(op)) { GHOST_toggleConsole(2); return OPERATOR_FINISHED; @@ -2651,7 +2651,7 @@ static void WM_OT_console_toggle(wmOperatorType *ot) ot->idname = "WM_OT_console_toggle"; ot->description = N_("Toggle System Console"); - ot->exec = wm_console_toggle_op; + ot->exec = wm_console_toggle_exec; ot->poll = WM_operator_winactive; } @@ -2988,7 +2988,7 @@ static void tweak_gesture_modal(bContext *C, const wmEvent *event) if ((val = wm_gesture_evaluate(gesture))) { wmEvent tevent; - tevent = *(window->eventstate); + wm_event_init_from_window(window, &tevent); if (gesture->event_type == LEFTMOUSE) tevent.type = EVT_TWEAK_L; else if (gesture->event_type == RIGHTMOUSE) diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index 01bebe8a1b8..4ad4286b657 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -239,7 +239,7 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct) static wmWindow *_curwindow = NULL; static wmSubWindow *_curswin = NULL; -void wmSubWindowScissorSet(wmWindow *win, int swinid, rcti *srct) +void wmSubWindowScissorSet(wmWindow *win, int swinid, const rcti *srct, bool srct_pad) { int width, height; _curswin = swin_from_swinid(win, swinid); @@ -257,8 +257,16 @@ void wmSubWindowScissorSet(wmWindow *win, int swinid, rcti *srct) glViewport(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height); if (srct) { - int scissor_width = BLI_rcti_size_x(srct) + 1; /* only here */ - int scissor_height = BLI_rcti_size_y(srct) + 1; + int scissor_width = BLI_rcti_size_x(srct); + int scissor_height = BLI_rcti_size_y(srct); + + /* typically a single pixel doesn't matter, + * but one pixel offset is noticable with viewport border render */ + if (srct_pad) { + scissor_width += 1; + scissor_height += 1; + } + glScissor(srct->xmin, srct->ymin, scissor_width, scissor_height); } else @@ -273,7 +281,7 @@ void wmSubWindowScissorSet(wmWindow *win, int swinid, rcti *srct) /* enable the WM versions of opengl calls */ void wmSubWindowSet(wmWindow *win, int swinid) { - wmSubWindowScissorSet(win, swinid, NULL); + wmSubWindowScissorSet(win, swinid, NULL, true); } void wmFrustum(float x1, float x2, float y1, float y2, float n, float f) diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index e0595e3c8ab..062107f834e 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -808,7 +808,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr * currently it seems to be common practice to generate new event for, but probably * we'll need utility function for this? (sergey) */ - event = *(win->eventstate); + wm_event_init_from_window(win, &event); event.type = MOUSEMOVE; event.prevx = event.x; event.prevy = event.y; @@ -957,7 +957,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr win->eventstate->x = wx; win->eventstate->y = wy; - event = *(win->eventstate); /* copy last state, like mouse coords */ + wm_event_init_from_window(win, &event); /* copy last state, like mouse coords */ /* activate region */ event.type = MOUSEMOVE; @@ -1065,7 +1065,8 @@ static int wm_window_timer(const bContext *C) else if (wt->event_type == TIMERAUTOSAVE) wm_autosave_timer(C, wm, wt); else if (win) { - wmEvent event = *(win->eventstate); + wmEvent event; + wm_event_init_from_window(win, &event); event.type = wt->event_type; event.val = 0; @@ -1323,6 +1324,16 @@ void wm_window_swap_buffers(wmWindow *win) #endif } +void wm_window_set_swap_interval (wmWindow *win, int interval) +{ + GHOST_SetSwapInterval(win->ghostwin, interval); +} + +int wm_window_get_swap_interval (wmWindow *win) +{ + return GHOST_GetSwapInterval(win->ghostwin); +} + /* ******************* exported api ***************** */ diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h index 22fa2423f61..d7e938fec7c 100644 --- a/source/blender/windowmanager/wm_window.h +++ b/source/blender/windowmanager/wm_window.h @@ -58,6 +58,8 @@ void wm_window_lower (wmWindow *win); void wm_window_set_size (wmWindow *win, int width, int height); void wm_window_get_position (wmWindow *win, int *posx_r, int *posy_r); void wm_window_swap_buffers (wmWindow *win); +void wm_window_set_swap_interval (wmWindow *win, int interval); +int wm_window_get_swap_interval (wmWindow *win); void wm_get_cursor_position (wmWindow *win, int *x, int *y); diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index ca57299fe1e..21502492c05 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -226,6 +226,7 @@ struct wmTimer *WM_event_add_timer(struct wmWindowManager *wm, struct wmWindow * void WM_event_remove_timer(struct wmWindowManager *wm, struct wmWindow *win, struct wmTimer *timer) {STUB_ASSERT(0);} void ED_armature_edit_bone_remove(struct bArmature *arm, struct EditBone *exBone) {STUB_ASSERT(0);} void object_test_constraints(struct Object *owner) {STUB_ASSERT(0);} +void ED_armature_ebone_to_mat4(struct EditBone *ebone, float mat[4][4]) {STUB_ASSERT(0);} void ED_object_parent(struct Object *ob, struct Object *par, int type, const char *substr) {STUB_ASSERT(0);} void ED_object_constraint_set_active(struct Object *ob, struct bConstraint *con) {STUB_ASSERT(0);} void ED_node_composit_default(struct bContext *C, struct Scene *scene) {STUB_ASSERT(0);} diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index dbb7cbc1816..7b5f5a7096a 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -284,6 +284,14 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); else canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE); + + // Setup vsync + int previous_vsync = canvas->GetSwapInterval(); + if (startscene->gm.vsync == VSYNC_ADAPTIVE) + canvas->SetSwapInterval(-1); + else + canvas->SetSwapInterval(startscene->gm.vsync); // VSYNC_OFF == 0, VSYNC_ON == 1, so this works + RAS_IRenderTools* rendertools = new KX_BlenderRenderTools(); RAS_IRasterizer* rasterizer = NULL; //Don't use displaylists with VBOs @@ -371,7 +379,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c // to the original file working directory if (exitstring != "") - strcpy(basedpath, exitstring.Ptr()); + BLI_strncpy(basedpath, exitstring.ReadPtr(), sizeof(basedpath)); // load relative to the last loaded file, this used to be relative // to the first file but that makes no sense, relative paths in @@ -384,9 +392,8 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c if (!bfd) { // just add "//" in front of it - char temppath[242]; - strcpy(temppath, "//"); - strcat(temppath, basedpath); + char temppath[FILE_MAX] = "//"; + BLI_strncpy(temppath + 2, basedpath, FILE_MAX - 2); BLI_path_abs(temppath, pathname); bfd = load_game_data(temppath); @@ -664,6 +671,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c } if (canvas) { + canvas->SetSwapInterval(previous_vsync); // Set the swap interval back delete canvas; canvas = NULL; } diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp index 3bd1c02f12e..3089b3fd44d 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp @@ -66,6 +66,16 @@ void KX_BlenderCanvas::SwapBuffers() BL_SwapBuffers(m_win); } +void KX_BlenderCanvas::SetSwapInterval(int interval) +{ + BL_SetSwapInterval(m_win, interval); +} + +int KX_BlenderCanvas::GetSwapInterval() +{ + return BL_GetSwapInterval(m_win); +} + void KX_BlenderCanvas::ResizeWindow(int width, int height) { // Not implemented for the embedded player diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h index c201d866efe..c5318b882fa 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h @@ -80,6 +80,16 @@ public: void SwapBuffers( ); + + void + SetSwapInterval( + int interval + ); + + int + GetSwapInterval( + ); + void ResizeWindow( int width, diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp index 61598995040..6ed4866579c 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp @@ -98,6 +98,16 @@ void BL_MakeDrawable(wmWindowManager *wm, wmWindow *win) wm_window_make_drawable(wm, win); } +void BL_SetSwapInterval(struct wmWindow *win, int interval) +{ + wm_window_set_swap_interval(win, interval); +} + +int BL_GetSwapInterval(struct wmWindow *win) +{ + return wm_window_get_swap_interval(win); +} + static void DisableForText() { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); /* needed for texture fonts otherwise they render as wireframe */ diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.h b/source/gameengine/BlenderRoutines/KX_BlenderGL.h index 54e76ff6489..8032d9a594a 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderGL.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.h @@ -43,6 +43,8 @@ struct wmWindowManager; // special swapbuffers, that takes care of which area (viewport) needs to be swapped void BL_SwapBuffers(struct wmWindow *win); +void BL_SetSwapInterval(struct wmWindow *win, int interval); +int BL_GetSwapInterval(struct wmWindow *win); void BL_MakeDrawable(struct wmWindowManager *wm, struct wmWindow *win); diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp index db9445b728d..a6b71e0bc43 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp @@ -37,6 +37,7 @@ #include "RAS_LightObject.h" #include "RAS_ICanvas.h" #include "RAS_GLExtensionManager.h" +#include "RAS_MeshObject.h" #include "KX_GameObject.h" #include "KX_PolygonMaterial.h" @@ -157,6 +158,11 @@ void KX_BlenderRenderTools::SetClientObject(RAS_IRasterizer *rasty, void* obj) bool KX_BlenderRenderTools::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void * const data) { double* const oglmatrix = (double* const) data; + + RAS_Polygon* poly = result->m_hitMesh->GetPolygon(result->m_hitPolygon); + if (!poly->IsVisible()) + return false; + MT_Point3 resultpoint(result->m_hitPoint); MT_Vector3 resultnormal(result->m_hitNormal); MT_Vector3 left(oglmatrix[0],oglmatrix[1],oglmatrix[2]); @@ -219,7 +225,7 @@ void KX_BlenderRenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmat } MT_Vector3 left = dir.normalized(); - dir = (left.cross(up)).normalized(); + dir = (up.cross(left)).normalized(); // we have calculated the row vectors, now we keep // local scaling into account: diff --git a/source/gameengine/Converter/BL_ArmatureConstraint.cpp b/source/gameengine/Converter/BL_ArmatureConstraint.cpp index 131fdaed3ec..1e6e3557aa4 100644 --- a/source/gameengine/Converter/BL_ArmatureConstraint.cpp +++ b/source/gameengine/Converter/BL_ArmatureConstraint.cpp @@ -189,7 +189,7 @@ void BL_ArmatureConstraint::UpdateTarget() if (m_blendsubtarget && m_subtarget) { m_subtarget->UpdateBlenderObjectMatrix(m_blendsubtarget); if (m_subpose && m_subtarget->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) - m_blendsubtarget->pose = ((BL_ArmatureObject*)m_target)->GetOrigPose(); + m_blendsubtarget->pose = ((BL_ArmatureObject*)m_subtarget)->GetOrigPose(); } } } diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 7a53144657d..98af99825e1 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -1143,7 +1143,7 @@ KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openl /* needed for lookups*/ GetMainDynamic().push_back(main_newlib); - strncpy(main_newlib->name, path, sizeof(main_newlib->name)); + BLI_strncpy(main_newlib->name, path, sizeof(main_newlib->name)); status = new KX_LibLoadStatus(this, m_ketsjiEngine, scene_merge, path); diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 05da38dd1af..5b528972e00 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -319,26 +319,20 @@ void BL_ConvertActuators(const char* maggiename, /* Get the name of the properties that objects must own that * we're sending to, if present */ - STR_String toPropName = (msgAct->toPropName - ? (char*) msgAct->toPropName - : ""); + STR_String toPropName = msgAct->toPropName; /* Get the Message Subject to send. */ - STR_String subject = (msgAct->subject - ? (char*) msgAct->subject - : ""); + STR_String subject = msgAct->subject; /* Get the bodyType */ int bodyType = msgAct->bodyType; - + /* Get the body (text message or property name whose value * we'll be sending, might be empty */ - STR_String body = (msgAct->body - ? (char*) msgAct->body - : ""); + const STR_String body = msgAct->body; KX_NetworkMessageActuator *tmpmsgact = new KX_NetworkMessageActuator( gameobj, // actuator controlling object diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp index acaf911c26e..1aae2738311 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.cpp +++ b/source/gameengine/Converter/KX_ConvertSensors.cpp @@ -177,9 +177,8 @@ void BL_ConvertSensors(struct Object* blenderobject, bTouchPulse = (blendertouchsensor->mode & SENS_COLLISION_PULSE); - STR_String touchPropOrMatName = ( bFindMaterial ? - blendertouchsensor->materialName: - (blendertouchsensor->name ? blendertouchsensor->name: "")); + const STR_String touchPropOrMatName = bFindMaterial ? + blendertouchsensor->materialName : blendertouchsensor->name; if (gameobj->GetPhysicsController()) @@ -229,9 +228,7 @@ void BL_ConvertSensors(struct Object* blenderobject, /* Get our NetworkScene */ NG_NetworkScene *NetworkScene = kxscene->GetNetworkScene(); /* filter on the incoming subjects, might be empty */ - STR_String subject = (msgSens->subject - ? (char*)msgSens->subject - : ""); + const STR_String subject = msgSens->subject; gamesensor = new KX_NetworkMessageSensor( eventmgr, // our eventmanager @@ -247,14 +244,9 @@ void BL_ConvertSensors(struct Object* blenderobject, SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR); if (eventmgr) { - STR_String nearpropertyname; bNearSensor* blendernearsensor = (bNearSensor*)sens->data; - if (blendernearsensor->name) - { - // only objects that own this property will be taken into account - nearpropertyname = (char*) blendernearsensor->name; - } - + const STR_String nearpropertyname = (char *)blendernearsensor->name; + //DT_ShapeHandle shape = DT_Sphere(0.0); // this sumoObject is not deleted by a gameobj, so delete it ourself @@ -453,18 +445,11 @@ void BL_ConvertSensors(struct Object* blenderobject, SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR); if (eventmgr) { - STR_String radarpropertyname; - STR_String touchpropertyname; bRadarSensor* blenderradarsensor = (bRadarSensor*) sens->data; + const STR_String radarpropertyname = blenderradarsensor->name; int radaraxis = blenderradarsensor->axis; - if (blenderradarsensor->name) - { - // only objects that own this property will be taken into account - radarpropertyname = (char*) blenderradarsensor->name; - } - MT_Scalar coneheight = blenderradarsensor->range; // janco: the angle was doubled, so should I divide the factor in 2 diff --git a/source/gameengine/Expressions/FloatValue.cpp b/source/gameengine/Expressions/FloatValue.cpp index b7d7f528155..0f468e328ed 100644 --- a/source/gameengine/Expressions/FloatValue.cpp +++ b/source/gameengine/Expressions/FloatValue.cpp @@ -97,7 +97,7 @@ ret: a new object containing the result of applying operator op to this return new CFloatValue (-m_float); break; case VALUE_NOT_OPERATOR: - return new CErrorValue (op2str(op) + "only allowed on booleans"); + return new CBoolValue (m_float == 0.f); break; case VALUE_AND_OPERATOR: case VALUE_OR_OPERATOR: @@ -160,6 +160,9 @@ ret: a new object containing the result of applying operator op to val and case VALUE_LEQ_OPERATOR: ret = new CBoolValue(((CIntValue *) val)->GetInt() <= m_float); break; + case VALUE_NOT_OPERATOR: + ret = new CBoolValue(m_float == 0); + break; default: ret = new CErrorValue("illegal operator. please send a bug report."); break; @@ -212,7 +215,9 @@ ret: a new object containing the result of applying operator op to val and case VALUE_POS_OPERATOR: ret = new CFloatValue (m_float); break; - + case VALUE_NOT_OPERATOR: + ret = new CBoolValue(m_float == 0); + break; default: ret = new CErrorValue("illegal operator. please send a bug report."); break; diff --git a/source/gameengine/Expressions/IntValue.cpp b/source/gameengine/Expressions/IntValue.cpp index 2cacea98467..fa4c9ad8ac9 100644 --- a/source/gameengine/Expressions/IntValue.cpp +++ b/source/gameengine/Expressions/IntValue.cpp @@ -96,7 +96,7 @@ object and val return new CIntValue (-m_int); break; case VALUE_NOT_OPERATOR: - return new CErrorValue (op2str(op) + "only allowed on booleans"); + return new CBoolValue (m_int == 0); break; case VALUE_AND_OPERATOR: case VALUE_OR_OPERATOR: @@ -170,7 +170,11 @@ CValue* CIntValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *v case VALUE_POS_OPERATOR: ret = new CIntValue (m_int); break; + case VALUE_NOT_OPERATOR: + ret = new CBoolValue(m_int == 0); + break; default: + printf("Found op: %d\n", op); ret = new CErrorValue("illegal operator. please send a bug report."); break; } @@ -215,6 +219,9 @@ CValue* CIntValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *v case VALUE_LEQ_OPERATOR: ret = new CBoolValue(((CFloatValue *) val)->GetFloat() <= m_int); break; + case VALUE_NOT_OPERATOR: + ret = new CBoolValue(m_int == 0); + break; default: ret = new CErrorValue("illegal operator. please send a bug report."); break; diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp index 70a05f7425b..e8c29d5aa4f 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp @@ -37,6 +37,7 @@ #include "RAS_LightObject.h" #include "RAS_ICanvas.h" #include "RAS_GLExtensionManager.h" +#include "RAS_MeshObject.h" #include "KX_GameObject.h" #include "KX_PolygonMaterial.h" @@ -166,6 +167,11 @@ void GPC_RenderTools::SetClientObject(RAS_IRasterizer *rasty, void* obj) bool GPC_RenderTools::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void * const data) { double* const oglmatrix = (double* const) data; + + RAS_Polygon* poly = result->m_hitMesh->GetPolygon(result->m_hitPolygon); + if (!poly->IsVisible()) + return false; + MT_Point3 resultpoint(result->m_hitPoint); MT_Vector3 resultnormal(result->m_hitNormal); MT_Vector3 left(oglmatrix[0],oglmatrix[1],oglmatrix[2]); diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index bedee5d9a47..c3cbf381af4 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -582,7 +582,12 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) m_canvas = new GPG_Canvas(window); if (!m_canvas) return false; - + + if (gm->vsync == VSYNC_ADAPTIVE) + m_canvas->SetSwapInterval(-1); + else + m_canvas->SetSwapInterval(gm->vsync); // VSYNC_OFF == 0, VSYNC_ON == 1, so this works + m_canvas->Init(); if (gm->flag & GAME_SHOW_MOUSE) m_canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); @@ -787,9 +792,6 @@ void GPG_Application::stopEngine() } m_pyGlobalDictString_Length = saveGamePythonConfig(&m_pyGlobalDictString); - - // when exiting the mainloop - exitGamePythonScripting(); #endif m_ketsjiengine->StopEngine(); @@ -803,6 +805,7 @@ void GPG_Application::stopEngine() m_system->removeTimer(m_frameTimer); m_frameTimer = 0; } + m_engineRunning = false; } @@ -880,6 +883,11 @@ void GPG_Application::exitEngine() GPU_extensions_exit(); +#ifdef WITH_PYTHON + // Call this after we're sure nothing needs Python anymore (e.g., destructors) + exitGamePlayerPythonScripting(); +#endif + m_exitRequested = 0; m_engineInitialized = false; } diff --git a/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp b/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp index a1d00dad0e1..e0559385ee6 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp @@ -107,6 +107,20 @@ void GPG_Canvas::SwapBuffers() } } +void GPG_Canvas::SetSwapInterval(int interval) +{ + if (m_window) + m_window->setSwapInterval(interval); +} + +int GPG_Canvas::GetSwapInterval() +{ + if (m_window) + return m_window->getSwapInterval(); + + return 0; +} + void GPG_Canvas::ResizeWindow(int width, int height) { if (m_window->getState() == GHOST_kWindowStateFullScreen) diff --git a/source/gameengine/GamePlayer/ghost/GPG_Canvas.h b/source/gameengine/GamePlayer/ghost/GPG_Canvas.h index 6168d96b337..6e1f86cac0e 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Canvas.h +++ b/source/gameengine/GamePlayer/ghost/GPG_Canvas.h @@ -55,6 +55,9 @@ public: virtual void SetMousePosition(int x, int y); virtual void SetMouseState(RAS_MouseState mousestate); virtual void SwapBuffers(); + virtual void SetSwapInterval(int interval); + virtual int GetSwapInterval(); + virtual int GetMouseX(int x) { return x; } virtual int GetMouseY(int y) { return y; } virtual float GetMouseNormalizedX(int x); diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index f1edb71f4fe..ccbcdd25639 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -118,6 +118,14 @@ static void mem_error_cb(const char *errorStr) fflush(stderr); } +// library.c will only free window managers with a callback function. +// We don't actually use a wmWindowManager, but loading a blendfile +// loads wmWindows, so we need to free those. +static void wm_free(bContext *C, wmWindowManager *wm) +{ + BLI_freelistN(&wm->windows); +} + #ifdef WIN32 typedef enum { SCREEN_SAVER_MODE_NONE = 0, @@ -501,6 +509,8 @@ int main(int argc, char** argv) sound_init_once(); + set_free_windowmanager_cb(wm_free); + /* if running blenderplayer the last argument can't be parsed since it has to be the filename. */ isBlenderPlayer = !BLO_is_a_runtime(argv[0]); if (isBlenderPlayer) @@ -813,9 +823,8 @@ int main(int argc, char** argv) if (!bfd) { // just add "//" in front of it - char temppath[242]; - strcpy(temppath, "//"); - strcat(temppath, basedpath); + char temppath[FILE_MAX] = "//"; + BLI_strncpy(temppath + 2, basedpath, FILE_MAX - 2); BLI_path_abs(temppath, pathname); bfd = load_game_data(temppath); diff --git a/source/gameengine/Ketsji/BL_ActionManager.cpp b/source/gameengine/Ketsji/BL_ActionManager.cpp index f3620a7b4ba..e3402972ca6 100644 --- a/source/gameengine/Ketsji/BL_ActionManager.cpp +++ b/source/gameengine/Ketsji/BL_ActionManager.cpp @@ -41,8 +41,6 @@ BL_ActionManager::~BL_ActionManager() float BL_ActionManager::GetActionFrame(short layer) { return m_layers[layer]->GetFrame(); - - return 0.f; } void BL_ActionManager::SetActionFrame(short layer, float frame) @@ -53,8 +51,6 @@ void BL_ActionManager::SetActionFrame(short layer, float frame) struct bAction *BL_ActionManager::GetCurrentAction(short layer) { return m_layers[layer]->GetAction(); - - return 0; } void BL_ActionManager::SetPlayMode(short layer, short mode) @@ -92,8 +88,6 @@ void BL_ActionManager::StopAction(short layer) bool BL_ActionManager::IsActionDone(short layer) { return m_layers[layer]->IsDone(); - - return true; } void BL_ActionManager::Update(float curtime) diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 630b2f0b32a..28abdc898ae 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -157,6 +157,11 @@ Material *KX_BlenderMaterial::GetBlenderMaterial() const return mMaterial->material; } +Image *KX_BlenderMaterial::GetBlenderImage() const +{ + return mMaterial->tface.tpage; +} + Scene* KX_BlenderMaterial::GetBlenderScene() const { return mScene->GetBlenderScene(); diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index c34a49e1bde..0a2675f04a8 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -78,6 +78,7 @@ public: )const; Material* GetBlenderMaterial() const; + Image* GetBlenderImage() const; MTFace* GetMTFace(void) const; unsigned int* GetMCol(void) const; BL_Texture * getTex (unsigned int idx) { diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index 0cd06a7b6eb..73ebf89bea3 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -521,6 +521,7 @@ PyAttributeDef KX_Camera::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("perspective", KX_Camera, pyattr_get_perspective, pyattr_set_perspective), KX_PYATTRIBUTE_RW_FUNCTION("lens", KX_Camera, pyattr_get_lens, pyattr_set_lens), + KX_PYATTRIBUTE_RW_FUNCTION("fov", KX_Camera, pyattr_get_fov, pyattr_set_fov), KX_PYATTRIBUTE_RW_FUNCTION("ortho_scale", KX_Camera, pyattr_get_ortho_scale, pyattr_set_ortho_scale), KX_PYATTRIBUTE_RW_FUNCTION("near", KX_Camera, pyattr_get_near, pyattr_set_near), KX_PYATTRIBUTE_RW_FUNCTION("far", KX_Camera, pyattr_get_far, pyattr_set_far), @@ -752,6 +753,35 @@ int KX_Camera::pyattr_set_lens(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, return PY_SET_ATTR_SUCCESS; } +PyObject *KX_Camera::pyattr_get_fov(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_Camera* self = static_cast<KX_Camera*>(self_v); + + float lens = self->m_camdata.m_lens; + float width = self->m_camdata.m_sensor_x; + float fov = 2.0 * atan(0.5 * width / lens); + + return PyFloat_FromDouble(fov * MT_DEGS_PER_RAD); +} + +int KX_Camera::pyattr_set_fov(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_Camera* self = static_cast<KX_Camera*>(self_v); + float fov = PyFloat_AsDouble(value); + if (fov <= 0.0) { + PyErr_SetString(PyExc_AttributeError, "camera.fov = float: KX_Camera, expected a float greater then zero"); + return PY_SET_ATTR_FAIL; + } + + fov *= MT_RADS_PER_DEG; + float width = self->m_camdata.m_sensor_x; + float lens = width / (2.0 * tan(0.5 * fov)); + + self->m_camdata.m_lens= lens; + self->m_set_projection_matrix = false; + return PY_SET_ATTR_SUCCESS; +} + PyObject *KX_Camera::pyattr_get_ortho_scale(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_Camera* self = static_cast<KX_Camera*>(self_v); diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index f615fefc223..454c4a54ec1 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -298,6 +298,8 @@ public: static PyObject* pyattr_get_lens(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_lens(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + static PyObject* pyattr_get_fov(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_fov(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject* pyattr_get_ortho_scale(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_ortho_scale(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject* pyattr_get_near(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index aa082c7ef19..85fa0b2b3ce 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -401,21 +401,21 @@ void KX_Dome::GLDrawWarpQuads(void) if (warp.nodes[i][j].i < 0 || warp.nodes[i+1][j].i < 0 || warp.nodes[i+1][j+1].i < 0 || warp.nodes[i][j+1].i < 0) continue; - glColor3f(warp.nodes[i][j].i, warp.nodes[i][j].i, warp.nodes[i][j].i); - glTexCoord2f((warp.nodes[i][j].u * uv_width), (warp.nodes[i][j].v * uv_height)); - glVertex3f(warp.nodes[i][j].x, warp.nodes[i][j].y,0.0); - - glColor3f(warp.nodes[i+1][j].i, warp.nodes[i+1][j].i, warp.nodes[i+1][j].i); - glTexCoord2f((warp.nodes[i+1][j].u * uv_width), (warp.nodes[i+1][j].v * uv_height)); - glVertex3f(warp.nodes[i+1][j].x, warp.nodes[i+1][j].y,0.0); + glColor3f(warp.nodes[i][j+1].i, warp.nodes[i][j+1].i, warp.nodes[i][j+1].i); + glTexCoord2f((warp.nodes[i][j+1].u * uv_width), (warp.nodes[i][j+1].v * uv_height)); + glVertex3f(warp.nodes[i][j+1].x, warp.nodes[i][j+1].y,0.0); glColor3f(warp.nodes[i+1][j+1].i, warp.nodes[i+1][j+1].i, warp.nodes[i+1][j+1].i); glTexCoord2f((warp.nodes[i+1][j+1].u * uv_width), (warp.nodes[i+1][j+1].v * uv_height)); glVertex3f(warp.nodes[i+1][j+1].x, warp.nodes[i+1][j+1].y,0.0); - glColor3f(warp.nodes[i][j+1].i, warp.nodes[i][j+1].i, warp.nodes[i][j+1].i); - glTexCoord2f((warp.nodes[i][j+1].u * uv_width), (warp.nodes[i][j+1].v * uv_height)); - glVertex3f(warp.nodes[i][j+1].x, warp.nodes[i][j+1].y,0.0); + glColor3f(warp.nodes[i+1][j].i, warp.nodes[i+1][j].i, warp.nodes[i+1][j].i); + glTexCoord2f((warp.nodes[i+1][j].u * uv_width), (warp.nodes[i+1][j].v * uv_height)); + glVertex3f(warp.nodes[i+1][j].x, warp.nodes[i+1][j].y,0.0); + + glColor3f(warp.nodes[i][j].i, warp.nodes[i][j].i, warp.nodes[i][j].i); + glTexCoord2f((warp.nodes[i][j].u * uv_width), (warp.nodes[i][j].v * uv_height)); + glVertex3f(warp.nodes[i][j].x, warp.nodes[i][j].y,0.0); } } glEnd(); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 360a337f852..32666ec0792 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -99,7 +99,8 @@ const char KX_KetsjiEngine::m_profileLabels[tc_numCategories][15] = { "Rasterizer:", // tc_rasterizer "Services:", // tc_services "Overhead:", // tc_overhead - "Outside:" // tc_outside + "Outside:", // tc_outside + "GPU Latency:" // tc_latency }; double KX_KetsjiEngine::m_ticrate = DEFAULT_LOGIC_TIC_RATE; @@ -542,7 +543,10 @@ void KX_KetsjiEngine::EndFrame() m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true); m_rasterizer->EndFrame(); // swap backbuffer (drawing into this buffer) <-> front/visible buffer + m_logger->StartLog(tc_latency, m_kxsystem->GetTimeInSeconds(), true); m_rasterizer->SwapBuffers(); + m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true); + m_rendertools->EndFrame(m_rasterizer); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 4dd8ea10e62..d5d7262a418 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -158,9 +158,10 @@ private: tc_network, tc_scenegraph, tc_rasterizer, - tc_services, // time spend in miscelaneous activities + tc_services, // time spent in miscelaneous activities tc_overhead, // profile info drawing overhead - tc_outside, // time spend outside main loop + tc_outside, // time spent outside main loop + tc_latency, // time spent waiting on the gpu tc_numCategories } KX_TimeCategory; diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index 8e803c46358..2a9d59e8b7b 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -303,7 +303,7 @@ PyObject *KX_MeshProxy::PyTransformUV(PyObject *args, PyObject *kwds) "mesh.transformUV(...): invalid uv_index %d", uvindex); return NULL; } - if (uvindex_from < -1 || uvindex_from > 1 || uvindex == -1) { + if (uvindex_from < -1 || uvindex_from > 1) { PyErr_Format(PyExc_ValueError, "mesh.transformUV(...): invalid uv_index_from %d", uvindex); return NULL; @@ -387,16 +387,13 @@ PyObject *KX_MeshProxy::pyattr_get_materials(void *self_v, const KX_PYATTRIBUTE_ for (i=0; i<tot; mit++, i++) { - RAS_IPolyMaterial *polymat = mit->m_bucket->GetPolyMaterial(); - - /* Why do we need to check for RAS_BLENDERMAT if both are cast to a (PyObject *)? - Campbell */ - if (polymat->GetFlag() & RAS_BLENDERMAT) - { - KX_BlenderMaterial *mat = static_cast<KX_BlenderMaterial*>(polymat); + RAS_IPolyMaterial *polymat = mit->m_bucket->GetPolyMaterial(); + if (polymat->GetFlag() & RAS_BLENDERMAT) { + KX_BlenderMaterial *mat = static_cast<KX_BlenderMaterial *>(polymat); PyList_SET_ITEM(materials, i, mat->GetProxy()); } else { - KX_PolygonMaterial *mat = static_cast<KX_PolygonMaterial*>(polymat); + KX_PolygonMaterial *mat = static_cast<KX_PolygonMaterial *>(polymat); PyList_SET_ITEM(materials, i, mat->GetProxy()); } } diff --git a/source/gameengine/Ketsji/KX_NavMeshObject.cpp b/source/gameengine/Ketsji/KX_NavMeshObject.cpp index 24400398f03..e45346db9c7 100644 --- a/source/gameengine/Ketsji/KX_NavMeshObject.cpp +++ b/source/gameengine/Ketsji/KX_NavMeshObject.cpp @@ -49,7 +49,7 @@ extern "C" { #include "DetourStatNavMeshBuilder.h" #include "KX_ObstacleSimulation.h" -static const int MAX_PATH_LEN = 256; +#define MAX_PATH_LEN 256 static const float polyPickExt[3] = {2, 4, 2}; static void calcMeshBounds(const float* vert, int nverts, float* bmin, float* bmax) @@ -120,14 +120,14 @@ bool KX_NavMeshObject::BuildVertIndArrays(float *&vertices, int& nverts, int nAllVerts = 0; float *allVerts = NULL; buildNavMeshDataByDerivedMesh(dm, &vertsPerPoly, &nAllVerts, &allVerts, &ndtris, &dtris, - &npolys, &dmeshes, &polys, &dtrisToPolysMap, &dtrisToTrisMap, &trisToFacesMap); + &npolys, &dmeshes, &polys, &dtrisToPolysMap, &dtrisToTrisMap, &trisToFacesMap); - MEM_freeN(dtrisToPolysMap); - MEM_freeN(dtrisToTrisMap); - MEM_freeN(trisToFacesMap); + MEM_SAFE_FREE(dtrisToPolysMap); + MEM_SAFE_FREE(dtrisToTrisMap); + MEM_SAFE_FREE(trisToFacesMap); unsigned short *verticesMap = new unsigned short[nAllVerts]; - memset(verticesMap, 0xffff, sizeof(unsigned short)*nAllVerts); + memset(verticesMap, 0xff, sizeof(*verticesMap) * nAllVerts); int curIdx = 0; //vertices - mesh verts //iterate over all polys and create map for their vertices first... @@ -214,7 +214,7 @@ bool KX_NavMeshObject::BuildVertIndArrays(float *&vertices, int& nverts, } } - MEM_freeN(allVerts); + MEM_SAFE_FREE(allVerts); } else { diff --git a/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp b/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp index 8798f42fa07..456f5f8af3b 100644 --- a/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp +++ b/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp @@ -36,65 +36,19 @@ namespace { inline float perp(const MT_Vector2& a, const MT_Vector2& b) { return a.x()*b.y() - a.y()*b.x(); } - inline float sqr(float x) { return x*x; } - inline float lerp(float a, float b, float t) { return a + (b-a)*t; } + inline float sqr(float x) { return x * x; } + inline float lerp(float a, float b, float t) { return a + (b - a) * t; } inline float clamp(float a, float mn, float mx) { return a < mn ? mn : (a > mx ? mx : a); } - - inline float vdistsqr(const float* a, const float* b) { return sqr(b[0]-a[0]) + sqr(b[1]-a[1]); } - inline float vdist(const float* a, const float* b) { return sqrtf(vdistsqr(a,b)); } - inline void vcpy(float* a, const float* b) { a[0]=b[0]; a[1]=b[1]; } - inline float vdot(const float* a, const float* b) { return a[0]*b[0] + a[1]*b[1]; } -/* inline float vperp(const float* a, const float* b) { return a[0]*b[1] - a[1]*b[0]; } */ /* UNUSED */ - inline void vsub(float* v, const float* a, const float* b) { v[0] = a[0]-b[0]; v[1] = a[1]-b[1]; } - inline void vadd(float* v, const float* a, const float* b) { v[0] = a[0]+b[0]; v[1] = a[1]+b[1]; } - inline void vscale(float* v, const float* a, const float s) { v[0] = a[0]*s; v[1] = a[1]*s; } - inline void vset(float* v, float x, float y) { v[0]=x; v[1]=y; } - inline float vlensqr(const float* v) { return vdot(v,v); } - inline float vlen(const float* v) { return sqrtf(vlensqr(v)); } - inline void vlerp(float* v, const float* a, const float* b, float t) { v[0] = lerp(a[0], b[0], t); v[1] = lerp(a[1], b[1], t); } -/* inline void vmad(float* v, const float* a, const float* b, float s) { v[0] = a[0] + b[0]*s; v[1] = a[1] + b[1]*s; } */ /* UNUSED */ - inline void vnorm(float* v) - { - float d = vlen(v); - if (d > 0.0001f) - { - d = 1.0f/d; - v[0] *= d; - v[1] *= d; - } - } -} -inline float triarea(const float* a, const float* b, const float* c) -{ - return (b[0]*a[1] - a[0]*b[1]) + (c[0]*b[1] - b[0]*c[1]) + (a[0]*c[1] - c[0]*a[1]); -} - -static void closestPtPtSeg(const float* pt, - const float* sp, const float* sq, - float& t) -{ - float dir[2],diff[3]; - vsub(dir,sq,sp); - vsub(diff,pt,sp); - t = vdot(diff,dir); - if (t <= 0.0f) { t = 0; return; } - float d = vdot(dir,dir); - if (t >= d) { t = 1; return; } - t /= d; + inline void vset(float v[2], float x, float y) { v[0] = x; v[1] = y; } } -static float distPtSegSqr(const float* pt, const float* sp, const float* sq) -{ - float t; - closestPtPtSeg(pt, sp,sq, t); - float np[2]; - vlerp(np, sp,sq, t); - return vdistsqr(pt,np); -} +/* grr, seems moto provides no nice way to do this */ +#define MT_3D_AS_2D(v) MT_Vector2((v)[0], (v)[1]) -static int sweepCircleCircle(const MT_Vector3& pos0, const MT_Scalar r0, const MT_Vector2& v, - const MT_Vector3& pos1, const MT_Scalar r1, - float& tmin, float& tmax) +static int sweepCircleCircle( + const MT_Vector2 &pos0, const MT_Scalar r0, const MT_Vector2 &v, + const MT_Vector2 &pos1, const MT_Scalar r1, + float& tmin, float& tmax) { static const float EPS = 0.0001f; MT_Vector2 c0(pos0.x(), pos0.y()); @@ -114,9 +68,10 @@ static int sweepCircleCircle(const MT_Vector3& pos0, const MT_Scalar r0, const M return 1; } -static int sweepCircleSegment(const MT_Vector3& pos0, const MT_Scalar r0, const MT_Vector2& v, - const MT_Vector3& pa, const MT_Vector3& pb, const MT_Scalar sr, - float& tmin, float &tmax) +static int sweepCircleSegment( + const MT_Vector2 &pos0, const MT_Scalar r0, const MT_Vector2 &v, + const MT_Vector2& pa, const MT_Vector2 &pb, const MT_Scalar sr, + float& tmin, float &tmax) { // equation parameters MT_Vector2 c0(pos0.x(), pos0.y()); @@ -317,12 +272,12 @@ void KX_ObstacleSimulation::UpdateObstacles() obs->vel[1] = obs->m_gameObj->GetLinearVelocity().y(); // Update velocity history and calculate perceived (average) velocity. - vcpy(&obs->hvel[obs->hhead*2], obs->vel); + copy_v2_v2(&obs->hvel[obs->hhead * 2], obs->vel); obs->hhead = (obs->hhead+1) % VEL_HIST_SIZE; vset(obs->pvel,0,0); for (int j = 0; j < VEL_HIST_SIZE; ++j) - vadd(obs->pvel, obs->pvel, &obs->hvel[j*2]); - vscale(obs->pvel, obs->pvel, 1.0f/VEL_HIST_SIZE); + add_v2_v2v2(obs->pvel, obs->pvel, &obs->hvel[j * 2]); + mul_v2_fl(obs->pvel, 1.0f / VEL_HIST_SIZE); } } @@ -443,11 +398,11 @@ void KX_ObstacleSimulationTOI::AdjustObstacleVelocity(KX_Obstacle* activeObst, K // Fake dynamic constraint. float dv[2]; float vel[2]; - vsub(dv, activeObst->nvel, activeObst->vel); - float ds = vlen(dv); + sub_v2_v2v2(dv, activeObst->nvel, activeObst->vel); + float ds = len_v2(dv); if (ds > maxDeltaSpeed || ds<-maxDeltaSpeed) - vscale(dv, dv, fabs(maxDeltaSpeed/ds)); - vadd(vel, activeObst->vel, dv); + mul_v2_fl(dv, fabs(maxDeltaSpeed / ds)); + add_v2_v2v2(vel, activeObst->vel, dv); velocity.x() = vel[0]; velocity.y() = vel[1]; @@ -524,8 +479,7 @@ void KX_ObstacleSimulationTOI_rays::sampleRVO(KX_Obstacle* activeObst, KX_NavMes if (ob->m_shape == KX_OBSTACLE_CIRCLE) { MT_Vector2 vab; - if (vlen(ob->vel) < 0.01f*0.01f) - { + if (len_v2(ob->vel) < 0.01f * 0.01f) { // Stationary, use VO vab = svel; } @@ -535,9 +489,11 @@ void KX_ObstacleSimulationTOI_rays::sampleRVO(KX_Obstacle* activeObst, KX_NavMes vab = 2*svel - vel - ob->vel; } - if (!sweepCircleCircle(activeObst->m_pos, activeObst->m_rad, - vab, ob->m_pos, ob->m_rad, htmin, htmax)) + if (!sweepCircleCircle(MT_3D_AS_2D(activeObst->m_pos), activeObst->m_rad, + vab, MT_3D_AS_2D(ob->m_pos), ob->m_rad, htmin, htmax)) + { continue; + } } else if (ob->m_shape == KX_OBSTACLE_SEGMENT) { @@ -550,9 +506,12 @@ void KX_ObstacleSimulationTOI_rays::sampleRVO(KX_Obstacle* activeObst, KX_NavMes p1 = navmeshobj->TransformToWorldCoords(p1); p2 = navmeshobj->TransformToWorldCoords(p2); } - if (!sweepCircleSegment(activeObst->m_pos, activeObst->m_rad, svel, - p1, p2, ob->m_rad, htmin, htmax)) + + if (!sweepCircleSegment(MT_3D_AS_2D(activeObst->m_pos), activeObst->m_rad, svel, + MT_3D_AS_2D(p1), MT_3D_AS_2D(p2), ob->m_rad, htmin, htmax)) + { continue; + } } else { continue; @@ -591,8 +550,7 @@ void KX_ObstacleSimulationTOI_rays::sampleRVO(KX_Obstacle* activeObst, KX_NavMes tc.toie[iter] = tmine; } - if (vlen(activeObst->vel) > 0.1) - { + if (len_v2(activeObst->vel) > 0.1f) { // Constrain max turn rate. float cura = atan2(activeObst->vel[1],activeObst->vel[0]); float da = bestDir - cura; @@ -622,21 +580,20 @@ void KX_ObstacleSimulationTOI_rays::sampleRVO(KX_Obstacle* activeObst, KX_NavMes ///////////********* TOI_cells**********///////////////// static void processSamples(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj, - KX_Obstacles& obstacles, float levelHeight, const float vmax, - const float* spos, const float cs, const int nspos, float* res, - float maxToi, float velWeight, float curVelWeight, float sideWeight, - float toiWeight) + KX_Obstacles& obstacles, float levelHeight, const float vmax, + const float* spos, const float cs, const int nspos, float* res, + float maxToi, float velWeight, float curVelWeight, float sideWeight, + float toiWeight) { vset(res, 0,0); const float ivmax = 1.0f / vmax; float adir[2] /*, adist */; - vcpy(adir, activeObst->pvel); - if (vlen(adir) > 0.01f) - vnorm(adir); - else - vset(adir,0,0); + if (normalize_v2_v2(adir, activeObst->pvel) <= 0.01f) { + zero_v2(adir); + } + float activeObstPos[2]; vset(activeObstPos, activeObst->m_pos.x(), activeObst->m_pos.y()); /* adist = vdot(adir, activeObstPos); */ @@ -646,7 +603,7 @@ static void processSamples(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavM for (int n = 0; n < nspos; ++n) { float vcand[2]; - vcpy(vcand, &spos[n*2]); + copy_v2_v2(vcand, &spos[n * 2]); // Find min time of impact and exit amongst all obstacles. float tmin = maxToi; @@ -666,9 +623,9 @@ static void processSamples(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavM float vab[2]; // Moving, use RVO - vscale(vab, vcand, 2); - vsub(vab, vab, activeObst->vel); - vsub(vab, vab, ob->vel); + mul_v2_v2fl(vab, vcand, 2); + sub_v2_v2v2(vab, vab, activeObst->vel); + sub_v2_v2v2(vab, vab, ob->vel); // Side // NOTE: dp, and dv are constant over the whole calculation, @@ -677,30 +634,31 @@ static void processSamples(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavM float pb[2]; vset(pb, ob->m_pos.x(), ob->m_pos.y()); - const float orig[2] = {0,0}; - float dp[2],dv[2],np[2]; - vsub(dp,pb,pa); - vnorm(dp); - vsub(dv,ob->dvel, activeObst->dvel); + const float orig[2] = {0, 0}; + float dp[2], dv[2], np[2]; + sub_v2_v2v2(dp, pb, pa); + normalize_v2(dp); + sub_v2_v2v2(dv, ob->dvel, activeObst->dvel); - const float a = triarea(orig, dp,dv); - if (a < 0.01f) - { + /* TODO: use line_point_side_v2 */ + if (area_tri_signed_v2(orig, dp, dv) < 0.01f) { np[0] = -dp[1]; np[1] = dp[0]; } - else - { + else { np[0] = dp[1]; np[1] = -dp[0]; } - side += clamp(min(vdot(dp,vab)*2,vdot(np,vab)*2), 0.0f, 1.0f); + side += clamp(min(dot_v2v2(dp, vab), + dot_v2v2(np, vab)) * 2.0f, 0.0f, 1.0f); nside++; - if (!sweepCircleCircle(activeObst->m_pos, activeObst->m_rad, vab, ob->m_pos, ob->m_rad, - htmin, htmax)) + if (!sweepCircleCircle(MT_3D_AS_2D(activeObst->m_pos), activeObst->m_rad, + vab, MT_3D_AS_2D(ob->m_pos), ob->m_rad, htmin, htmax)) + { continue; + } // Handle overlapping obstacles. if (htmin < 0.0f && htmax > 0.0f) @@ -729,14 +687,13 @@ static void processSamples(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavM // This can be handle more efficiently by using seg-seg test instead. // If the whole segment is to be treated as obstacle, use agent->rad instead of 0.01f! const float r = 0.01f; // agent->rad - if (distPtSegSqr(activeObstPos, p, q) < sqr(r+ob->m_rad)) - { + if (dist_squared_to_line_segment_v2(activeObstPos, p, q) < sqr(r + ob->m_rad)) { float sdir[2], snorm[2]; - vsub(sdir, q, p); + sub_v2_v2v2(sdir, q, p); snorm[0] = sdir[1]; snorm[1] = -sdir[0]; // If the velocity is pointing towards the segment, no collision. - if (vdot(snorm, vcand) < 0.0f) + if (dot_v2v2(snorm, vcand) < 0.0f) continue; // Else immediate collision. htmin = 0.0f; @@ -767,17 +724,16 @@ static void processSamples(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavM if (nside) side /= nside; - const float vpen = velWeight * (vdist(vcand, activeObst->dvel) * ivmax); - const float vcpen = curVelWeight * (vdist(vcand, activeObst->vel) * ivmax); + const float vpen = velWeight * (len_v2v2(vcand, activeObst->dvel) * ivmax); + const float vcpen = curVelWeight * (len_v2v2(vcand, activeObst->vel) * ivmax); const float spen = sideWeight * side; const float tpen = toiWeight * (1.0f/(0.1f+tmin/maxToi)); const float penalty = vpen + vcpen + spen + tpen; - if (penalty < minPenalty) - { + if (penalty < minPenalty) { minPenalty = penalty; - vcpy(res, vcand); + copy_v2_v2(res, vcand); } } } @@ -786,7 +742,7 @@ void KX_ObstacleSimulationTOI_cells::sampleRVO(KX_Obstacle* activeObst, KX_NavMe const float maxDeltaAngle) { vset(activeObst->nvel, 0.f, 0.f); - float vmax = vlen(activeObst->dvel); + float vmax = len_v2(activeObst->dvel); float* spos = new float[2*m_maxSamples]; int nspos = 0; @@ -795,7 +751,7 @@ void KX_ObstacleSimulationTOI_cells::sampleRVO(KX_Obstacle* activeObst, KX_NavMe { const float cvx = activeObst->dvel[0]*m_bias; const float cvy = activeObst->dvel[1]*m_bias; - float vmax = vlen(activeObst->dvel); + float vmax = len_v2(activeObst->dvel); const float vrange = vmax*(1-m_bias); const float cs = 1.0f / (float)m_sampleRadius*vrange; @@ -837,22 +793,27 @@ void KX_ObstacleSimulationTOI_cells::sampleRVO(KX_Obstacle* activeObst, KX_NavMe { for (int x = 0; x < rad; ++x) { - const float vx = res[0] + x*cs - half; - const float vy = res[1] + y*cs - half; - if (vx*vx+vy*vy > sqr(vmax+cs/2)) continue; - spos[nspos*2+0] = vx; - spos[nspos*2+1] = vy; + const float v_xy[2] = { + res[0] + x * cs - half, + res[1] + y * cs - half}; + + if (len_squared_v2(v_xy) > sqr(vmax + cs / 2)) + continue; + + copy_v2_v2(&spos[nspos * 2 + 0], v_xy); nspos++; } } - processSamples(activeObst, activeNavMeshObj, m_obstacles, m_levelHeight, vmax, spos, cs/2, - nspos, res, m_maxToi, m_velWeight, m_curVelWeight, m_collisionWeight, m_toiWeight); + processSamples(activeObst, activeNavMeshObj, m_obstacles, m_levelHeight, vmax, spos, cs/2, + nspos, res, m_maxToi, m_velWeight, m_curVelWeight, m_collisionWeight, m_toiWeight); cs *= 0.5f; } - vcpy(activeObst->nvel, res); + copy_v2_v2(activeObst->nvel, res); } + + delete [] spos; } KX_ObstacleSimulationTOI_cells::KX_ObstacleSimulationTOI_cells(MT_Scalar levelHeight, bool enableVisualization) diff --git a/source/gameengine/Ketsji/KX_PolyProxy.h b/source/gameengine/Ketsji/KX_PolyProxy.h index f02aa90998e..837e7f8354c 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.h +++ b/source/gameengine/Ketsji/KX_PolyProxy.h @@ -29,8 +29,8 @@ * \ingroup ketsji */ -#ifndef __KX_POLYROXY -#define __KX_POLYPROXY +#ifndef __KX_POLYPROXY_H__ +#define __KX_POLYPROXY_H__ #ifdef WITH_PYTHON @@ -82,4 +82,4 @@ public: #endif /* WITH_PYTHON */ -#endif /* __KX_POLYPROXY */ +#endif /* __KX_POLYPROXY_H__ */ diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 58996f7b86f..d8b4bf9e8bd 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -233,9 +233,8 @@ static char gPyExpandPath_doc[] = path - the string path to convert.\n\n\ Use / as directory separator in path\n\ You can use '//' at the start of the string to define a relative path;\n\ -Blender replaces that string by the directory of the startup .blend or runtime\n\ -file to make a full path name (doesn't change during the game, even if you load\n\ -other .blend).\n\ +Blender replaces that string by the directory of the current .blend or runtime\n\ +file to make a full path name.\n\ The function also converts the directory separator to the local file system format."; static PyObject *gPyExpandPath(PyObject *, PyObject *args) @@ -1372,6 +1371,29 @@ static PyObject *gPyGetMipmapping(PyObject *) return PyLong_FromLong(gp_Rasterizer->GetMipmapping()); } +static PyObject *gPySetVsync(PyObject *, PyObject *args) +{ + int interval; + + if (!PyArg_ParseTuple(args, "i:setVsync", &interval)) + return NULL; + + if (interval < VSYNC_OFF || interval > VSYNC_ADAPTIVE) { + PyErr_SetString(PyExc_ValueError, "Rasterizer.setVsync(value): value must be VSYNC_OFF, VSYNC_ON, or VSYNC_ADAPTIVE"); + return NULL; + } + + if (interval == VSYNC_ADAPTIVE) + interval = -1; + gp_Canvas->SetSwapInterval(interval); + Py_RETURN_NONE; +} + +static PyObject *gPyGetVsync(PyObject *) +{ + return PyLong_FromLong(gp_Canvas->GetSwapInterval()); +} + static struct PyMethodDef rasterizer_methods[] = { {"getWindowWidth",(PyCFunction) gPyGetWindowWidth, METH_VARARGS, "getWindowWidth doc"}, @@ -1417,6 +1439,8 @@ static struct PyMethodDef rasterizer_methods[] = { {"getFullScreen", (PyCFunction) gPyGetFullScreen, METH_NOARGS, ""}, {"setMipmapping", (PyCFunction) gPySetMipmapping, METH_VARARGS, ""}, {"getMipmapping", (PyCFunction) gPyGetMipmapping, METH_NOARGS, ""}, + {"setVsync", (PyCFunction) gPySetVsync, METH_VARARGS, ""}, + {"getVsync", (PyCFunction) gPyGetVsync, METH_NOARGS, ""}, { NULL, (PyCFunction) NULL, 0, NULL } }; @@ -2122,6 +2146,7 @@ void setupGamePython(KX_KetsjiEngine* ketsjiengine, KX_Scene *startscene, Main * "'render':__import__('Rasterizer'), " "'events':__import__('GameKeys'), " "'constraints':__import__('PhysicsConstraints'), " + "'physics':__import__('PhysicsConstraints')," "'types':__import__('GameTypes'), " "'texture':__import__('VideoTexture')});" /* so we can do 'import bge.foo as bar' */ @@ -2130,6 +2155,7 @@ void setupGamePython(KX_KetsjiEngine* ketsjiengine, KX_Scene *startscene, Main * "'bge.render':bge.render, " "'bge.events':bge.events, " "'bge.constraints':bge.constraints, " + "'bge.physics':bge.physics," "'bge.types':bge.types, " "'bge.texture':bge.texture})" ); @@ -2187,6 +2213,11 @@ PyObject *initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas) KX_MACRO_addTypesToDict(d, RAS_MIPMAP_NEAREST, RAS_IRasterizer::RAS_MIPMAP_NEAREST); KX_MACRO_addTypesToDict(d, RAS_MIPMAP_LINEAR, RAS_IRasterizer::RAS_MIPMAP_LINEAR); + /* for get/setVsync */ + KX_MACRO_addTypesToDict(d, VSYNC_OFF, VSYNC_OFF); + KX_MACRO_addTypesToDict(d, VSYNC_ON, VSYNC_ON); + KX_MACRO_addTypesToDict(d, VSYNC_ADAPTIVE, VSYNC_ADAPTIVE); + // XXXX Add constants here // Check for errors diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 0604157a420..1a8fda0749a 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -1146,7 +1146,7 @@ void CcdPhysicsController::ApplyTorque(float torqueX,float torqueY,float torque { //workaround for incompatibility between 'DYNAMIC' game object, and angular factor //a DYNAMIC object has some inconsistency: it has no angular effect due to collisions, but still has torque - const btVector3& angFac = body->getAngularFactor(); + const btVector3 angFac = body->getAngularFactor(); btVector3 tmpFac(1,1,1); body->setAngularFactor(tmpFac); body->applyTorque(torque); @@ -1590,17 +1590,7 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, /* Can happen with ngons */ if (!tot_bt_verts) { - m_shapeType = PHY_SHAPE_NONE; - m_meshObject = NULL; - m_vertexArray.clear(); - m_polygonIndexArray.clear(); - m_triFaceArray.clear(); - m_triFaceUVcoArray.clear(); - if (free_dm) { - dm->release(dm); - dm = NULL; - } - return false; + goto cleanup_empty_mesh; } m_vertexArray.resize(tot_bt_verts*3); @@ -1679,17 +1669,7 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, /* Can happen with ngons */ if (!tot_bt_verts) { - m_shapeType = PHY_SHAPE_NONE; - m_meshObject = NULL; - m_vertexArray.clear(); - m_polygonIndexArray.clear(); - m_triFaceArray.clear(); - m_triFaceUVcoArray.clear(); - if (free_dm) { - dm->release(dm); - dm = NULL; - } - return false; + goto cleanup_empty_mesh; } m_vertexArray.resize(tot_bt_verts*3); @@ -1834,6 +1814,19 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, m_meshShapeMap.insert(std::pair<RAS_MeshObject*,CcdShapeConstructionInfo*>(meshobj,this)); } return true; + + +cleanup_empty_mesh: + m_shapeType = PHY_SHAPE_NONE; + m_meshObject = NULL; + m_vertexArray.clear(); + m_polygonIndexArray.clear(); + m_triFaceArray.clear(); + m_triFaceUVcoArray.clear(); + if (free_dm) { + dm->release(dm); + } + return false; } #include <cstdio> diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp index bfe29a48c69..e85b57f1769 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp @@ -352,7 +352,7 @@ void RAS_2DFilterManager::UpdateOffsetMatrix(RAS_ICanvas* canvas) } } -void RAS_2DFilterManager::UpdateCanvasTextureCoord(unsigned int * viewport) +void RAS_2DFilterManager::UpdateCanvasTextureCoord(const int viewport[4]) { /* * This function update canvascoord[]. @@ -360,12 +360,10 @@ void RAS_2DFilterManager::UpdateCanvasTextureCoord(unsigned int * viewport) * That way we can access the texcoord relative to the canvas: * (0.0,0.0) bottom left, (1.0,1.0) top right, (0.5,0.5) center */ - canvascoord[0] = (GLfloat) viewport[0] / viewport[2]; - canvascoord[0] *= -1; + canvascoord[0] = (GLfloat) viewport[0] / -viewport[2]; canvascoord[1] = (GLfloat) (texturewidth - viewport[0]) / viewport[2]; - canvascoord[2] = (GLfloat) viewport[1] / viewport[3]; - canvascoord[2] *= -1; + canvascoord[2] = (GLfloat) viewport[1] / -viewport[3]; canvascoord[3] = (GLfloat)(textureheight - viewport[1]) / viewport[3]; } @@ -396,14 +394,14 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas) if (num_filters <= 0) return; - const GLint *viewport = canvas->GetViewPort(); + const int *viewport = canvas->GetViewPort(); RAS_Rect rect = canvas->GetWindowArea(); int rect_width = rect.GetWidth()+1, rect_height = rect.GetHeight()+1; if (texturewidth != rect_width || textureheight != rect_height) { UpdateOffsetMatrix(canvas); - UpdateCanvasTextureCoord((unsigned int*)viewport); + UpdateCanvasTextureCoord(viewport); need_tex_update = true; } @@ -432,7 +430,10 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas) // We do this to make side-by-side stereo rendering work correctly with 2D filters. It would probably be nicer to just set the viewport, // but it can be easier for writing shaders to have the coordinates for the whole screen instead of just part of the screen. RAS_Rect scissor_rect = canvas->GetDisplayArea(); - glScissor(scissor_rect.GetLeft()+viewport[0], scissor_rect.GetBottom()+viewport[1], scissor_rect.GetWidth()+1, scissor_rect.GetHeight()+1); + glScissor(scissor_rect.GetLeft() + viewport[0], + scissor_rect.GetBottom() + viewport[1], + scissor_rect.GetWidth() + 1, + scissor_rect.GetHeight() + 1); glDisable(GL_DEPTH_TEST); // in case the previous material was wire diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.h b/source/gameengine/Rasterizer/RAS_2DFilterManager.h index ba74018d36b..a637baa3d09 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.h +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.h @@ -53,7 +53,7 @@ private: void FreeTextures(); void UpdateOffsetMatrix(RAS_ICanvas* canvas); - void UpdateCanvasTextureCoord(unsigned int * viewport); + void UpdateCanvasTextureCoord(const int viewport[4]); float canvascoord[4]; float textureoffsets[18]; diff --git a/source/gameengine/Rasterizer/RAS_ICanvas.h b/source/gameengine/Rasterizer/RAS_ICanvas.h index 1b1e43a5257..9e8a6e8ccf6 100644 --- a/source/gameengine/Rasterizer/RAS_ICanvas.h +++ b/source/gameengine/Rasterizer/RAS_ICanvas.h @@ -105,6 +105,17 @@ public: void SwapBuffers( )=0; + + virtual + void + SetSwapInterval( + int interval + )=0; + + virtual + int + GetSwapInterval( + )=0; virtual void diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp index 900d6f387ff..77bd540a039 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp @@ -40,6 +40,7 @@ extern "C"{ } RAS_StorageIM::RAS_StorageIM(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib, int *attrib_layer) : + m_drawingmode(RAS_IRasterizer::KX_TEXTURED), m_texco_num(texco_num), m_attrib_num(attrib_num), m_texco(texco), diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp index 72af3852cf6..006c07b0491 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp @@ -30,6 +30,7 @@ #include "GL/glew.h" RAS_StorageVA::RAS_StorageVA(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib, int *attrib_layer) : + m_drawingmode(RAS_IRasterizer::KX_TEXTURED), m_texco_num(texco_num), m_attrib_num(attrib_num), m_last_texco_num(0), diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp index c7779c209ba..06f85b143d2 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp @@ -182,6 +182,7 @@ void VBO::Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num, } RAS_StorageVBO::RAS_StorageVBO(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib, int *attrib_layer): + m_drawingmode(RAS_IRasterizer::KX_TEXTURED), m_texco_num(texco_num), m_attrib_num(attrib_num), m_texco(texco), diff --git a/source/gameengine/SceneGraph/SG_Tree.cpp b/source/gameengine/SceneGraph/SG_Tree.cpp index 99f68ef625a..bef246533a6 100644 --- a/source/gameengine/SceneGraph/SG_Tree.cpp +++ b/source/gameengine/SceneGraph/SG_Tree.cpp @@ -37,13 +37,19 @@ #include "SG_Tree.h" #include "SG_Node.h" -SG_Tree::SG_Tree() +SG_Tree::SG_Tree() : + m_left(NULL), + m_right(NULL), + m_parent(NULL), + m_radius(0.0), + m_client_object(NULL) { } SG_Tree::SG_Tree(SG_Tree* left, SG_Tree* right) : m_left(left), m_right(right), + m_parent(NULL), m_client_object(NULL) { if (m_left) @@ -63,6 +69,7 @@ SG_Tree::SG_Tree(SG_Tree* left, SG_Tree* right) : SG_Tree::SG_Tree(SG_Node* client) : m_left(NULL), m_right(NULL), + m_parent(NULL), m_client_object(client) { m_bbox = SG_BBox(client->BBox(), client->GetWorldTransform()); diff --git a/source/gameengine/VideoTexture/BlendType.h b/source/gameengine/VideoTexture/BlendType.h index 28eebe07789..561c6e8768f 100644 --- a/source/gameengine/VideoTexture/BlendType.h +++ b/source/gameengine/VideoTexture/BlendType.h @@ -38,7 +38,7 @@ template <class PyObj> class BlendType { public: /// constructor - BlendType (const char * name) : m_name(name) {} + BlendType (const char * name) : m_name(name), m_objType(NULL) {} /// check blender type and return pointer to contained object or NULL (if type is not valid) PyObj *checkType(PyObject *obj) diff --git a/source/gameengine/VideoTexture/Exception.cpp b/source/gameengine/VideoTexture/Exception.cpp index 0f571550205..804834af4cd 100644 --- a/source/gameengine/VideoTexture/Exception.cpp +++ b/source/gameengine/VideoTexture/Exception.cpp @@ -111,6 +111,8 @@ Exception::Exception (ExceptionID & expID, RESULT rslt, const char *fil, int lin // set file and line if (fil[0] != '\0' || lin > 0) setFileLine (fil, lin); + else + m_line = -1; } diff --git a/source/gameengine/VideoTexture/FilterSource.h b/source/gameengine/VideoTexture/FilterSource.h index 0289c88f056..bc80b2b36cc 100644 --- a/source/gameengine/VideoTexture/FilterSource.h +++ b/source/gameengine/VideoTexture/FilterSource.h @@ -164,7 +164,7 @@ class FilterYV12 : public FilterBase { public: /// constructor - FilterYV12 (void) {} + FilterYV12 (void): m_buffV(NULL), m_buffU(NULL), m_pitchUV(0) {} /// destructor virtual ~FilterYV12 (void) {} diff --git a/source/gameengine/VideoTexture/ImageMix.h b/source/gameengine/VideoTexture/ImageMix.h index e55b95834fa..161a8b375ea 100644 --- a/source/gameengine/VideoTexture/ImageMix.h +++ b/source/gameengine/VideoTexture/ImageMix.h @@ -43,7 +43,7 @@ class ImageSourceMix : public ImageSource { public: /// constructor - ImageSourceMix (const char *id) : ImageSource(id), m_weight(0x100) {} + ImageSourceMix (const char *id) : ImageSource(id), m_offset(0), m_weight(0x100) {} /// destructor virtual ~ImageSourceMix (void) {} diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index f184ab9bd1d..d83cd2dc6fd 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -70,7 +70,9 @@ ImageRender::ImageRender (KX_Scene *scene, KX_Camera * camera) : m_owncamera(false), m_observer(NULL), m_mirror(NULL), - m_clip(100.f) + m_clip(100.f), + m_mirrorHalfWidth(0.f), + m_mirrorHalfHeight(0.f) { // initialize background color setBackground(0, 0, 255, 255); |